事实证明,这毕竟是我想多了。
由于我正在处理 API 后端,我需要做的就是验证 IDP Bearer 令牌,而不是创建它们。最后,我能够使用以下简单代码验证 3 个 ID 提供者:
services.AddAuthentication(OKTA_SCHEME)
.AddJwtBearer(ADFS_SCHEME, options =>
{
options.Authority = adfsConfig.authority;
options.Authority = adfsConfig.authority;
})
.AddJwtBearer(GOOGLE_SCHEME, jwt => jwt.UseGoogle(
clientId: googleConfig.clientId
))
.AddJwtBearer(OKTA_SCHEME, options =>
{
options.Authority = oktaConfig.authority;
options.Audience = oktaConfig.audience;
});
请注意,这需要安装一个额外的 nuget 包来简化 Google 令牌的验证,这似乎不符合标准:Hellang.Authentication.JwtBearer.Google。
此时我可以使用以下属性进行授权:
[Authorize(AuthorizationSchemes = OKTA_SCHEME)]
...或根据方案设置策略。
第二部分的问题是将我的各种登录链接到本地数据库中的用户,我最终使用自定义 IClaimsTransformation 执行此操作,该 IClaimsTransformation 使用填充到 ClaimsPrincipal 的信息在我的数据库中查找用户,并添加一个“员工" 角色声明,如果找到的话。
public class EmployeeClaims : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
if (!principal.HasClaim(a => a.Type == "EmployeeNumber"))
{
Employee employee = lookupEmployee(principal);
if (employee != null)
{
ClaimsIdentity id = new ClaimsIdentity();
id.AddClaim(new Claim(ClaimTypes.Role, "Employee"));
id.AddClaim(new Claim("EmployeeNumber", employee.EmployeeNumber.ToString()));
principal.AddIdentity(id);
}
}
return Task.FromResult(principal);
}
private Employee lookupEmployee(ClaimsPrincipal principal) {
string issuer = principal.Claims.Single(a => a.Type == "iss").Value;
if (issuer.Contains("google.com"))
...
}
}
然后,此 IClaimsTransformation 由以下人员注册:
services.AddScoped<IClaimsTransformation, EmployeeClaims>();
现在我可以额外授权员工:
[Authorize(Roles = "Employee")]