具有 ASP.NET 身份 3 的 JWT 不记名令牌
JWT bearer tokens w/ ASP.NET Identity 3
基于 Shaun Luttin 在 的出色示例,我能够使用该代码生成和使用不记名令牌。微小的变化是为了获得最新的软件包:
"dependencies": {
"Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4"
}
尽管该代码是一个很好的开始,但它并不是一个完全集成了 w/ASP.NET Identity 的完整解决方案。我修改了 AuthorizationProvider class 如下:
public override Task GrantResourceOwnerCredentials(
GrantResourceOwnerCredentialsContext context)
{
var user = _userManager.FindByNameAsync(context.UserName).Result;
if (user == null)
{
context.Rejected("The user name or password is incorrect.");
}
else
{
var signInManager = context.HttpContext.RequestServices
.GetRequiredService<SignInManager<ApplicationUser>>();
if (signInManager.CanSignInAsync(user).Result &&
_userManager.CheckPasswordAsync(user, context.Password).Result)
{
var principal = signInManager.CreateUserPrincipalAsync(user).Result;
//To avoid leaking confidential data, AspNet.Security.OpenIdConnect.Server
//refuses to serialize the claims that don't explicitly specify a destination.
foreach (var claim in principal.Claims)
claim.WithDestination("token id_token");
context.Validated(principal);
}
else
context.Rejected("The user name or password is incorrect.");
}
return Task.FromResult(0);
}
我正在使用 CreateUserPrincipalAsync 为 Validated 方法创建 ClaimsPrincipal。有没有更好的方法来集成 w/ ASP.NET Identity?
您的实施看起来不错,次要 3 评论:
- 您应该使用
async/await
来避免 .Result
阻塞调用。
- 您应该考虑按照 OAuth2 规范的要求实施暴力反制措施:https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2。使用 Identity 3 可以轻松做到这一点,因为它提供了对“锁定”的本机支持。
- 您必须记住,此实现将导致序列化与用户关联的所有声明(甚至是自定义声明),其中可能包含机密数据。
最后两点在 OpenIddict
(内部使用 AspNet.Security.OpenIdConnect.Server
的全新实验性 OIDC 服务器)中得到缓解,所以请不要犹豫,看看它的默认实现:https://github.com/openiddict/core/blob/dev/src/OpenIddict.Core/OpenIddictProvider.cs#L353.
基于 Shaun Luttin 在
"dependencies": {
"Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4"
}
尽管该代码是一个很好的开始,但它并不是一个完全集成了 w/ASP.NET Identity 的完整解决方案。我修改了 AuthorizationProvider class 如下:
public override Task GrantResourceOwnerCredentials(
GrantResourceOwnerCredentialsContext context)
{
var user = _userManager.FindByNameAsync(context.UserName).Result;
if (user == null)
{
context.Rejected("The user name or password is incorrect.");
}
else
{
var signInManager = context.HttpContext.RequestServices
.GetRequiredService<SignInManager<ApplicationUser>>();
if (signInManager.CanSignInAsync(user).Result &&
_userManager.CheckPasswordAsync(user, context.Password).Result)
{
var principal = signInManager.CreateUserPrincipalAsync(user).Result;
//To avoid leaking confidential data, AspNet.Security.OpenIdConnect.Server
//refuses to serialize the claims that don't explicitly specify a destination.
foreach (var claim in principal.Claims)
claim.WithDestination("token id_token");
context.Validated(principal);
}
else
context.Rejected("The user name or password is incorrect.");
}
return Task.FromResult(0);
}
我正在使用 CreateUserPrincipalAsync 为 Validated 方法创建 ClaimsPrincipal。有没有更好的方法来集成 w/ ASP.NET Identity?
您的实施看起来不错,次要 3 评论:
- 您应该使用
async/await
来避免.Result
阻塞调用。 - 您应该考虑按照 OAuth2 规范的要求实施暴力反制措施:https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2。使用 Identity 3 可以轻松做到这一点,因为它提供了对“锁定”的本机支持。
- 您必须记住,此实现将导致序列化与用户关联的所有声明(甚至是自定义声明),其中可能包含机密数据。
最后两点在 OpenIddict
(内部使用 AspNet.Security.OpenIdConnect.Server
的全新实验性 OIDC 服务器)中得到缓解,所以请不要犹豫,看看它的默认实现:https://github.com/openiddict/core/blob/dev/src/OpenIddict.Core/OpenIddictProvider.cs#L353.