002-.net core6 Jwt授权-颁发Token

1. 添加程序包 

  System.IdentityModel.Tokens.Jwt 

  Microsoft.AspNetCore.Authentication.JwtBearer

 2.添加类文件 JwtHelp

public class JwtHelp
{
    //发起人:当前项目
    private static string issuer = "TZ.Web";
    //订阅:我们需要谁去使用这个Token
    private static string audience = "TZ.Web";
    private static string secretKey = "GQDsdcKsx0NHjPOmXOYg5MbeJ1XT0uFiyDVvVBrk";
    //jwt登录过期时间(天)
    private static int expire = 3;

    /// <summary>
    /// 生成token
    /// </summary>
    /// <returns></returns>
    public static string GenerateJwtToken()
    {
        var authTime = DateTime.Now;
        var expiresAt = authTime.AddSeconds(expire);
        var claims = new List<Claim>()
        {
            new Claim("UserId", "0001"),
            new Claim("UserName", "admin"),
            new Claim("Permissions", JsonConvert.SerializeObject(new List<string> { "*:*:*", "system:user:list" }))
        };
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(secretKey);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Issuer = issuer,
            Audience = audience,
            IssuedAt = authTime,//token生成时间
            Expires = expiresAt,//token过期时间
            TokenType = "Bearer",
            //对称秘钥,签名证书
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }

    /// <summary>
    /// 验证Token
    /// </summary>
    /// <returns></returns>
    public static TokenValidationParameters ValidParameters()
    {
        return new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidIssuer = issuer,
            ValidAudience = audience,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)),
            ValidateLifetime = true,//是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
            ClockSkew = TimeSpan.FromSeconds(30),
            RequireExpirationTime = true,//过期时间
        };
    }


    /// /// <summary>
    /// 从令牌中获取数据声明
    /// </summary>
    /// <param name="token">令牌</param>
    /// <returns></returns>
    public static IEnumerable<Claim> ParseToken(string token)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var validateParameter = ValidParameters();
        token = token.Replace("Bearer ", "");
        try
        {
            tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken);
            var jwtToken = tokenHandler.ReadJwtToken(token);
            return jwtToken.Claims;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return null;
        }
    }

    /// <summary>
    /// jwt token校验
    /// </summary>
    /// <param name="jwtToken"></param>
    /// <returns></returns>
    public static string? ValidateJwtToken(IEnumerable<Claim> jwtToken)
    {
        try
        {
            var UserId = jwtToken.FirstOrDefault(x => x.Type == "UserId")?.Value;
            var UserName = jwtToken.FirstOrDefault(x => x.Type == "UserName")?.Value;
            return UserId;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return null;
        }
    }
}

2.添加类文件 VerifyTokenAttribute

/// <summary>
/// 授权校验访问
/// 如果跳过授权登录在Action 或controller加上 AllowAnonymousAttribute
/// </summary>
public class VerifyTokenAttribute : Attribute, IAuthorizationFilter
{
    /// <summary>
    /// 只判断token是否正确,不判断权限
    /// 如果需要判断权限的在Action上加上ApiActionPermission属性标识权限类别,ActionPermissionFilter作权限处理
    /// </summary>
    /// <param name="context"></param>
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var noNeedCheck = false;
        if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
        {
            noNeedCheck = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                .Any(a => a.GetType().Equals(typeof(AllowAnonymousAttribute)));
        }
        if (noNeedCheck) return;
        string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
        string url = context.HttpContext.Request.Path;
        var token = context.HttpContext.GetToken();
        if(token == null)
        {
            string msg = $"请传入有效的Token";
            context.Result = new JsonResult(new ApiResult { Msg = EnumApiResult.ERROR, Content = msg });
            return;
        }
        if (JwtHelp.ParseToken(context.HttpContext.GetToken()) == null)
        {
            string msg = $"请传入有效的Token";
            context.Result = new JsonResult(new ApiResult { Msg = EnumApiResult.ERROR, Content = msg });
        }
    }
}

3. 在Program.cs添加注册

{
    //jwt 认证
    builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddCookie()
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = JwtHelp.ValidParameters();
    });
}

{
    app.UseAuthentication();
    app.UseAuthorization();
}

4. 调用获取token 和 校验token

[VerifyToken]
public class SysLoginController : BaseController
{
    [AllowAnonymous]
    [HttpPost]
    public IActionResult Login()
    {
        return SUCCESS(JwtHelp.GenerateJwtToken());
    }

    [HttpPost]
    public IActionResult Test1()
    {
        return SUCCESS(666);
    }
}

 

posted @ 2022-06-21 22:10  红中0920  阅读(346)  评论(0)    收藏  举报