我正在使用asp.net识别来保护我的API,我使用以下函数在登录
时创建访问代币用户private string GenerateAccessToken(string userName, string role)
{
ClaimsIdentity oAuthIdentity = new ClaimsIdentity(Startup.OAuthOptions.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, userName));
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Role, role));
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
DateTime currentUtc = DateTime.UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromDays(365));
string accessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
Request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
return accessToken;
}
一切都很好,直到我执行帐户密码更新,之后我更新了SecurityStamp
UserManager.UpdateSecurityStampAsync(loggedinUser.Id);
,但问题在于,令牌仍然可以用来调用我的API毫无问题。那么,如何使用每个请求检查安全措施?
您可以使用startup.cs
中配置的JwtBearerEvents
检查SecurityStamp
或根据.NET版本的program.cs
。
这是SecurityStamp
验证的非常简单的版本(.net 6):
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(cfg =>
{
cfg.Events = new JwtBearerEvents
{
OnTokenValidated = async (ctx) =>
{
var signInManager = ctx.HttpContext.RequestServices
.GetRequiredService<SignInManager<ApplicationUser>>();
var user = await signInManager.ValidateSecurityStampAsync(ctx.Principal);
if (user == null)
{
ctx.Fail("Invalid Security Stamp");
}
}
};
// more code...
});
注意:为了使此示例正常工作,您需要确保将SecurityStamp
与用户创建期间的索赔一起包装,如下示例。
var identityOptions = _config.Get<ClaimsIdentityOptions>();
claims.Add(new Claim(identityOptions.SecurityStampClaimType, user.SecurityStamp));