c# - JWT 令牌删除或注销
问题描述
我正在使用 JWT 令牌进行用户控制。登录没问题,但是怎么退出呢?
数据库比较我的看法,有没有更好的方法建议
令牌控制器我在 UyelikOnaylam 类中验证用户
public class TokenController : ApiController
{
[HttpPost]
public async Task<HttpResponseMessage> Post(TokenRequestDto dto)
{
UyelikOnaylama uyelikOnaylama = new UyelikOnaylama();
var sonuc = await uyelikOnaylama.AsekronMethod(dto);
Random random = new Random();
if (sonuc==1)
{
var claims = new[]
{
new Claim(ClaimTypes.Name, dto.UserName),
new Claim(ClaimTypes.Role, random.ToString()+"asd"),
new Claim("scope", random.ToString()+"tasd"),
new Claim("scope", "**")
};
var token = new JwtSecurityToken(
issuer: "localhost",
audience: "localhost",
claims: claims,
expires: DateTime.UtcNow.AddMonths(30),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("!^'+sda1905SDASDQdqqdD'^+!34123")), SecurityAlgorithms.HmacSha256)
);
return Request.CreateResponse(HttpStatusCode.OK, new JwtSecurityTokenHandler().WriteToken(token));
}
else
{
return Request.CreateResponse(HttpStatusCode.Unauthorized, "Hatalı kullanıcı adı ya da parola");
}
}
}
我正在检查一个启动类
public class Startup
{
public void Configuration(IAppBuilder app)
{
string secretKey = "!^'+sda1905SDASDQdqqdD'^+!34123";
var opt = new JwtBearerAuthenticationOptions();
var prov = new SymmetricKeyIssuerSecurityKeyProvider[1];
prov[0] = new SymmetricKeyIssuerSecurityKeyProvider("localhost", Encoding.UTF8.GetBytes(secretKey));
opt.IssuerSecurityKeyProviders = prov;
opt.AllowedAudiences = new String[1] { "localhost" };
app.UseJwtBearerAuthentication(opt);
}
}
解决方案
如果我错了,请纠正我,但是您从 JWT 服务中获得了 AccessToken?使用此令牌,您可以获得访问 WebApi 上的数据(或您使用它执行的任何操作)所需的权限。如果您的用户注销,AccessToken 仍然可用。
如果这是您的问题,只需从包含所有令牌的列表中删除令牌。您还可以减少令牌过期的时间
解决方案
将这 3 个类添加到您的项目中
public static class JwtSecurityKey
{
public static SymmetricSecurityKey Create(string secret)
{
return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret));
}
}
public sealed class JwtToken
{
private JwtSecurityToken Token;
internal JwtToken(JwtSecurityToken token)
{
this.Token = token;
}
public DateTime ValidTo => Token.ValidTo;
public string Value => new JwtSecurityTokenHandler().WriteToken(this.Token);
}
public class JwtTokenBuilder
{
private SecurityKey SecurityKey = null;
private string Subject = "";
private string Issuer = "";
private string Audience = "";
private Dictionary<string, string> Claims = new Dictionary<string, string>();
private int ExpiryInMinutes = 5;
public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey)
{
this.SecurityKey = securityKey;
return this;
}
public JwtTokenBuilder AddSubject(string subject)
{
this.Subject = subject;
return this;
}
public JwtTokenBuilder AddIssuer(string issuer)
{
this.Issuer = issuer;
return this;
}
public JwtTokenBuilder AddAudience(string audience)
{
this.Audience = audience;
return this;
}
public JwtTokenBuilder AddClaim(string type, string value)
{
this.Claims.Add(type, value);
return this;
}
public JwtTokenBuilder AddClaims(Dictionary<string, string> claims)
{
this.Claims.Union(claims);
return this;
}
public JwtTokenBuilder AddExpiry(int expiryInMinutes)
{
this.ExpiryInMinutes = expiryInMinutes;
return this;
}
public JwtToken Build()
{
EnsureArguments();
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, this.Subject),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}
.Union(this.Claims.Select(item => new Claim(item.Key, item.Value)));
var token = new JwtSecurityToken(
issuer: this.Issuer,
audience: this.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(ExpiryInMinutes),
signingCredentials: new SigningCredentials(
this.SecurityKey,
SecurityAlgorithms.HmacSha256));
return new JwtToken(token);
}
#region Privates
private void EnsureArguments()
{
if (this.SecurityKey == null)
throw new ArgumentNullException("Security Key");
if (string.IsNullOrEmpty(this.Subject))
throw new ArgumentNullException("Subject");
if (string.IsNullOrEmpty(this.Issuer))
throw new ArgumentNullException("Issuer");
if (string.IsNullOrEmpty(this.Audience))
throw new ArgumentNullException("Audience");
}
#endregion
}
在您的 Startup 类中,调用此方法:
private void ConfigureTokenServices(IServiceCollection services)
{
// Add Token Authentication
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Custom.Security.Bearer",
ValidAudience = "Custom.Security.Bearer",
IssuerSigningKey = JwtSecurityKey.Create("Yout securitykey which must be a very long string to work")
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Debug.WriteLine("OnAuthenticationFailed: " + context.Exception.Message);
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
Debug.WriteLine("OnTokenValidated: " + context.SecurityToken);
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("Guest",
policy => policy.RequireClaim("Role", "Add here your roles"));
});
}
并添加这一行
app.UseAuthentication();
至
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
有了这个,你就可以在你的 Controller 中进行过滤,这就是 JWT 的意义:
[Produces("application/json")]
[Route("YourRoute")]
[Authorize("Role")]
public class MyController
{
或者您可以直接在方法上执行此操作。
[Authorize("Role")]
[HttpGet, Route("YourRoute")]
public IActionResult HttpGet()
{
告诉我我是否正确理解了您的问题以及实施此问题是否有任何问题
推荐阅读
- arrays - 尝试使用非常数整数对数组进行切片时,Vivado 出现问题
- typescript - 在 VSCode 的 javascript/typescript 项目中的 JSDoc 注释中编写多行代码的正确方法是什么?
- python - 为拖放的对象编写欧拉积分器
- c# - 动态 CRM 的 aspx 页面中的用户“NT AUTHORITY\ANONYMOUS LOGON”错误登录失败
- express - 如何在基于 NUXT + EXPRESS 的项目中减小 vendor.js 的大小?
- javascript - 如何附加整个 HTML 集合
- database - 在mac中更改mongo db的位置
- highcharts - 有没有办法将多线图表工具提示格式化为单线?
- javascript - 按数组名称查询 Firestore
- c# - WPF Listview 项目模板