azure - 将 Azure AD B2C 用户连接到我的数据库帐户的正确 Core 3.0 API 中间件?
问题描述
我有一个 .Net Core 3 API,可以正确授权和验证通过 Azure AD B2C 传递给它的令牌。它还构建了一些自定义代码,用于检查 JWT 令牌中传递的范围,以确认对端点的访问。(我正在使用 Microsoft.AspNetCore.Authentication.AzureADB2C.UI 包)这是使这成为可能的中间件块:
services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
.AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
var issuer = $"https://{Configuration["AzureAdB2C_Custom:TenantB2CHost"]}/{Configuration["AzureAdB2C:Domain"]}/v2.0/";
services.AddAuthorization(options =>
{
options.AddPolicy("api_read", policy => policy.Requirements.Add(new HasScopeRequirement("api_read", issuer)));
options.AddPolicy("api_write", policy => policy.Requirements.Add(new HasScopeRequirement("api_write", issuer)));
});
这一切似乎都在努力正确地访问端点。然后,这些端点在模型中公开来自我的 SQL 数据库的各种信息。
但是,现在我正试图通过控制对在这些端点中检索到的数据的特定部分的访问,根据 JWT 令牌在我的数据库中实际绑定的对象,将我的安全性的另一个方面带回家。
在我的特定情况下,我有一个 Accounts 表,我可以在其中存储在 JWT 令牌中找到的来自 Azure AD B2C 的 ObjectID,然后在调用时使用该 ObjectID 获取 Account。我可以在端点的顶部执行此操作,但我怀疑这不是最好的方法。看来我应该在 Startup 的中间件层构建它作为某种处理程序。
有人可以为我确认这将是正确的方法,并可能给我一个例子,或者至少为我指明正确的方向吗?
解决方案
谢谢你们的回复。这是我为其他处理此问题的人所做的。向@juunas 大喊他发送的链接,这让我走上了正确的道路。该特定解决方案还不够,因为我使用 Azure AD B2C 库进行授权/身份验证。
这是我找到的链接,一旦我尝试从@juunas 实施解决方案: https ://blog.denious.net/azure-b2c-role-based-authorization-part-1/
根据我在该链接中发现的内容,我的解决方案最终看起来像这样:
//Azure ADB2C is injected for authentication
services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
.AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
services.PostConfigure<JwtBearerOptions>(
AzureADB2CDefaults.JwtBearerAuthenticationScheme,
o =>
{
o.Events = new JwtBearerEvents
{
OnTokenValidated = ctx =>
{
//Get user's immutable object id from claims that came from Azure AD
string oid = ctx.Principal
.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
//Get My Data EF context
var db = ctx.HttpContext.RequestServices.GetRequiredService<MyDataContext>();
//Grab the user - found in My Accounts table, tied to OID
var user = db.Accounts.Include("AccountType")
.Where(a => a.AuthorityId == oid)
.FirstOrDefault();
if (user != null)
{
// since we're using AADB2C only, the first identity is the only identity
var identity = ctx.Principal.Identities.First();
//Place My user type into the claims as a role claim type
var extraRoleClaim = new Claim(identity.RoleClaimType, user.AccountType);
identity.AddClaim(extraRoleClaim);
}
return Task.CompletedTask;
}
};
});
设置完成后,我就可以在端点内部执行此操作:
if (User.IsInRole("Some Role"))
{
return Ok();
}
else
{
return StatusCode(403, "Forbidden - Unacceptable Role");
}
从链接中注意,我还可以在我的授权属性中对控制器或操作执行以下操作:[Authorize(Roles = "Some Role")]
推荐阅读
- python - 该应用程序使用 UWSGI 和 Flask (tiangolo/uwsgi-nginx-flask) 在生产模式下运行两次
- postgresql - Postgres:带有时区的时间戳类型的无效输入语法:“”
- sql - 使用 SQL 汇总数据
- css - Web 配置和 IIS
- excel - Excel宏上的元素相乘
- typescript - 嵌入另一个泛型的 TypeScript 泛型
- c# - 可以在 ApiMember 属性和 xmldoc 摘要注释中使用相同的描述吗?
- vue.js - 制表符:在单元格焦点上加载编辑器参数
- android - 如何从输入法服务更改导航栏的颜色?
- c# - 如何使用 user32.dll 将 VB 转换为 CSharp?