c# - 在使用来自外部提供者的 ASP.NET 身份和 JWT 身份验证时,我可以使用角色和声明的授权属性过滤吗?
问题描述
所以我在我的 WebAPI 应用程序上使用 firebase 进行身份验证。它获取一个 JWT 令牌,然后对其进行身份验证,然后将声明放入HttpContext.User
.
我唯一的问题是我只想使用 Firebase 身份验证进行身份验证,而不是授权。我想为此使用 ASP.NET Identity。
所以现在,当有人连接到我的服务器时,我会检查他们是否没有帐户,如果没有,我会为他们创建一个。
var name = _contextAccessor.HttpContext.User.Claims.First(c => c.Type == "user_id").Value;
ApplicationUser user = await _userManager.FindByNameAsync(name);
if (user == null)
{
user = new ApplicationUser(name);
await _userManager.CreateAsync(user);
}
所以这是可行的,现在 ASPNetUsers 中有一个针对用户的记录,稍后,我可以根据我想要的任何业务规则为其提供声明和角色。
但是,我的问题是,以前,当我使用 ASP.NET Identity 时,我已经能够利用 Authorize 属性等所有内置功能来进行授权。
因此,如果身份验证和授权都使用 ASP.NET Identity 完成,我可以编写
[Authorize(Roles = "Administrator")]
显然,这不适用于外部身份验证,因为HttpContext.User
是 Firebase Authenticated 用户,而不是具有管理员角色的相应 ASP.NET 身份用户。
有没有办法自定义现有的 Authorize 属性以将其配置为以某种方式将我的 firebase 令牌转换为 ASP.NET 身份,以便它能够识别角色并声称它具有,或者如果我想通过中间件来完成所有这些,我会去吗需要编写我自己的授权属性吗?
解决方案
好的,所以我终于想通了。在 Jwt 身份验证过程中,您似乎可以拦截几个事件。特别是,有一个 OnTokenValidated 事件。
services.AddJwtBearer(options =>
{
...
options.Events = new JwtBearerEvents
{
OnTokenValidated = async ctx =>
{
// 1. grabs the user id from firebase
var name = ctx.Principal.Claims.First(c => c.Type == "user_id").Value;
// Get userManager out of DI
var _userManager = ctx.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>();
// 2. retrieves the roles that the user has
ApplicationUser user = await _userManager.FindByNameAsync(name);
var userRoles = await _userManager.GetRolesAsync(user);
//3. adds the role as a new claim
ClaimsIdentity identity = ctx.Principal.Identity as ClaimsIdentity;
if (identity != null)
{
foreach (var role in userRoles)
{
identity.AddClaim(new System.Security.Claims.Claim(ClaimTypes.Role, role));
}
}
}
};
});
那么上面的代码在说什么
- 令牌通过身份验证后,从外部提供者处获取 userId
进入 ASP.NET Identity 并找到该用户的用户和角色 [记住我最初的问题,当他们第一次登录时,我将用户插入到 ASP.NET Identity 表中,我只是抓住了那个用户]
将该用户的角色重新插入到 ClaimsIdentity
结果是,当 Authorize 属性运行时,它会在检查中包含用户的 AspNET 身份角色,我可以执行以下操作,它会检查角色。
[Authorize(Roles = "Administrator")]
推荐阅读
- python - 尝试在 Instagram 上上传图片时遇到问题
- java - 不支持的 JavaFX 配置:运行 jar 文件时从“未命名模块 @121464c3”加载类
- javascript - 将嵌套对象的数组合并到同一对象的数组中的简单方法
- ios - Google-Mobile-Ads-SDK 在主应用程序和框架中使用时因初始化错误而失败
- symfony - 迁移:每次我尝试运行迁移时加载迁移列表
- android - Fragment 从不接收来自共享 ViewModel 的 LiveData 更新
- javascript - 在开关中投射类型
- git - 父模块中的 git status 未显示子模块中的新提交
- apache - 反向代理尝试将子目录重定向到 Symfony 特定路由
- python - 在 Python 中序列化/反序列化类对象的最佳方法是什么?