龙空技术网

ASP.NET Core利用Jwt技术实现对客户端的身份认证

迈信达科技 167

前言:

当前朋友们对“asp登录和验证代码”大约比较关切,你们都想要剖析一些“asp登录和验证代码”的相关资讯。那么小编在网摘上网罗了一些对于“asp登录和验证代码””的相关内容,希望咱们能喜欢,同学们快快来了解一下吧!

背景

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

项目演练/举例:

1、有一个“用户中心”独立子系统名为“Miidy.UserHub”,是一个基于ASP.NET Core MVC的项目。

2、有一个处理用户订单的独立子系统名为“Miidy.UserOrder”,是一个基于ASP.NET Core Web Api 的项目。

3、同时还有一个处理用户文件上传的独立子系统名为“Miidy.UserUpload”,是一个基于ASP.NET Core Web Api的项目。

业务关系如下:

用户成功登录后进入“Miidy.UserHub”,在用户查看订单时通过前端Ajax调用“Miidy.UserOrder”的Web Api接口,在用户上传图片是通过前端Ajax调用“Miidy.UserUpload”的web api接口。

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

1、如何保障“Miidy.UserOrder”与“Miidy.UserUpload”两个独立系统内的Web Api接口安全,因为它们已经被暴露在了前端。

2、如何在“Miidy.UserHub”站颁发Token。

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

Jwt 全名为:JSON Web Token,是一个很成熟的技术,网络上也有很多这方面的知识,我这里就不再重述了。

实现原理

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

实现代码

Miidy.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      });            }

Miidy.UserHub前端Ajax跨站请求代码:

//封装一个Ajax请求公共方法function GetWebDataByObject(url, requestMethon, paramter) {    jQuery.support.cors = true;    apiUrl = ';;    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;}

“Miidy.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();}

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

[Route("api/[Controller]")]//添加过滤器后,该控制器内所有Action都将进行Token验证[Authorize]public class OrderController : Controller{     }

至此,基于ASP.NET Core的Jwt跨站验证Token方案就全部完成了,是不是很简单呀^_^ ^_^ !! 

总结

1、Token颁发者与验证者都必须使用相同的私钥,私钥、发行者、接受者等参数可以放在配置文件中动态配置!

2、在项目Startup类中的ConfigureServices方法内添加注册使用Jwt身份验证的功能。

3、在验证者项目的控制器上或方法上加上过滤器 [Authorize]即可开启身份验证。

标签: #asp登录和验证代码 #jwtajax请求 #jquery公用验证