JWT令牌授权认证,本文就不多说了,网上有大量的资料。本文只说说,JWT令牌如何在ASP.NET CORE中开启。


阅读本文之前,你也可以先参考以下资料:

  1. 什么是 JWT?
  2. ASP.Net Core 3.1 中使用JWT认证
  3. Authentication跟Authorization的区别
  4. JWT签名解析

JWT在asp.net core 2.2的版本框架就已经存在了,现在已经发展到.net 5了。本文主要针对.NET 5的版本进行阐述。

开启JWT主要需要包含以下几个步骤:

  1. 程序启动过程中,注册JWT中间件
  2. 生成Token,并返回给客户端
  3. 标记授权访问
  4. 携带Token进行访问服务器的API

具体通过代码来看看以下的几个步骤:

一、注册JWT中间件

打开Startup.cs文件,定位到方法ConfigureServices(IServiceCollection services),将JWT验证服务注册到服务集合。


        /// <summary>
        /// JWT Token构建所需要的参数
        /// </summary>
        public class JWTTokenParamter
        {
            public JWTTokenParamter()
            {
                ExpirationInterval = TimeSpan.FromMinutes(30);
            }

            /// <summary>
            /// Token加密用的私钥,该私钥不能泄露出去
            /// </summary>
            public string SecretKey { get; set; }

            /// <summary>
            /// Token密钥颁发者
            /// </summary>
            public string Issuer { get; set; }

            /// <summary>
            /// Token接收者
            /// </summary>
            public string Audience { get; set; }

            /// <summary>
            /// Token距离生效时间的过期时间间隔,默认30分钟
            /// </summary>
            public TimeSpan ExpirationInterval { get; set; }
        }

        //以下代码在 Startup.cs 类中

        //引入命名空间
        using Microsoft.AspNetCore.Authentication.JwtBearer;
        using Microsoft.IdentityModel.Tokens;

        //注入和配置中间件服务   
        public void ConfigureServices(IServiceCollection services)
        {
            //从配置文件 appsettings.json 中读取JWT相关的配置项
            var token = Configuration.GetSection("JWTTokenParamter").Get<JWTTokenParamter>();
            
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer = false,//是否验证Issuer
                    ValidateAudience = false,//是否验证Audience
                    ValidateLifetime = false,//是否验证失效时间
                    ClockSkew = TimeSpan.FromMinutes(30),
                    ValidateIssuerSigningKey = false,//是否验证SecurityKey
                    ValidAudience = token.Audience,//Audience
                    ValidIssuer = token.Issuer,//Issuer,这两项和前面签发jwt的设置一致
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(token.SecretKey))//拿到SecurityKey
                };
            });

            //省略其它代码
        }

        //配置中间件管道。注意,中间件管道是有顺序的,所以这边贴完整代码
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //app.UseHttpsRedirection();
            //开启令牌验证,注意和UseAuthorization区分
            app.UseAuthentication();
            app.UseRouting();
            app.UseCors();
            //开启身份授权,开启后Authorize特性才会生效,否则会报错。.net5已经把身份授权集成到框架了,net core 2.2不需要此项
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

appsettings.json中的token配置节点示例:

  "JWTTokenParamter": {
    "SecretKey": "123456123456123456",
    "Issuer": "a",
    "Audience": "a",
    "ExpirationInterval": "0.00:30:00"
  },

二、生成Token

生成Token的过程,请参考什么是 JWT?。此处就不赘述了,直接贴代码。

        /// <summary>
        /// 创建JWT令牌
        /// </summary>
        /// <param name="tokenParamter"></param>
        /// <param name="claims">自定义的TOKEN负载的信息</param>
        /// <returns></returns>
        public static string CreateJWTToken(JWTTokenParamter tokenParamter, Claim[] claims)
        {
            //声明一个对称密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenParamter.SecretKey));
            //以HmacSha256进行加密,生成签名凭证
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            
            var notBeforeTime = DateTime.Now;  //生效时间
            //生成JWT令牌Token
            var jwtToken = new JwtSecurityToken(tokenParamter.Issuer, tokenParamter.Audience, claims, notBeforeTime, notBeforeTime + tokenParamter.ExpirationInterval, credentials);
            //将Token转成Json
            return new JwtSecurityTokenHandler().WriteToken(jwtToken);
        }        

生成Token的过程,一般都是在登录的环节,用户身份验证通过后,生成Token返回给客户端。调用部分的代码,这里就不做演示了。

三、标记授权访问

到这里,我们的api调用还不会执行JWT身份验证,需要在控制器上标记需要启用授权认证。方法很简单,只需要在控制器上增加[Authorize]的特性标签即可。

    [ApiController]
    //在此处增加需要授权访问的特性标签
    [Authorize]
    [EnableCors]
    [Route("[controller]")]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            
            return "your code";
        }
    }

这里的 [Authorize] 不仅仅是可以给控制器上使用,也可以直接在方法上使用,执行效果一致的。如下所示:

    [ApiController]    
    [EnableCors]
    [Route("[controller]")]
    public class TestController : ControllerBase
    {
        //在此处增加需要授权访问的特性标签
        [Authorize]
        [HttpGet]
        public string Get()
        {
            
            return "your code";
        }
    }

所以开启授权验证,可以根据实际业务需要,很方便的开启和关闭。

四、携带Token进行访问服务器的API

最后我们要让我们能正常访问web api,我们需要在http的请求头部增加授权认证的token。因为我们使用的是Bearer的JWT认证,所以我们在附带头部信息的时候,需要以Bearer 开头(注意后面需要追加空格),如Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJuYmYiOjE2MDc1MDA3MzQsImV4cCI6MTYwNzUwMjUzNCwiaXNzIjoiYSIsImF1ZCI6ImEifQ.kD55oXqgRmsfW7o3V1QBjXOOuh7H1YLEdkSeykV_ozg

完整的Header添加Key为Authorization项,Value为Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJuYmYiOjE2MDc1MDA3MzQsImV4cCI6MTYwNzUwMjUzNCwiaXNzIjoiYSIsImF1ZCI6ImEifQ.kD55oXqgRmsfW7o3V1QBjXOOuh7H1YLEdkSeykV_ozg 即可。

我们以js的调用方法为例:

    await fetch("http://127.0.0.1:5000/login", {
        headers: {
          Authorization: "Bearer " + localStorage.getItem("token"),
        },
      })

这里的token是从本地存储中读取,登录成功后,我们需要将token存储起来,方便后续的接口调用携带。

我们测试的过程中,可以使用PostMan来进行测试,当我们给头部携带Token后,可以正常返回结果。

如果没有携带Token,则请求返回 401 Unauthorized

到这里,JWT基础的开启就完成了,大家还有什么疑问,欢迎在评论区留言。


本文会经常更新,请阅读原文: https://huchengv5.gitee.io//post/asp.net-core-%E5%A6%82%E4%BD%95%E5%BC%80%E5%90%AFJWT%E4%BB%A4%E7%89%8C.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名胡承(包含链接: https://huchengv5.gitee.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系