欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET Core 基于JWT的认证(二)

程序员文章站 2022-03-18 11:57:41
ASP.NET Core 基于 JWT 的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt 在 .Net Core 上的实际运用。 环境 .Net Core 2.2 Visual Studio 2017 ASP.NET C ......

asp.net core 基于jwt的认证(二)

上一节我们对 jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 jwt.net core 上的实际运用。

环境

  • .net core 2.2
  • visual studio 2017
  • asp.net core webapi2

在上一篇文章中,我们详细的介绍了jwt的知识,这一次,我们将进行一次实战的训练,这一块将会有三个部分组成。分别是:
1.如何使用微软官方提供的库实现jwt
2.如何自定义一个jwt认证类
3.使用非关系型数据库redisjwt信息的更新和替换
当然,我在后期的文章中也会讲解如何使用identityserver4去进行我们的权限控制。
在本文中,你将会学到如何使用微软官方提供的库进行jwt的签发、验证以及权限控制。我们使用的webapi作为演示程序。

配置信息的存储

通常来说,我们会把数据库等等一系列的配置放在我们的appsettings.json中,我们也尝试着将我们的jwt私钥等存在其中。

  "jwtsettings": {
    "issuer": "admin",
    "audience": "user",
    "secretkey": "ahfuawivb754huab21n5n1"
  }

当然你也可以把更多的配置放进去。
然后我们用依赖注入的方法,将配置文件注入到我们的类对象中。我们创建一个jwtsetting类,并且在服务中进行注入。
类对象

    public class jwtsettings
    {
        /// <summary>
        /// 证书颁发者
        /// </summary>
        public string issuer { get; set; }

        /// <summary>
        /// 允许使用的角色
        /// </summary>
        public string audience { get; set; }

        /// <summary>
        /// 加密字符串
        /// </summary>
        public string secretkey { get; set; }
    }

注入

services.configure<jwtsettings>(configuration.getsection("jwtsettings"));
            jwtsettings setting = new jwtsettings();
            configuration.bind("jwtsettings", setting);
            jwthelper.settings = setting;

想必这里的代码大家肯定是看的轻车熟路了,非常的简单。
接下来我们对jwt的签发制作一个jwthelper类。

jwt的签发

这一块,你可以上网去查看的一些介绍。

这里我简要的做一个介绍:
claim是什么呢,他就是一个用于描述一个具体的实体对象的一些描述性的字段。

claimsidentity就是用于指明claim中所存储的内容的合集,比如我们的身份证,年龄、性别、身份证号码等就组成了我们的身份证。

claimsprincipal我们称为“证件当事人”,也就是我们之前声明的东西的一个合计,类似,比如说你可能有驾照、身份证、医保卡等等,而所持有这些的人就叫做claimsprincipal

一些代码是一个普通的结构,大家可以按照这种模板进行修改模型,从而创建自己的jwt结构

代码:

    public class jwthelper
    {
        private static jwtsettings settings;
        public static jwtsettings settings { set { settings = value; } }
        public static string create_token(tokenpayload user)
        {
            //这里就是声明我们的claim
            var claims = new claim[] {
                        new claim(claimtypes.name, user.name),
                        new claim(claimtypes.role, user.role),
                        new claim(claimtypes.sid,user.sid.tostring())
                    };
            var key = new symmetricsecuritykey(encoding.utf8.getbytes(settings.secretkey));
            var creds = new signingcredentials(key, securityalgorithms.hmacsha256);

            var token = new jwtsecuritytoken(
                issuer: settings.issuer,
                audience: settings.audience,
                claims: claims,
                expires: datetime.now.adddays(1),
                signingcredentials: creds);
            var token = new jwtsecuritytokenhandler().writetoken(token);
            return token;
        }
    }

jwt认证

在这里,你可以使用我们下一节所遇到的自定义认证,不过我们还是先学着使用我们最为普通的官方方法。具体的操作非常简单,只需要在我们的容器service中注入一下就可以了。

            services.addauthentication(jwtbearerdefaults.authenticationscheme)
            .addjwtbearer(config =>
            {
                config.tokenvalidationparameters = new tokenvalidationparameters
                {
                    validateissuer = true,//是否验证issuer
                    validateaudience = true,//是否验证audience
                    validatelifetime = true,//是否验证失效时间
                    validateissuersigningkey = true,//是否验证securitykey
                    validaudience = setting.audience,//audience
                    validissuer = setting.issuer,//issuer,这两项和前面签发jwt的设置一致
                    issuersigningkey = new symmetricsecuritykey(encoding.utf8.getbytes(setting.secretkey))//拿到securitykey
                };
            });

这样,就完成了我们的jwt认证过程。
如果我们需要从token中取出我们的信息也非常的简单,利用依赖注入,使用
c# services.addtransient<igetinfofromtoken, getinfofromtoken>();
自己创建号这两个接口和类,对httpcontext进行截断,从httpcontext.user中就可以直接取出我们需要的payload。当然也可以使用中间件的方式,这里我们就不再用篇幅进行叙述了。

如果我的文章帮到了你,请帮忙点个赞,点个关注。谢谢!

我的掘金:warrenryan

我的简书:warrenryan

欢迎关注我的博客获得第一时间更新

我的github:steveneco

我的博客园:warrenryan