This repository has been archived by the owner on Dec 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 600
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Challenge/Forbid behavior to policy evaluator
- Loading branch information
Showing
10 changed files
with
280 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 0 additions & 101 deletions
101
src/Microsoft.AspNetCore.Authorization.Policy/AuthorizationPolicyEvaluator.cs
This file was deleted.
Oops, something went wrong.
18 changes: 0 additions & 18 deletions
18
src/Microsoft.AspNetCore.Authorization.Policy/IAuthorizationPolicyEvaluator.cs
This file was deleted.
Oops, something went wrong.
35 changes: 35 additions & 0 deletions
35
src/Microsoft.AspNetCore.Authorization.Policy/IPolicyEvaluator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// 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.Security.Claims; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace Microsoft.AspNetCore.Authorization.Policy | ||
{ | ||
/// <summary> | ||
/// Base class for authorization handlers that need to be called for a specific requirement type. | ||
/// </summary> | ||
public interface IPolicyEvaluator | ||
{ | ||
/// <summary> | ||
/// Does authentication for <see cref="AuthorizationPolicy.AuthenticationSchemes"/> and sets the resulting | ||
/// <see cref="ClaimsPrincipal"/> to <see cref="HttpContext.User"/>. If no schemes are set, this is a no-op. | ||
/// </summary> | ||
/// <param name="policy">The <see cref="AuthorizationPolicy"/>.</param> | ||
/// <param name="context">The <see cref="HttpContext"/>.</param> | ||
/// <returns><see cref="PolicyAuthenticationResult.Success"/> unless all schemes specified by <see cref="AuthorizationPolicy.AuthenticationSchemes"/> failed to authenticate. </returns> | ||
Task<PolicyAuthenticationResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context); | ||
|
||
/// <summary> | ||
/// Attempts authorization for a policy using <see cref="IAuthorizationService"/>. | ||
/// </summary> | ||
/// <param name="policy">The <see cref="AuthorizationPolicy"/>.</param> | ||
/// <param name="authenticationResult">The result of a call to <see cref="AuthenticateAsync(AuthorizationPolicy, HttpContext)"/>.</param> | ||
/// <param name="context">The <see cref="HttpContext"/>.</param> | ||
/// <returns>Returns <see cref="PolicyAuthorizationResult.Success"/> if authorization succeeds. | ||
/// Otherwise returns <see cref="PolicyAuthorizationResult.Forbid"/> if <see cref="PolicyAuthenticationResult.Succeeded"/>, otherwise | ||
/// returns <see cref="PolicyAuthorizationResult.Challenge"/></returns> | ||
Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy, PolicyAuthenticationResult authenticationResult, HttpContext context); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/Microsoft.AspNetCore.Authorization.Policy/PolicyAuthenticationResult.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// 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.Security.Claims; | ||
|
||
namespace Microsoft.AspNetCore.Authorization.Policy | ||
{ | ||
public class PolicyAuthenticationResult | ||
{ | ||
private PolicyAuthenticationResult() { } | ||
|
||
/// <summary> | ||
/// Authentication from at least one scheme was successful. | ||
/// </summary> | ||
public bool Succeeded { get; private set; } | ||
|
||
public static PolicyAuthenticationResult Success() | ||
=> new PolicyAuthenticationResult { Succeeded = true }; | ||
|
||
public static PolicyAuthenticationResult Failed() | ||
=> new PolicyAuthenticationResult(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
src/Microsoft.AspNetCore.Authorization.Policy/PolicyEvaluator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// 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; | ||
|
||
/// <summary> | ||
/// Constructor | ||
/// </summary> | ||
/// <param name="authorization">The authorization service.</param> | ||
public PolicyEvaluator(IAuthorizationService authorization) | ||
{ | ||
_authorization = authorization; | ||
} | ||
|
||
/// <summary> | ||
/// Does authentication for <see cref="AuthorizationPolicy.AuthenticationSchemes"/> and sets the resulting | ||
/// <see cref="ClaimsPrincipal"/> to <see cref="HttpContext.User"/>. If no schemes are set, this is a no-op. | ||
/// </summary> | ||
/// <param name="policy">The <see cref="AuthorizationPolicy"/>.</param> | ||
/// <param name="context">The <see cref="HttpContext"/>.</param> | ||
/// <returns><see cref="PolicyAuthenticationResult.Success"/> unless all schemes specified by <see cref="AuthorizationPolicy.AuthenticationSchemes"/> failed to authenticate. </returns> | ||
public virtual async Task<PolicyAuthenticationResult> 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 PolicyAuthenticationResult.Success(); | ||
} | ||
else | ||
{ | ||
context.User = new ClaimsPrincipal(new ClaimsIdentity()); | ||
return PolicyAuthenticationResult.Failed(); | ||
} | ||
} | ||
return PolicyAuthenticationResult.Success(); | ||
} | ||
|
||
/// <summary> | ||
/// Attempts authorization for a policy using <see cref="IAuthorizationService"/>. | ||
/// </summary> | ||
/// <param name="policy">The <see cref="AuthorizationPolicy"/>.</param> | ||
/// <param name="authenticationResult">The result of a call to <see cref="AuthenticateAsync(AuthorizationPolicy, HttpContext)"/>.</param> | ||
/// <param name="context">The <see cref="HttpContext"/>.</param> | ||
/// <returns>Returns <see cref="PolicyAuthorizationResult.Success"/> if authorization succeeds. | ||
/// Otherwise returns <see cref="PolicyAuthorizationResult.Forbid"/> if <see cref="PolicyAuthenticationResult.Succeeded"/>, otherwise | ||
/// returns <see cref="PolicyAuthorizationResult.Challenge"/></returns> | ||
public virtual async Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy, PolicyAuthenticationResult authenticationResult, HttpContext context) | ||
{ | ||
if (policy == null) | ||
{ | ||
throw new ArgumentNullException(nameof(policy)); | ||
} | ||
|
||
var authResult = await _authorization.AuthorizeAsync(context.User, context, policy); | ||
if (authResult.Succeeded) | ||
{ | ||
return PolicyAuthorizationResult.Success(); | ||
} | ||
|
||
// If authentication was successful, return forbidden, otherwise challenge | ||
return (authenticationResult.Succeeded) | ||
? PolicyAuthorizationResult.Forbid() | ||
: PolicyAuthorizationResult.Challenge(); | ||
} | ||
} | ||
} |
Oops, something went wrong.