Asp.Net样板.Net Core 2.0 AbpAuthorizationFilter-ChallengeResult/未经授权 [英] Asp.Net Boilerplate .Net Core 2.0 AbpAuthorizationFilter - ChallengeResult / Unauthorized

查看:215
本文介绍了Asp.Net样板.Net Core 2.0 AbpAuthorizationFilter-ChallengeResult/未经授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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:

  1. 添加我自己的授权过滤器,并在AddAbp()服务配置之前向MvcOptions注册.过滤器会有条件地将结果设置为挑战"或禁止"
  2. 覆盖OnRedirectToLogin事件(即为经过身份验证的用户自定义)
  3. 覆盖HandleChallengeAsync处理程序(即检查请求是否已通过身份验证,并为未通过身份验证的请求发出ForbidResult或ChallengeResult)
  1. Add my own authorization filter and register with the MvcOptions prior to the AddAbp() service configuration. The filter would conditionally set the result to Challenge or Forbid
  2. Override the OnRedirectToLogin event ( i.e., customize for authenticated users )
  3. Override the HandleChallengeAsync handler ( i.e., check to see if the request is authenticated and issue ForbidResult or ChallengeResult for unauthenticated requests)

在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:

  1. 引入了最少的代码,而无需复制整个授权过滤器以仅更改两行代码.
  2. 具有一组自己的角色和权限(请参见下面的代码解决方案),可以更好地控制挑战体验(MVC应用程序也是OIDC客户端)
  3. 在做出响应时,OnRedirectToLogin事件仅由HandleChallengeAsync引发. AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs#L441"rel =" nofollow noreferrer> CookieAuthenticationHandler ,所以这就像是覆盖ChallengeResult行为的正确位置.
  1. Minimal code introduced without duplicating an entire authorization filter to only change two lines of code.
  2. More control of the challenge experience ( the MVC app is an OIDC client too ) with its own set of roles and permissions ( see code solution below )
  3. At the time of this response, the OnRedirectToLogin event is only raised by the HandleChallengeAsync in the CookieAuthenticationHandler so this feels like the correct place to override the ChallengeResult behavior.

解决方案:

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-ChallengeResult/未经授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆