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
    一个web项目web.xml的配置中<context-param>配置作用
    JVM之几种垃圾收集器简单介绍
    JVM日志和参数的理解
    Java GC日志查看
    Java-性能调优-理解GC日志
    理解Java的GC日志
    tomcat打印GC日志
    快速解读GC日志
    Java 堆内存
  • 原文地址:https://www.cnblogs.com/Agui520/p/8400163.html
Copyright © 2011-2022 走看看