// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Authorization.Policy { public class PolicyEvaluator : IPolicyEvaluator { private readonly IAuthorizationService _authorization; /// /// Constructor /// /// The authorization service. public PolicyEvaluator(IAuthorizationService authorization) { _authorization = authorization; } /// /// Does authentication for and sets the resulting /// to . If no schemes are set, this is a no-op. /// /// The . /// The . /// unless all schemes specified by failed to authenticate. public virtual async Task AuthenticateAsync(AuthorizationPolicy policy, HttpContext context) { if (policy.AuthenticationSchemes != null && policy.AuthenticationSchemes.Count > 0) { ClaimsPrincipal newPrincipal = null; foreach (var scheme in policy.AuthenticationSchemes) { var result = await context.AuthenticateAsync(scheme); if (result != null && result.Succeeded) { newPrincipal = SecurityHelper.MergeUserPrincipal(newPrincipal, result.Principal); } } if (newPrincipal != null) { context.User = newPrincipal; return AuthenticateResult.Success(new AuthenticationTicket(newPrincipal, string.Join(";", policy.AuthenticationSchemes))); } else { context.User = new ClaimsPrincipal(new ClaimsIdentity()); return AuthenticateResult.NoResult(); } } return (context.User?.Identity?.IsAuthenticated ?? false) ? AuthenticateResult.Success(new AuthenticationTicket(context.User, "context.User")) : AuthenticateResult.NoResult(); } /// /// Attempts authorization for a policy using . /// /// The . /// The result of a call to . /// The . /// Returns if authorization succeeds. /// Otherwise returns if , otherwise /// returns public virtual async Task AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context) { if (policy == null) { throw new ArgumentNullException(nameof(policy)); } var result = await _authorization.AuthorizeAsync(context.User, context, policy); if (result.Succeeded) { return PolicyAuthorizationResult.Success(); } // If authentication was successful, return forbidden, otherwise challenge return (authenticationResult.Succeeded) ? PolicyAuthorizationResult.Forbid() : PolicyAuthorizationResult.Challenge(); } } }