我正在使用JWT令牌进行用户控制。 登录没问题,但是如何注销?
数据库比较 我的想法, 你有更好的方法建议
令牌控制器 我在UyelikOnaylama类中验证了用户
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);
}
}
答案 0 :(得分:0)
如果我错了,请纠正我,但是您从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()
{
告诉我,如果我理解您的问题是正确的,并且在执行此操作时是否有任何问题