首页 > 其他分享 >.Net Core之JWT授权

.Net Core之JWT授权

时间:2023-11-07 09:11:22浏览次数:40  
标签:Core 令牌 JWT JWTAuthorization new Net configuration public

一、什么是JWT

文章参考:https://www.leo96.com/article/detail/55

JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义 了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为JSON对象。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对JWT进行签名。

二、使用场景

1、授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。

2、信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

三、JWT授权流程

 

四、JWT令牌结构

1、header(头部)头部是令牌的第一部分,通常由两部分组成:令牌的类型(即JWT)和令牌所使用的签名算法,如SHA256、HMAC等

2、payload(有效载荷)头部是令牌的第一部分,通常由两部分组成:令牌的类型(即JWT)和令牌所使用的签名算法,如SHA256、HMAC等

有三种说明类型,预定义声明、公共声明和私有声明。声明名称仅是三个字符,因为JWT是紧凑的

  • 预定义声明:包括iss(发出者), exp(到期时间), sub(主题), aud(受众)等,是推荐的但是不是强制的可以没有。
  • 公共声明:公共声明,这个部分可以随便定义,但是要注意和 IANA JSON Web Token 冲突。
  • 私有声明:这个部分是共享被认定信息中自定义部分。

3、signature(签名)  签名是令牌的第三部分,由header和payload进行64位编码后再使用加密算法加密即可

五、代码撸起来

楼主用vs2022新建了两个解决方案,分别是Application.Authorization(用来生成token),Application.WebAPI(用来token授权)

 

 

 

一、生成token 

复制代码
[ApiController]
    [Route("[controller]")]
    public class AuthorizationController : ControllerBase
    {
        public IConfiguration _configuration { get; }
        public AuthorizationController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetToken")]
        public dynamic GetToken(string userName= "xiaohemaio", string pwd= "123456")
        {
            // 验证用户和密码应该去查询数据库,此处省略
            if(userName.Equals("xiaohemaio") && pwd.Equals("123456"))
            {
                //  有效载荷,这里可以自定义写,尽量避免敏感信息

                Claim[] claims = new Claim[] { 
                new Claim("NickName",userName),
                new Claim("Role","Admin")
                };
                // 需要加密,需要加密key
                // NuGet引入:Microsoft.IdentityModel.Tokens
                SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWTAuthorization:securitykey"]));

                SigningCredentials creds = new SigningCredentials(key,SecurityAlgorithms.HmacSha256);

                // NuGet引入:Microsoft.IdentityModel.Tokens.Jwt
                // 官方规定了7个非强制但建议使用的字段:
                // iss(issuer):签发人
                // exp(expiration time) :过期时间
                // sub(subject):主题
                // aud(audience):受众
                // nbf(not befaore):生效时间
                // lat(issued at):签发时间
                // jti(jwt id):编号

                JwtSecurityToken token = new JwtSecurityToken(
                issuer:_configuration["JWTAuthorization:issuer"],
                audience: _configuration["JWTAuthorization:audience"],
                claims: claims,
                expires:System.DateTime.Now.AddMinutes(5),
                signingCredentials: creds
                );

                string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
                return Ok(new { Data= returnToken ,Success=true,Msg="Token生成成功"});
            }
            return Ok(new { Data = string.Empty, Success = false, Msg = "Token生成失败" });
        }
    }
复制代码

 

复制代码
  "JWTAuthorization": {
    "issuer": "xiaohemaio", // 签发人,可自定义
    "audience": "xiaohemiao", // 受众,可自定义
    "securitykey": "8cbe2b73be20b183bd787f31d4dc3f0d05bb2640495ebf8f52e790907d20f70a" // 加密key,根据需要自己生成 参考地址 https://crypot.51strive.com/sha256.html

  }
复制代码

 

 

 

 

 

 二、Token授权

复制代码
[ApiController]
    [Route("[controller]")]
    public class AuthorizationController : ControllerBase
    {

        [HttpGet]
        [Route("Get")]
        public dynamic Get()
        {
            return Ok(new { Data = "test", Sueccess = true });
        }

        [HttpGet]
        [Route("GetAuthorizationData")]
        [Authorize]
        public dynamic GetAuthorizationData()
        {
            // 获取当前登录的用户名
            var userName = HttpContext.AuthenticateAsync().Result.Principal.Claims.FirstOrDefault(x => x.Type.Equals("NickName"))?.Value;

            return new JsonResult(new { Data = userName, Sueccess = true });
        }

       
    }
复制代码 复制代码
public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            {
                // ************************2、JWT鉴权授权******************************************
                // NuGet引入程序包:Microsoft.AspNetCore.Authentication.JwtBearer (如果是.net5则使用5.0及以上的版本,如是.net6 则使用6.0及以上版本,如是.net core 3.1 则使用3.0及以上版本)
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options => {
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidateAudience = true,
                            ValidateLifetime = true,
                            ValidateIssuerSigningKey= true,
                            ValidIssuer= Configuration["JWTAuthorization:issuer"], // Issuer 这个和应用Application.Authorization里面的设置一样,表示谁签发的Token
                            ValidAudience = Configuration["JWTAuthorization:audience"], // Audience 这个和应用Application.Authorization里面的设置一样,表示受众的Token
                            IssuerSigningKey =new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWTAuthorization:securitykey"])), // 拿到securitykey 
                            AudienceValidator = (m,n,z) => {  // 自定义规则
                                return true;
                            }
                        };
                    });
            }


        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            // ********************1、启用鉴权*********************
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
复制代码 复制代码
  "JWTAuthorization": {
    "issuer": "xiaohemaio", // 签发人,可自定义
    "audience": "xiaohemiao", // 受众,可自定义
    "securitykey": "8cbe2b73be20b183bd787f31d4dc3f0d05bb2640495ebf8f52e790907d20f70a" // 加密key,根据需要自己生成 参考地址 https://crypot.51strive.com/sha256.html

  }
复制代码

 

 

 

 

学习链接 :https://www.cnblogs.com/wei325/p/16316004.html

 

  来自:https://www.cnblogs.com/sportsky/p/15943695.html

标签:Core,令牌,JWT,JWTAuthorization,new,Net,configuration,public
From: https://www.cnblogs.com/djd66/p/17814272.html

相关文章

  • .NET(C#) Linq Concat和Union以及Select和SelectMany的使用及区别
    1、Concat操作符Concat操作符用于连接两个序列,生成一个新序列。usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceConsoleApplication{classProgram{staticvoidMain(s......
  • .NET C# 9.0 record和with的定义及使用
    C#9引入record,它一种可以创建的新引用类型,而不是类或结构。C#10添加了recordstructs,以便可以将记录定义为值类型。记录与类不同,区别在于record类型使用基于值的相等性。两个记录类型的变量在它们的类型和值都相同时,它们是相等的。with表达式在C#9.0及更高版本中可用,......
  • .NET(C#) LinkedList、Queue<T>和Stack<T>的使用
    本文主要介绍.NET(C#)中,LinkedList链表、Queue<T>队列和Stack<T>堆栈的使用,以及相关的示例代码。1、LinkedList(链表)链表中元素存储内存中是不连续分配,每个元素都有记录前后节点,节点值可以重复,不能通过下标访问,泛型的使用保证类型安全,可以避免装箱拆箱,找元素就只能遍历,查找不方......
  • .NET(C#) Linq GroupBy和GroupJoin的使用
    Linq是LanguageIntegratedQuery的简称,它是微软在.NETFramework3.5里面新加入的特性,用以简化查询查询操作。本文主要介绍.NET(C#)中Linq的GroupBy和GroupJoin操作符1、GroupBy操作符GroupBy操作符类似于SQL语言仲的GruopBy语句,这里的GroupBy操作符用于将输入序列中的元素进......
  • .NET(C#) Cast和OfType的使用
    Linq是LanguageIntegratedQuery的简称,它是微软在.NETFramework3.5里面新加入的特性,用以简化查询查询操作。本文主要介绍.NET(C#)中Linq的Cast和OfType操作符。1、Cast操作符Cast操作符用于将一个类型为IEnumerable的集合对象转换为IEnumerable<T>类型的集合对象。也就是非......
  • .NET(C#) Linq Range和Repeat的使用
    Linq是LanguageIntegratedQuery的简称,它是微软在.NETFramework3.5里面新加入的特性,用以简化查询查询操作。本文主要介绍.NET(C#)中Linq的Range和Repeat操作符。1、Range操作符Range操作符用于辅助生成一个整数序列。usingSystem;usingSystem.Collections.Generic;usi......
  • .NET(C#) 对象的拷贝(浅拷贝和深拷贝)
    本文主要介绍.NET(C#),对象的拷贝,包括浅拷贝和深拷贝,以及浅拷贝和深拷贝的实现方式,不同的实现方式之间的性能对比。1、浅拷贝和深拷贝浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值......
  • NET(C#) Linq Take和TakeWhile的使用
    Linq是LanguageIntegratedQuery的简称,它是微软在.NETFramework3.5里面新加入的特性,用以简化查询查询操作。本文主要介绍.NET(C#)中Linq的Take和TakeWhile操作符。1、Take操作符Take操作符用于从输入序列中返回指定数量的元素,常用于分页。usingSystem;usingSystem.Coll......
  • 在ASP.NET MVC框架中,如何处理多个提交按钮?
    内容来自DOChttps://q.houxu6.top/?s=在ASP.NETMVC框架中,如何处理多个提交按钮?在ASP.NETFrameworkBeta中,有几种方法可以处理同一表单中的多个提交按钮。一种方法是使用一个隐藏字段来区分不同的提交按钮。例如:<%Html.BeginForm("MyAction","MyController",FormMethod......
  • EF Core 关系配置
    一、一对多publicclassArticle{publiclongId{get;set;}//主键publicstringTitle{get;set;}//标题publicstringContent{get;set;}//内容publicList<Comment>Comments{get;set;}=newList<Comment>();//此文章的若干条评论}......