当前位置: 移动技术网 > IT编程>开发语言>.net > ASP.NET Core 2.0利用Jwt实现授权认证

ASP.NET Core 2.0利用Jwt实现授权认证

2018年08月28日  | 移动技术网IT编程  | 我要评论

爱特运维,峰峰二手车,关于友谊的文章

背景

在微服务架构下,一般都会按不同的业务或功能将整个系统切分成不同的独立子系统,再通过rest api或rpc进行通讯并相互调用,形成各个子系统之间的串联结构。在这里,我们将采用rest api的通讯方式。

比如:

1、有一个“用户中心”独立子系统名为“lezhima.userhub”,是一个基于asp.net core mvc 2.0的项目。

2、有一个处理用户订单的独立子系统名为“lezhima.userorder”,是一个基于asp.net core webp api 2.0的项目。

3、同时还有一个处理用户文件上传的独立子系统名为“lezhima.userupload”,是一个基于asp.net core webp api 2.0的项目。

业务关系如下:

用户成功登录后进入“lezhima.userhub”,在用户查看订单时通过前端ajax调用“lezhima.userorder”的web api接口,在用户上传图片是通过前端ajax调用“lezhima.userupload”的web api接口。

至此,我们了解了上面的业务关系后,心里一定产生出如下两个问题:

1、如何保障“lezhima.userorder”与“lezhima.userupload”两个独立系统内的web api接口安全,因为它们已经被暴露在了前端。

2、如何在“lezhima.userhub”站颁发token。

那么,带着问题我们下面就结合asp.net core 自带的jwt技术来讨论具体的实现(也许聪明的你有更好的解决方法,请一定告知我,谢谢)。

jwt 全名为:json web token,是一个很成熟的技术,园子里也有很多这方面的知识,我这里就不再重述了。

 

 实现原理

“lezhima.userhub”站因为已经做了登录验证,我们暂且认为它是可信的,所以在前端ajax请求“lezhima.userorder”站的web api接口时先到自已后端去生成一个token,并随之同本次跨站请求一块携带至“lezhima.userorder”站,“lezhima.userorder”站验证请求头中的token是否合法,如合法则继续路由到具体方法中,否则结束请求。“lezhima.userupload”站原理与“lezhima.userorder”相同。

 

实现代码

lezhima.userhub颁发token代码:

        /// <summary>
        /// 颁发一个指定有效期的token,并将当前登录的用户id传递进来		
        /// </summary>
        /// <param name="currentuserid"></param>
        /// <param name="expiresminutes"></param>
        /// <returns></returns>
	  public static async task<string> getaccesstoken(string currentuserid,int expiresminutes=2)
        {
            return await task.run(() =>
            {
				//约定私钥,下面三个参数可放到配置文件中				
                var secret = "nguznmnlnzqtzthkzc00yjrh";
				//发行者
                var iss = "andre";
				//接受者
                var aud = "andre";

                if (string.isnullorempty(secret) || string.isnullorempty(iss) || string.isnullorempty(aud))
                    return "";

                if (string.isnullorempty(currentuserid))
                    currentuserid = guid.newguid().tostring();

                var now = datetime.utcnow;
                var claims = new claim[]
                {
                    new claim(jwtregisteredclaimnames.sub, currentuserid),
                    new claim(jwtregisteredclaimnames.iat, now.touniversaltime().tostring(), claimvaluetypes.integer64)
                };
                var signingkey = new symmetricsecuritykey(encoding.ascii.getbytes(secret));
                var jwt = new jwtsecuritytoken(
                       issuer: iss,
                       audience: aud,
                       claims: claims,
                       notbefore: now,
                       expires: now.add(timespan.fromminutes(expiresminutes)),
                       signingcredentials: new signingcredentials(signingkey, securityalgorithms.hmacsha256)
                 );
                return new jwtsecuritytokenhandler().writetoken(jwt);  //生成一个新的token
            });           
        }

lezhima.userhub前端ajax跨站请求代码:

//封装一个ajax请求公共方法
function getwebdatabyobject(url, requestmethon, paramter) {
    jquery.support.cors = true;
    apiurl = 'http://127.0.0.1:8012/';
    var token = gettoken(); //调用本站内的token颁发web api接口 
    var result = [];
    $.ajax({
        type: requestmethon,
        url: apiurl + url,
        data: paramter,
        async: false,
        beforesend: function (xhr) {
			//将token携带到请求头中
            xhr.setrequestheader("authorization", "bearer " + token);
        },  
        success: function (data) {
            result = data;
        },
        error: function (xmlhttprequest, textstatus, errorthrown) {
            // 状态码
            console.log(xmlhttprequest.status);
            // 状态
            console.log(xmlhttprequest.readystate);
            // 错误信息   
            console.log(textstatus);
        }
    });
    return result;
}

“lezhima.userorder”站开启jwt的token验证,在startup.cs里添加如下代码:

        public iserviceprovider configureservices(iservicecollection services)
        {            
            services.addcors();
			
			//从配置文件中获取私钥、发行者、接受者三个参数
			//三个参数的值必需与颁发token站相同
            var audienceconfig = configuration.getsection("audience");

            var signingkey = new symmetricsecuritykey(encoding.ascii.getbytes(audienceconfig["secret"]));
            var tokenvalidationparameters = new tokenvalidationparameters
            {
                validateissuersigningkey = true,
                issuersigningkey = signingkey,
                validateissuer = true,
                validissuer = audienceconfig["iss"],
                validateaudience = true,
                validaudience = audienceconfig["aud"],
                validatelifetime = true,
                clockskew = timespan.zero,
                requireexpirationtime = true,
            };
			//注入jwt验证
            services.addauthentication(jwtbearerdefaults.authenticationscheme)
                .addjwtbearer(options => {
                    options.requirehttpsmetadata = false;
                    options.tokenvalidationparameters = tokenvalidationparameters;
                });

            services.addmvc();


            var builder = new containerbuilder();
            builder.registermodule(new evolution());
            builder.populate(services);
            var container = builder.build();
            return container.resolve<iserviceprovider>();
        }
        public void configure(iapplicationbuilder app, ihostingenvironment env)
        {
            if (env.isdevelopment())
            {
                app.usedeveloperexceptionpage();
            }
            app.usecors(builder =>
              builder.withorigins("*")
              .allowanyheader()
              .allowanymethod()
              .allowcredentials()
            );         
            //开启验证
            app.useauthentication();
            app.usemvc();
        }

“lezhima.userorder”站内的控制器里添加验证过滤器[authorize],如下代码:

    [route("api/[controller]")]
    //添加过滤器后,该控制器内所有action都将进行token验证
    [authorize]
    public class ordercontroller : controller
    {
        
    }

  

至此,基于asp.net core的jwt跨站验证token方案就全部完成了,是不是很简单呀^_^  ^_^  

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网