public async Task InvokeAsync(IDirectiveContext context) { AuthorizeDirective directive = context.Directive .ToObject <AuthorizeDirective>(); if (directive.Apply == ApplyPolicy.AfterResolver) { await _next(context).ConfigureAwait(false); AuthState state = await CheckPermissionsAsync( context, directive) .ConfigureAwait(false); if (state != AuthState.Allowed && !IsErrorResult(context)) { SetError(context, directive, state); } } else { AuthState state = await CheckPermissionsAsync( context, directive) .ConfigureAwait(false); if (state == AuthState.Allowed) { await _next(context).ConfigureAwait(false); } else { SetError(context, directive, state); } } }
private static async Task <AuthState> AuthorizeWithPolicyAsync( IDirectiveContext context, AuthorizeDirective directive, ClaimsPrincipal principal) { IServiceProvider services = context.Service <IServiceProvider>(); IAuthorizationService?authorizeService = services.GetService <IAuthorizationService>(); IAuthorizationPolicyProvider?policyProvider = services.GetService <IAuthorizationPolicyProvider>(); if (authorizeService == null || policyProvider == null) { // authorization service is not configured so the user is // authorized with the previous checks. return(string.IsNullOrWhiteSpace(directive.Policy) ? AuthState.Allowed : AuthState.NotAllowed); } AuthorizationPolicy?policy = null; if ((directive.Roles is null || directive.Roles.Count == 0) && string.IsNullOrWhiteSpace(directive.Policy)) { policy = await policyProvider.GetDefaultPolicyAsync() .ConfigureAwait(false); if (policy == null) { return(AuthState.NoDefaultPolicy); } }
private static async Task <AuthState> CheckPermissionsAsync( IDirectiveContext context, AuthorizeDirective directive) { if (!TryGetAuthenticatedPrincipal(context, out ClaimsPrincipal? principal)) { return(AuthState.NotAuthenticated); } if (IsInAnyRole(principal !, directive.Roles)) { if (NeedsPolicyValidation(directive)) { return(await AuthorizeWithPolicyAsync( context, directive, principal !) .ConfigureAwait(false)); } else { return(AuthState.Allowed); } } return(AuthState.NotAllowed); }
public void CreateInstance_Policy_PolicyIsSet() { // arrange // act var authorizeDirective = new AuthorizeDirective("abc"); // assert Assert.Equal("abc", authorizeDirective.Policy); Assert.Null(authorizeDirective.Roles); }
public void CreateInstance_PolicyRoles_PolicyIsSetRolesIsNull() { // arrange // act var authorizeDirective = new AuthorizeDirective( "abc", Array.Empty <string>()); // assert Assert.Equal("abc", authorizeDirective.Policy); Assert.Empty(authorizeDirective.Roles); }
public void CreateInstance_Roles_RolesHasItems() { // arrange // act var authorizeDirective = new AuthorizeDirective( new[] { "a", "b" }); // assert Assert.Null(authorizeDirective.Policy); Assert.Collection(authorizeDirective.Roles, t => Assert.Equal("a", t), t => Assert.Equal("b", t)); }
private void SetError( IDirectiveContext context, AuthorizeDirective directive, AuthState state) { switch (state) { case AuthState.NoDefaultPolicy: context.Result = context.Result = ErrorBuilder.New() .SetMessage(AuthResources.AuthorizeMiddleware_NoDefaultPolicy) .SetCode(ErrorCodes.Authentication.NoDefaultPolicy) .SetPath(context.Path) .AddLocation(context.Selection.SyntaxNode) .Build(); break; case AuthState.PolicyNotFound: context.Result = ErrorBuilder.New() .SetMessage(string.Format( CultureInfo.InvariantCulture, AuthResources.AuthorizeMiddleware_PolicyNotFound, directive.Policy)) .SetCode(ErrorCodes.Authentication.PolicyNotFound) .SetPath(context.Path) .AddLocation(context.Selection.SyntaxNode) .Build(); break; default: context.Result = ErrorBuilder.New() .SetMessage(AuthResources.AuthorizeMiddleware_NotAuthorized) .SetCode(state == AuthState.NotAllowed ? ErrorCodes.Authentication.NotAuthorized : ErrorCodes.Authentication.NotAuthenticated) .SetPath(context.Path) .AddLocation(context.Selection.SyntaxNode) .Build(); break; } }
private static bool NeedsPolicyValidation(AuthorizeDirective directive) { return(directive.Roles == null || directive.Roles.Count == 0 || !string.IsNullOrEmpty(directive.Policy)); }