Cookie认证下验证JWT

ASP.NET Core中的cookies 认证不支持传递jwt。需要自定义实现 ISecureDataFormat接口的类。现在,你只是验证token,不是生成它们,只需要实现Unprotect方法,其他的交给System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler这个类处理。

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.IdentityModel.Tokens;
 
namespace SimpleTokenProvider
{
    public class CustomJwtDataFormat : ISecureDataFormat<AuthenticationTicket>
    {
        private readonly string algorithm;
        private readonly TokenValidationParameters validationParameters;
 
        public CustomJwtDataFormat(string algorithm, TokenValidationParameters validationParameters)
        {
            this.algorithm = algorithm;
            this.validationParameters = validationParameters;
        }
 
        public AuthenticationTicket Unprotect(string protectedText)
            => Unprotect(protectedText, null);
 
        public AuthenticationTicket Unprotect(string protectedText, string purpose)
        {
            var handler = new JwtSecurityTokenHandler();
            ClaimsPrincipal principal = null;
            SecurityToken validToken = null;
 
            try
            {
                principal = handler.ValidateToken(protectedText, this.validationParameters, out validToken);
 
                var validJwt = validToken as JwtSecurityToken;
 
                if (validJwt == null)
                {
                    throw new ArgumentException("Invalid JWT");
                }
 
                if (!validJwt.Header.Alg.Equals(algorithm, StringComparison.Ordinal))
                {
                    throw new ArgumentException($"Algorithm must be '{algorithm}'");
                }
 
                // Additional custom validation of JWT claims here (if any)
            }
            catch (SecurityTokenValidationException)
            {
                return null;
            }
            catch (ArgumentException)
            {
                return null;
            }
 
            // Validation passed. Return a valid AuthenticationTicket:
            return new AuthenticationTicket(principal, new AuthenticationProperties(), "Cookie");
        }
 
        // This ISecureDataFormat implementation is decode-only
        public string Protect(AuthenticationTicket data)
        {
            throw new NotImplementedException();
        }
 
        public string Protect(AuthenticationTicket data, string purpose)
        {
            throw new NotImplementedException();
        }
    }
}

 在startup.cs中调用

var tokenValidationParameters = new TokenValidationParameters
{
    // The signing key must match!
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = signingKey,
 
    // Validate the JWT Issuer (iss) claim
    ValidateIssuer = true,
    ValidIssuer = "ExampleIssuer",
 
    // Validate the JWT Audience (aud) claim
    ValidateAudience = true,
    ValidAudience = "ExampleAudience",
 
    // Validate the token expiry
    ValidateLifetime = true,
 
    // If you want to allow a certain amount of clock drift, set that here:
    ClockSkew = TimeSpan.Zero
};
 
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    AuthenticationScheme = "Cookie",
    CookieName = "access_token",
    TicketDataFormat = new CustomJwtDataFormat(
        SecurityAlgorithms.HmacSha256,
        tokenValidationParameters)
});

 如果请求中包含名为access_token的cookie验证为合法的JWT,这个请求就能返回正确的结果,如果需要,你可以加上额外的jwt chaims,或者复制jwt chaims到ClaimsPrincipal在CustomJwtDataFormat.Unprotect方法中,上面是验证token,下面将在asp.net core中生成token。

https://www.cnblogs.com/indexlang/p/indexlang.html

猜你喜欢

转载自wyf.iteye.com/blog/2422882