Identity Server 4 自定义令牌端点,在运行时获取签名凭证
Identity Server 4 custom token endpoint, get signingcredential at runtime
我正在为我的 identityserver4 项目实现自定义令牌端点。目标是根据更复杂的凭据模型(与 Identity Server 的内置“client/scope”概念不同的用户数据库)的验证来颁发令牌,并颁发带有额外声明的 Jwt 令牌以帮助用户身份和我自定义的访问权限 api.
我的代码是这样的:
[HttpPost]
public IActionResult GetCustomApiToken(CustomUserCredentialsModel credentials)
{
var customUser = GetCustomValidatedUser(credentials); //validate user from DB
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(ApplicationSettings.SigningKey); // <--- DeveloperSigningCredential ???
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] { new Claim("user", customUser.ToString()) /* extra custom claims */ }),
Issuer = "my identity server",
Audience = "my custom api",
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
请注意,我还没有完全测试上面的内容,但是如果密钥在 ApplicationSettings 中进行管理,类似的东西应该可以在生产环境中使用。
但它不会在通过 Identity Server 4 的 AddDeveloperSigningCredential() 扩展添加签名密钥的开发中工作。
一种解决方案是在所有 Dev/Test 环境(= 麻烦)的配置中添加 SigningCredentials。
我能否在运行时解析签名凭据(因为它们在 Program/Startup 中设置)?
(此外,是的,我知道:不要在 appSettings 中存储可读的签名密钥,请忽略上面示例中的内容。)
好的,我明白了,您可以注入 ISigningCredentialStore 单例并从那里解析 signingCredential:
private readonly ISigningCredentialStore _signingCredentialStore;
public CustomTokenController(ISigningCredentialStore signingCredentialStore)
{
_signingCredentialStore = signingCredentialStore ?? throw new ArgumentNullException(nameof(signingCredentialStore));
}
[HttpPost]
public async Task<IActionResult> GetCustomApiToken(CustomUserCredentialsModel credentials)
{
var userId = GetCustomValidatedUser(credentials);
if (userId == null) return Unauthorized();
var signingCredentials = await _signingCredentialStore.GetSigningCredentialsAsync();
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] { new Claim("userId", userId.ToString()) /* extra custom claims */ }),
Issuer = "my IdentityServer",
IssuedAt = DateTime.UtcNow,
Audience = "my api",
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = signingCredentials
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
这对我有用,生成的 Jwt 令牌可以像内置“connect/token”端点发出的任何令牌一样进行验证。
我正在为我的 identityserver4 项目实现自定义令牌端点。目标是根据更复杂的凭据模型(与 Identity Server 的内置“client/scope”概念不同的用户数据库)的验证来颁发令牌,并颁发带有额外声明的 Jwt 令牌以帮助用户身份和我自定义的访问权限 api.
我的代码是这样的:
[HttpPost]
public IActionResult GetCustomApiToken(CustomUserCredentialsModel credentials)
{
var customUser = GetCustomValidatedUser(credentials); //validate user from DB
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(ApplicationSettings.SigningKey); // <--- DeveloperSigningCredential ???
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] { new Claim("user", customUser.ToString()) /* extra custom claims */ }),
Issuer = "my identity server",
Audience = "my custom api",
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
请注意,我还没有完全测试上面的内容,但是如果密钥在 ApplicationSettings 中进行管理,类似的东西应该可以在生产环境中使用。 但它不会在通过 Identity Server 4 的 AddDeveloperSigningCredential() 扩展添加签名密钥的开发中工作。
一种解决方案是在所有 Dev/Test 环境(= 麻烦)的配置中添加 SigningCredentials。
我能否在运行时解析签名凭据(因为它们在 Program/Startup 中设置)?
(此外,是的,我知道:不要在 appSettings 中存储可读的签名密钥,请忽略上面示例中的内容。)
好的,我明白了,您可以注入 ISigningCredentialStore 单例并从那里解析 signingCredential:
private readonly ISigningCredentialStore _signingCredentialStore;
public CustomTokenController(ISigningCredentialStore signingCredentialStore)
{
_signingCredentialStore = signingCredentialStore ?? throw new ArgumentNullException(nameof(signingCredentialStore));
}
[HttpPost]
public async Task<IActionResult> GetCustomApiToken(CustomUserCredentialsModel credentials)
{
var userId = GetCustomValidatedUser(credentials);
if (userId == null) return Unauthorized();
var signingCredentials = await _signingCredentialStore.GetSigningCredentialsAsync();
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] { new Claim("userId", userId.ToString()) /* extra custom claims */ }),
Issuer = "my IdentityServer",
IssuedAt = DateTime.UtcNow,
Audience = "my api",
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = signingCredentials
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
这对我有用,生成的 Jwt 令牌可以像内置“connect/token”端点发出的任何令牌一样进行验证。