Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Filter should call through to AuthorizationService #4385

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public AuthorizeFilter(AuthorizationPolicy policy)
public AuthorizationPolicy Policy { get; }

/// <inheritdoc />
public virtual async Task OnAuthorizationAsync(Filters.AuthorizationFilterContext context)
public virtual async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (context == null)
{
Expand Down Expand Up @@ -76,9 +76,7 @@ public virtual async Task OnAuthorizationAsync(Filters.AuthorizationFilterContex
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();

// Note: Default Anonymous User is new ClaimsPrincipal(new ClaimsIdentity())
if (httpContext.User == null ||
!httpContext.User.Identities.Any(i => i.IsAuthenticated) ||
!await authService.AuthorizeAsync(httpContext.User, context, Policy))
if (!await authService.AuthorizeAsync(httpContext.User, context, Policy))
{
context.Result = new ChallengeResult(Policy.AuthenticationSchemes.ToArray());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related to this PR, but I'm still not very comfortable with such code. It's a decision that should be made at the authorization service level, not in the authentication middleware 👎

@HaoK curious: do you remember the outcome of the alternate design I had suggested for IAuthorizationService? https://github.com/PinpointTownes/Security/commit/7ac1a2515015a98dc6f4919f28baa9db33beb50a#commitcomment-11507157

Returning an AuthorizationResult class/struct/enum instead of a binary bool would allow much more flexibility IMHO, and would allow replacing the current crazy design, that consists in guessing whether an AuthenticationTicket can be resolved by the authentication middleware to determine if a 401 or a 403 response should be returned 😄

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ public void InvalidUser()
Assert.True(authorizationContext.HttpContext.User.Identities.Any(i => i.IsAuthenticated));
}

[Fact]
public async Task AuthorizeFilterCanAuthorizeNonAuthenticatedUser()
{
// Arrange
var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(_ => true).Build());
var authorizationContext = GetAuthorizationContext(services => services.AddAuthorization(), anonymous: true);
authorizationContext.HttpContext.User = new ClaimsPrincipal();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a variation for null user?


// Act
await authorizeFilter.OnAuthorizationAsync(authorizationContext);

// Assert
Assert.Null(authorizationContext.Result);
}

[Fact]
public async Task Invoke_ValidClaimShouldNotFail()
{
Expand Down