zoukankan      html  css  js  c++  java
  • 菜鸟入门【ASP.NET Core】12:JWT 设计解析及定制

    前言

    上一节我们讲述的书如何使用jwt token,而且上一节的token是要加Authorization:bearer XXXXXXXXXXXX才能访问。

    这一节我们来研究如何自定义类似jwt的token验证,也就是说直接从header中拿取我们想要的token

    自己定制JWT

    首先,继续在上一节的JwtAuthSample项目中的Startup.cs中的ConfigureServices方法中注释掉以下内容,然后自定义jwt token

    复制代码
            public void ConfigureServices(IServiceCollection services)
            {
                //将appsettings.json中的JwtSettings部分文件读取到JwtSettings中,这是给其他地方用的
                services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));
    
                //由于初始化的时候我们就需要用,所以使用Bind的方式读取配置
                //将配置绑定到JwtSettings实例中
                var jwtSettings=new JwtSettings();
                Configuration.Bind("JwtSettings",jwtSettings);
    
                services.AddAuthentication(options=>{
                    //认证middleware配置
                    options.DefaultAuthenticateScheme=JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme=JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(o=>{
                    // //主要是jwt  token参数设置
                    // o.TokenValidationParameters=new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
                    //     ValidIssuer =jwtSettings.Issuer,
                    //     ValidAudience =jwtSettings.Audience,
                    //     //这里的key要进行加密,需要引用Microsoft.IdentityModel.Tokens
                    //     IssuerSigningKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey))
                    // };
    
                    o.SecurityTokenValidators.Clear();//将SecurityTokenValidators清除掉,否则它会在里面拿验证
    
                    o.Events=new JwtBearerEvents{
                        //重写OnMessageReceived
                        OnMessageReceived=context=>{
                            var token=context.Request.Headers["mytoken"];
                            context.Token=token.FirstOrDefault();
                            return Task.CompletedTask;
                        }
                    };
                });
    
    
                services.AddMvc();
            }
    复制代码

    接下来我们新建MyTokenValidator.cs类来验证token,并让这个类实现ISecurityTokenValidator接口

    复制代码
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using System.Security.Claims;
    using Microsoft.IdentityModel.Tokens;
    
    namespace JwtAuthSample
    {
        public class MyTokenValidator : ISecurityTokenValidator
        {
            bool ISecurityTokenValidator.CanValidateToken =>true;
    
            int ISecurityTokenValidator.MaximumTokenSizeInBytes { get; set; }
    
            bool ISecurityTokenValidator.CanReadToken(string securityToken)
            {
                return true;
            }
    
            //验证token
            ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
            {
                validatedToken=null;
                //判断token是否正确
                if(securityToken!="abcdefg")
                return null;
    
                //给Identity赋值
                var identity=new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim("name","wyt"));
                identity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType,"admin"));
    
                var principle=new ClaimsPrincipal(identity);
                return principle;
            }
        }
    
    }
    复制代码

    然后我们在Startup.cs的ConfigureServices方法中将我们自定义的MyTokenValidator验证加进去

    o.SecurityTokenValidators.Add(new MyTokenValidator());

    这时候我们执行dotnet watch run运行项目,用postman不加header头或加错误的hearder头,发现无法访问

     

    我们用正确的自定义token进行访问

    Role以及Claims授权

    Role授权

    我们之前的授权方式都是添加  [Authorize]  标签但是由于我们在Claim中设置了Role

    所以我们可以将  [Authorize]  标签写成[Authorize(Roles="admin")]

    只有解析出来的token中的角色为admin才授权成功

     

     Claims授权

     要使用Claims授权,我们首先需要在Startup.cs的ConfigureServices方法中添加授权

                //添加Claim授权
                services.AddAuthorization(options=>{
                    options.AddPolicy("SuperAdminOnly",policy=>{policy.RequireClaim("SuperAdminOnly");});
                });

    然后在AuthorizeController.cs生成token的action中的Claim中添加SuperAdminOnly

    最后在需要权限认证的地方使用标签    [Authorize(Policy="SuperAdminOnly")]

    我们首先获取一下token,到jwt官网上解析一下发现token中包含SuperAdminOnly

    然后访问成功

  • 相关阅读:
    java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header.
    spring-session-data-redis依赖冲突问题
    centos7启动iptables时报Job for iptables.service failed because the control process exited with error cod
    图片上传后台服务报内存溢出 Out Of Memory Java heap space
    mysql 数据库密码忘记重置 进行远程连接
    打Jar包
    Type interface com.innovationV2.mapper.UserMapper is not known to the MapperRegistry
    关于java基础类型Integer String的clone()
    clion使用clang编译
    token & refresh token 机制总结
  • 原文地址:https://www.cnblogs.com/Agui520/p/8400163.html
Copyright © 2011-2022 走看看