public void OnAuthorization(AuthorizationFilterContext context) { IServiceProvider services = context.HttpContext.RequestServices; object authorization = services.GetRequiredService(serviceType); IAuthorizationResultAccessor accessor = services.GetRequiredService <IAuthorizationResultAccessor>(); PolicyResult policyResult = (PolicyResult)tryAuthorizeMethod.Invoke(authorization, new object[] { policyExpression }); SortedSet <string> succeeded = new SortedSet <string>(); SortedSet <string> failed = new SortedSet <string>(); SortedSet <string> notHandled = new SortedSet <string>(); switch (policyResult) { case PolicyResult.Success: succeeded.Add(policyExpression); break; case PolicyResult.Failed: failed.Add(policyExpression); break; case PolicyResult.NotHandled: default: notHandled.Add(policyExpression); break; } PolicyOnlyExpression exp = new PolicyOnlyExpression(policyExpression, policyResult); PolicyExpressionRoot root = new PolicyExpressionRoot(exp); AuthorizationResult result = new AuthorizationResult(root); if (accessor.Result == null) { accessor.Result = result; } else { result.CombineAsAnd(accessor.Result); accessor.Result = result; } bool overall = false; switch (result.Result) { case PolicyResult.Success: overall = true; break; case PolicyResult.Failed: break; case PolicyResult.NotHandled: default: if (!failedIfNotHandled) { overall = true; } break; } if (overall) { return; } switch (failedAction) { case AuthorizationFailedAction.KeepUnauthorized: return; case AuthorizationFailedAction.Return401: context.Result = new HttpUnauthorizedResult(); return; case AuthorizationFailedAction.CustomHandler: break; } // custom handler IAuthorizationDeclarationCache cache = services.GetRequiredService <IAuthorizationDeclarationCache>(); AuthorizationDeclarationInfo info = null; switch (context.ActionDescriptor) { case ControllerActionDescriptor controllerActionDescriptor: info = cache.Get(controllerActionDescriptor); break; case CompiledPageActionDescriptor compiledPageActionDescriptor: info = cache.Get(compiledPageActionDescriptor); break; default: throw new Exception($"not handled with action descriptor of type {context.ActionDescriptor.GetType().Name}"); } if (info != null && info.Declaration != AuthorizationDeclaration.No && info.FailedAction == AuthorizationFailedAction.CustomHandler && info.FailedHandler != null) { IActionResult actionResult = info.FailedHandler.Execute(context.HttpContext, result); if (actionResult != null) { context.Result = actionResult; return; } else { // not handled throw new Exception($"not handled"); } } throw new Exception($"no handler set for type {context.ActionDescriptor.GetType().Name}"); }