首页 > 解决方案 > 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);
    }
}

标签: c#jwt

解决方案


如果我错了,请纠正我,但是您从 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()
    {

告诉我我是否正确理解了您的问题以及实施此问题是否有任何问题


推荐阅读