我正在使用 Asp.Net Boilerplate版本3.4.0 Web应用程序运行 Asp.Net Core 2.0 .
I am running an Asp.Net Core 2.0 with Asp.Net Boilerplate version 3.4.0 web application.
当我的身份验证的用户没有访问资源所需的权限时,AbpAuthorizationFilter会通过 Abp 框架由AbpAuthorizationFilter设置.此行为导致用户返回到默认登录页面.如果用户已通过身份验证,我想设置一个ForbidResult并将其重定向到默认的AccessDenied页面.
When I have an authenticated user that does not have the required permissions to access a resource, a ChallengeResult is set by the AbpAuthorizationFilter via the Abp framework. This behavior results in the user being returned to the default login page. If the user is authenticated, I would like to set a ForbidResult and redirect them to the default AccessDenied page.
查看我的选项后,我看到以下选项:
After reviewing my options, I see that I have the following options:
在ABP的.Net框架版本中,我注意到AbpMvcAuthorizeFilter(即HandleUnauthorizedRequest)中有可重写的方法;但是,这不适用于.Net Core版本.参见GitHub Issue 1256-> 使AbpMvcAuthorizeFilter和AbpApiAuthorizeFilter可以覆盖
I noticed in the .Net framework version of ABP, that there are overridable methods in the AbpMvcAuthorizeFilter (i.e., HandleUnauthorizedRequest) ; however, this does not apply to the .Net Core version. See GitHub Issue 1256 -> Make AbpMvcAuthorizeFilter and AbpApiAuthorizeFilter overridable
是否还有其他人需要更改默认的 Abp 行为,即为未授权的请求返回ChallengeResult?如果是,您使用了什么解决方案?是否在 Abp 配置或Asp.Net Core中缺少了某些东西(除了上面列出的三个选项之外),这些东西可以让我更好地控制这种行为?
Has anyone else needed to change the default Abp behavior of returning a ChallengeResult for unauthorized requests? If yes, what solution did you use? Did I missing something in the Abp configuration or Asp.Net Core ( other than the three options listed above) that would provide me more control of this behavior?
如果我要采取一种解决方法,则可以控制这种行为.
If I go with a workaround, it feels kind of a like a hack to control this behavior.
在我列出的三个选项中,选项一个似乎是处理此逻辑的最干净最合适的地方.这也不是很漂亮,因为我将复制整个AbpAuthorizationFilter来仅更改几行代码.
Out of the three options that I listed, option one seems the cleanest and most appropriate place to handle this logic. It's not pretty either as I would be copying the entire AbpAuthorizationFilter to only change a few lines of code.
当前代码:
context.Result = new ChallengeResult();建议的更改:
if (context.HttpContext.User.Identity.IsAuthenticated) { //User is already logged in.. No need to redirect to the //login page context.Result = new ForbidResult(); } else { context.Result = new ChallengeResult(); }下面的完整代码:
AbpAuthorizationFilter.cs 请参见捕获块行-58-77
AbpAuthorizationFilter.cs See Catch block lines - 58 - 77
选项2感觉 kludgy ,因为我将在OnRedirectToLogin事件中引入的逻辑必须假设已通过身份验证的用户已尝试访问未经授权的资源.当前,我仅看到通过HandleChallengeAsync方法在CookieAuthenticationHandler中引发了Events.RedirectToLogin.话虽这么说,可以放心地假设此事件仅由ChallengeResult结果引发. CookieAuthenticationHandler.cs
Option two feels kludgy because the logic that I would introduce into the OnRedirectToLogin event would have to make an assumption that an authenticated user has attempted to access an unauthorized resource. Currently, I only see the Events.RedirectToLogin being raised in the CookieAuthenticationHandler via the HandleChallengeAsync method. With that being said it feels safe to assume that this event would only be raised by a ChallengeResult result. CookieAuthenticationHandler.cs
选项3是最后一个选项(即,不惜一切代价避免使用
Option three would be the last option( i.e., avoided at all costs)
主要目标是为尝试访问未经授权的资源的经过身份验证的用户提供更好的体验.不应将用户重定向到登录页面,而应将用户重定向到一个未经授权/禁止的页面,该页面应明确表明他们未经授权.这可能包括一个选项,提示用户提供更高特权的凭据.通过提示用户,它闻起来像ChallengeResult结果流,所以也许我只是回答了我自己的问题.就目前的行为而言,我没有太多有关发布ChallengeResult的为什么" 的上下文信息.我将知道用户已登录并且引发了OnRedirectToLogin事件.这可能是足够的信息,可以为已验证的用户自定义ChallengeResult的行为.开始觉得这是正确的解决方案.有关使用此方法的任何建议或反馈?
The main goal is to provide a better experience for authenticated users attempting to access unauthorized resources. Rather than redirecting the user to the login page, the user should be redirected to an unauthorized / forbidden page that clearly indicates that they are not authorized. This might include an option to prompt the user to provide higher privileged credentials. By prompting the user, it smells like a ChallengeResult result flow so maybe I just answered my own question. With the current behavior, I don't have much context information on "why" the ChallengeResult was issued. I will know that the user is logged in and that the OnRedirectToLogin event was raised. This is probably enough info to customize the behavior of the ChallengeResult for authenticated users. This is starting to feel like this is the correct solution. Any suggestions or feedback on using this approach?
推荐答案出于以下原因,在三个选项中,我选择了第二个选项(覆盖OnRedirectToLogin事件):
Out of the three options, I went with option number two ( override the OnRedirectToLoginevent) for the following reasons:
解决方案:
options.Events.OnRedirectToLogin = context => { if (context.HttpContext?.User?.Identity?.IsAuthenticated == false) { //The user is not authenticated... Use the "oidc" challenge scheme //and send them to identity server. var task = context.HttpContext.ChallengeAsync("oidc"); task.WaitAndUnwrapException(); return Task.CompletedTask; } var accessDeniedPath = BuildRedirectUri(context.HttpContext, options.AccessDeniedPath); context.Response.Redirect(accessDeniedPath); context.Response.StatusCode = 302; return Task.CompletedTask; };旁注:
应注意,AbpAuthorizationFilter的默认行为不会反映Asp.Net Core MVC 2.0 AuthorizeFilter的库存行为.如果对经过身份验证的用户的授权失败,则Asp.Net Core MVC 2.0 AuthorizeFilter会返回禁止结果.
It should be noted that the default behavior of the AbpAuthorizationFilter does not mirror the stock behavior of Asp.Net Core MVC 2.0 AuthorizeFilter. When authorization fails for an authenticated user, the Asp.Net Core MVC 2.0 AuthorizeFilter returns a Forbid result.
Asp.Net Core MVC的默认AuthorizeFilter将授权委派给IPolicyEvaluator.如果授权失败并且对用户进行了身份验证,则设置为禁止"结果;或者,如果授权失败并且未对用户进行身份验证,则将设置挑战"结果.
Asp.Net Core MVC's default AuthorizeFilter delegates the authorization to the IPolicyEvaluator. If the authorization fails and the user is authenticated, a Forbid result is set or if the authorization fails and the user is not-authenticated, a Challenge result is set.
PolicyEvaluator.cs
var result = await _authorization.AuthorizeAsync(context.User, resource, policy); if (result.Succeeded) { return PolicyAuthorizationResult.Success(); } // If authentication was successful, return forbidden, otherwise challenge return (authenticationResult.Succeeded) ? PolicyAuthorizationResult.Forbid() : PolicyAuthorizationResult.Challenge();更多推荐
Asp.Net样板.Net Core 2.0 AbpAuthorizationFilter
发布评论