首页 新闻 会员 周边

asp.net core 项目有多个授权方案时,如何在一个不需要登录的页面取到非默认授权方案的登录凭证

0
悬赏园豆:10 [已解决问题] 解决于 2020-06-17 17:39

有三组Api(或页面),使用不同的授权方案,要求彼此独立,但默认只有授权方案只有一个。

需要授权的api(或页面)好解决,使用Authorize(AuthenticationSchemes = "")在对应的控制器、方法、Razor Pages标注就可以了。

但是对于不需要授权的api(或页面)且不是默认授权方案的,怎么确保 HttpContext.User 获取到的是当前Api(或页面)所在授权方案内中获取的 User 信息。

举个栗子:

三组接口或api:A组页面使用Cookie授权方案,B组Api使用自定义授权方案,C组Api使用JwtBearer授权方案,A、B、C互不兼容,且A、B、C组内都分别有需要授权的和不需要授权的接口(或页面)。

假设A1、B1、C1是需要授权的,A2、B2、C2是不需要授权就能访问的。

历史原因,需优先确保B组接口正常,因为B组Api接口在大量使用中,接口众多且不好修改,能不动就不动,只能设置成默认的授权方案(即自定义的授权方案),杜绝出现B2接口内部识别不了当前请求用户的情况。

现在的问题是:
A2页面顶部有个导航条需要显示当前登录的用户名,因为这个页面不需要授权,即不能使用Authorize(AuthenticationSchemes = "") 标注,也就没法区分这个页面到底属于那组,那么只能取默认的,即这个页面内 HttpContext.User 获取到的是B组的登录凭证。

Adming的主页 Adming | 初学一级 | 园豆:119
提问于:2020-06-14 23:35
< >
分享
最佳答案
0

你看看是否可以这样实现
ABC各定义一组授权标注,在需要授权的PAI加上对应的注解即可,不需要授权的PAI加上AllowAnonymous注解即可。
在授权方案中,首先是检索是否有不授权注解,如果有,那么直接返回,大概代码如下:
/// <summary>
/// A授权认证过滤器
/// </summary>
public class AAuthFilterAttribute : AuthorizationFilterAttribute
{
/// <summary>
/// 认证授权验证
/// </summary>
/// <param name="actionContext">请求上下文</param>
public override void OnAuthorization(HttpActionContext actionContext)
{
// 有 AllowAnonymous 属性的接口直接开绿灯
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
return;
}

         // 对应A的授权逻辑,自己实现

    }
}

/// <summary>
/// B授权认证过滤器
/// </summary>
public class BAuthFilterAttribute : AuthorizationFilterAttribute
{
/// <summary>
/// 认证授权验证
/// </summary>
/// <param name="actionContext">请求上下文</param>
public override void OnAuthorization(HttpActionContext actionContext)
{
// 有 AllowAnonymous 属性的接口直接开绿灯
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
return;
}

         // 对应B的授权逻辑,自己实现

    }
}

/// <summary>
///C授权认证过滤器
/// </summary>
public class CAuthFilterAttribute : AuthorizationFilterAttribute
{
/// <summary>
/// 认证授权验证
/// </summary>
/// <param name="actionContext">请求上下文</param>
public override void OnAuthorization(HttpActionContext actionContext)
{
// 有 AllowAnonymous 属性的接口直接开绿灯
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
return;
}

         // 对应C的授权逻辑,自己实现
    }
}
收获园豆:10
程序员修炼之旅 | 小虾三级 |园豆:776 | 2020-06-15 09:16

是可以这样实现,引起这个bug的原因就是 AuthorizeAttribute 可以指定 AuthenticationSchemes AllowAnonymousAttribute 却没有对应的参数可以区分

Adming | 园豆:119 (初学一级) | 2020-06-15 09:26

引起这个的原因就是默认系统只能有一个默认的 AuthenticationScheme,在 AuthenticationMiddleware 未显示用 AuthorizeAttribute 指定 AuthenticationSchemes 时,它就取的是默认的。
修复方法就是,重写 HttpContext.User,用你的这种方式也行,直接写在业务逻辑前也可以。
// 在A2页面 OnGet 最前面加上如下代码即可
var result = await this.HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
if (result?.Principal != null)
{
this.HttpContext.User = result.Principal;
}

不知道这个算不算是一个bug

Adming | 园豆:119 (初学一级) | 2020-06-15 09:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册