我配置了多个外部身份验证提供程序,例如Facebook、MSA 等。当用户通过其中任何一个登录时,我想转换/规范化声明并可能添加其他自定义声明,例如角色,在用户被发送回客户端之前。这样我的客户就不必关心用户通过哪个提供商登录,因为 token 中的所有声明都是相同的。 IE。无需在客户端转换声明。
我还想根据用户登录的提供商来执行此操作。
我研究过使用 UserClaimsPrincipalFactory<TUser>
(支持 DI)然后用 AddClaimsPrincipalFactory
注册我的实现.这是首选方法吗?但是我在这里看不到使用哪个提供商登录,因为身份验证方法始终是 Identity.Application
.此处的声明中没有任何内容表明使用了哪个提供商。
我也研究过替换 SignInManager<TUser>
然后覆盖方法 SignInAsync
,但如果我在此处更改声明,则它不会反射(reflect)在发送给客户端的 token 中。还有参数 authenticationMethod
用户首次登录并完成同意和电子邮件/用户名确认屏幕时为空。
我还想避免替换 GetExternalLoginInfoAsync
中自动处理的大部分代码。和 ExternalLoginSignInAsync
从帐户 Controller 调用的方法。
我假设转换来自外部提供者的声明将是一等公民功能,但不清楚如何以及在何处进行操作,因此它已正确存储在数据库中(假设使用了 ASP.NET Core Identity)和 token 。
最佳答案
我发现使用 IClaimsTransformation
转换声明对我有用。它似乎在所有版本的 .NET Core 中都可用,我添加/更新的信息传递给客户端调用 IdentityServer。
注意这个类可能会被调用多次,所以转换应该是幂等的。
这是一个声明转换示例,它将用 DEMO
替换 given_name
public class DemoClaimsTransformator : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
if (!(principal.Identity is ClaimsIdentity identity))
{
return Task.FromResult(principal);
}
var existingClaim = identity.FindFirst("given_name");
if (existingClaim != null)
{
identity.RemoveClaim(existingClaim);
}
identity.AddClaim(new Claim("given_name", "DEMO"));
return Task.FromResult(principal);
}
}
我在这篇博文中发现了它: https://davidwalschots.com/how-to-add-additional-claims-to-the-httpcontext-user/
关于asp.net-identity - 转换和规范化来自外部身份验证提供商的声明的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48410868/