/// <inheritdoc />
        public async Task OnAuthorizationAsync([NotNull] Filters.AuthorizationContext context)
        {
            // If this filter is not closest to the action, it is not applicable.
            if (!IsClosestToAction(context.Filters))
            {
                return;
            }

            var httpContext = context.HttpContext;
            var request     = httpContext.Request;

            if (request.Headers.ContainsKey(CorsConstants.Origin))
            {
                var policy = await _corsPolicyProvider.GetPolicyAsync(httpContext, 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.Ordinal) &&
                    !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 HttpStatusCodeResult(StatusCodes.Status200OK);
                }

                // Continue with other filters and action.
            }
        }
Exemple #2
0
        /// <inheritdoc />
        public virtual async Task OnAuthorizationAsync(Filters.AuthorizationContext 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());
            }
        }