/// <inheritdoc /> public async Task OnAuthorizationAsync(Filters.AuthorizationFilterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // If this filter is not closest to the action, it is not applicable. if (!context.IsEffectivePolicy <ICorsAuthorizationFilter>(this)) { _logger.NotMostEffectiveFilter(typeof(ICorsAuthorizationFilter)); return; } var httpContext = context.HttpContext; var request = httpContext.Request; if (request.Headers.ContainsKey(CorsConstants.Origin)) { var policy = await _corsPolicyProvider.GetPolicyAsync(httpContext, PolicyName); if (policy == null) { throw new InvalidOperationException( Resources.FormatCorsAuthorizationFilter_MissingCorsPolicy(PolicyName)); } var result = _corsService.EvaluatePolicy(context.HttpContext, policy); _corsService.ApplyResult(result, context.HttpContext.Response); var accessControlRequestMethod = httpContext.Request.Headers[CorsConstants.AccessControlRequestMethod]; if (string.Equals( request.Method, CorsConstants.PreflightHttpMethod, StringComparison.OrdinalIgnoreCase) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { // If this was a preflight, there is no need to run anything else. // Also the response is always 200 so that anyone after mvc can handle the pre flight request. context.Result = new StatusCodeResult(StatusCodes.Status200OK); } // Continue with other filters and action. } }
/// <inheritdoc /> public virtual async Task OnAuthorizationAsync(Filters.AuthorizationFilterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // Build a ClaimsPrincipal with the Policy's required authentication types if (Policy.AuthenticationSchemes != null && Policy.AuthenticationSchemes.Any()) { ClaimsPrincipal newPrincipal = null; foreach (var scheme in Policy.AuthenticationSchemes) { var result = await context.HttpContext.Authentication.AuthenticateAsync(scheme); if (result != null) { newPrincipal = SecurityHelper.MergeUserPrincipal(newPrincipal, result); } } // If all schemes failed authentication, provide a default identity anyways if (newPrincipal == null) { newPrincipal = new ClaimsPrincipal(new ClaimsIdentity()); } context.HttpContext.User = newPrincipal; } // Allow Anonymous skips all authorization if (context.Filters.Any(item => item is IAllowAnonymousFilter)) { return; } var httpContext = context.HttpContext; 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)) { context.Result = new ChallengeResult(Policy.AuthenticationSchemes.ToArray()); } }
private AuthorizationFilterContext GetAuthorizationContext( bool anonymous = false, Action <IServiceCollection> registerServices = null) { var basicPrincipal = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanViewPage"), new Claim(ClaimTypes.Role, "Administrator"), new Claim(ClaimTypes.Role, "User"), new Claim(ClaimTypes.NameIdentifier, "John") }, "Basic")); var validUser = basicPrincipal; var bearerIdentity = new ClaimsIdentity( new Claim[] { new Claim("Permission", "CupBearer"), new Claim(ClaimTypes.Role, "Token"), new Claim(ClaimTypes.NameIdentifier, "John Bear") }, "Bearer"); var bearerPrincipal = new ClaimsPrincipal(bearerIdentity); validUser.AddIdentity(bearerIdentity); // ServiceProvider var serviceCollection = new ServiceCollection(); var auth = new Mock <IAuthenticationService>(); serviceCollection.AddOptions(); serviceCollection.AddLogging(); serviceCollection.AddSingleton(auth.Object); serviceCollection.AddAuthorization(); serviceCollection.AddAuthorizationPolicyEvaluator(); if (registerServices != null) { registerServices(serviceCollection); } var serviceProvider = serviceCollection.BuildServiceProvider(); // HttpContext var httpContext = new Mock <HttpContext>(); auth.Setup(c => c.AuthenticateAsync(httpContext.Object, "Bearer")).ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(bearerPrincipal, "Bearer"))); auth.Setup(c => c.AuthenticateAsync(httpContext.Object, "Basic")).ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(basicPrincipal, "Basic"))); auth.Setup(c => c.AuthenticateAsync(httpContext.Object, "Fails")).ReturnsAsync(AuthenticateResult.Fail("Fails")); httpContext.SetupProperty(c => c.User); if (!anonymous) { httpContext.Object.User = validUser; } httpContext.SetupGet(c => c.RequestServices).Returns(serviceProvider); // AuthorizationFilterContext var actionContext = new ActionContext( httpContext: httpContext.Object, routeData: new RouteData(), actionDescriptor: new ActionDescriptor()); var authorizationContext = new Filters.AuthorizationFilterContext( actionContext, Enumerable.Empty <IFilterMetadata>().ToList() ); return(authorizationContext); }