使用ASP.NET Core 2.0进行身份验证期间向用户添加自定义声明
就在最近的一个小型业余项目中,我需要一种方法来向用户使用Azure AD登录后向其注入声明。具体来说,一些角色和其他与用户可以在应用程序中执行的操作有关的事情。
事实证明这很容易。这将是一篇简短的文章。
OpenID连接
可以在OnTokenValidated事件中添加自定义声明,如下所示:
services
.AddAuthentication(o =>
{
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(o =>
{
//Additional config snipped
o.Events = new OpenIdConnectEvents
{
OnTokenValidated = async 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 EF context
var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();
//Check is user a super admin
bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == oid);
if (isSuperAdmin)
{
//Add claim if they are
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role, "superadmin")
};
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
}
};
});
在这里,我们:
- 从依赖项注入容器获取EF数据库上下文
- 使用它来尝试在表中查找用户
- 如果找到,则将超级管理员角色应用于他们
此后,所有现有的索赔仍然存在。我们仅添加新的声明。由于我们使用cookie身份验证作为登录方案,因此此新声明也将写入cookie。因此,它将在以后的所有请求中可用。
我在GitHub上为此制作了一个示例应用程序:https : //github.com/juunas11/CustomOidcClaims。
智威汤逊
确实与以前类似,请看一下:
services
.AddAuthentication(o =>
{
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
//Additional config snipped
o.Events = new JwtBearerEvents
{
OnTokenValidated = async ctx =>
{
//Get the calling app client id that came from the token produced by Azure AD
string clientId = ctx.Principal.FindFirstValue("appid");
//Get EF context
var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();
//Check if this app can read confidential items
bool canReadConfidentialItems = await db.Applications.AnyAsync(a => a.ClientId == clientId && a.ReadConfidentialItems);
if (canReadConfidentialItems)
{
//Add claim if yes
var claims = new List<Claim>
{
new Claim("ConfidentialAccess", "true")
};
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
}
};
});
如果您需要解释所发生的情况,请查看OIDC上的上一部分:D
您可以在那里执行各种逻辑,并且可以访问DI以及HTTP上下文。
尽管如果在应用的所有部分中都不需要这些声明,则最好检查授权策略中的访问权限:)
不过,OnTokenValidated可以在JWT Bearer的每个请求上运行,因此,如果可以将声明包含在令牌中,那肯定更好!
浙公网安备 33010602011771号