Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 593|回复: 0

关于ASP.Net Core Web及API身份认证的解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-18 10:05:36 | 显示全部楼层 |阅读模式

    https://www.cnblogs.com/ibeisha/p/jwt-webapi.html

     

    .NetCore自发布以来,颇受关注,现在.Net Core2.0已经正式发布,边迫不及待的将.Net跨平台移植的工作进行到底。想来,也费不了多少事儿。我经常和同事们说,要敢于尝试新鲜事物,不阴损守旧,方能使自己不断进步,站在队伍的前列。下面就关于Asp.Net Core在Web 及API项目上身份认证的问题做下简单的阐述。

    一、Asp.Net Core Web项目的登录认证

        在MVC Web项目中,做用户登录授权,是必不可少的工作,不知道大家平时是怎么做的,我想,大多朋友还是使用微软提供的一套认证机制,可以省去很多功夫。从WebForm时代的Form身份认证,无非是通过客户端Cookie中存储认证票据,在请求受保护的资源时,通过Cookie中携带的身份票据,再有Asp.net的认证模块,完整对请求者的身份认证。这一过程,是很清晰简单的了。在MVC中,大多是通过中间件(MiddleWare)来完整认证授权过程。在ASP.NETMVC中,我们了解到基于声明的授权认证(Claim),这种认证方式,好处在于,我们想在用户授权时,存储多个属性信息,只需要添加多个声明即可,我们在微软的认证中间件中,看到的都是定义好的常量,当然,我们可以定义自己的ClaimTypes。然我们看看微软在.NetCore中定义的一些声明吧:

        // Summary:
            //     http://schemas.xmlsoap.org/ws/2009/09/identity/claims/actor.
            public  const  string  Actor =  "http://schemas.xmlsoap.org/ws/2009/09/identity/claims/actor" ;
            //
            // Summary:
            //     The URI for a claim that specifies the postal code of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode.
            public  const  string  PostalCode =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode" ;
            //
            // Summary:
            //     The URI for a claim that specifies the primary group SID of an entity, http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid.
            public  const  string  PrimaryGroupSid =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid" ;
            //
            // Summary:
            //     The URI for a claim that specifies the primary SID of an entity, http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid.
            public  const  string  PrimarySid =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid" ;
            //
            // Summary:
            //     The URI for a claim that specifies the role of an entity, http://schemas.microsoft.com/ws/2008/06/identity/claims/role.
            public  const  string  Role =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" ;
            //
            // Summary:
            //     The URI for a claim that specifies an RSA key, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa.
            public  const  string  Rsa =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa" ;
            //
            // Summary:
            //     The URI for a claim that specifies a serial number, http://schemas.microsoft.com/ws/2008/06/identity/claims/serialnumber.
            public  const  string  SerialNumber =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/serialnumber" ;
            //
            // Summary:
            //     The URI for a claim that specifies a security identifier (SID), http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid.
            public  const  string  Sid =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid" ;
            //
            // Summary:
            //     The URI for a claim that specifies a service principal name (SPN) claim, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/spn.
            public  const  string  Spn =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/spn" ;
            //
            // Summary:
            //     The URI for a claim that specifies the state or province in which an entity resides,
            //     http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince.
            public  const  string  StateOrProvince =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince" ;
            //
            // Summary:
            //     The URI for a claim that specifies the street address of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress.
            public  const  string  StreetAddress =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress" ;
            //
            // Summary:
            //     The URI for a claim that specifies the surname of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname.
            public  const  string  Surname =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" ;
            //
            // Summary:
            //     The URI for a claim that identifies the system entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system.
            public  const  string  System =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system" ;
            //
            // Summary:
            //     The URI for a claim that specifies a thumbprint, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint.
            //     A thumbprint is a globally unique SHA-1 hash of an X.509 certificate.
            public  const  string  Thumbprint =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint" ;
            //
            // Summary:
            //     The URI for a claim that specifies a user principal name (UPN), http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn.
            public  const  string  Upn =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" ;
            //
            // Summary:
            //     The URI for a claim that specifies a URI, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/uri.
            public  const  string  Uri =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/uri" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata.
            public  const  string  UserData =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/version.
            public  const  string  Version =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/version" ;
            //
            // Summary:
            //     The URI for a claim that specifies the webpage of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage.
            public  const  string  Webpage =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage" ;
            //
            // Summary:
            //     The URI for a claim that specifies the Windows domain account name of an entity,
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname.
            public  const  string  WindowsAccountName =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdeviceclaim.
            public  const  string  WindowsDeviceClaim =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdeviceclaim" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdevicegroup.
            public  const  string  WindowsDeviceGroup =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdevicegroup" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsfqbnversion.
            public  const  string  WindowsFqbnVersion =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsfqbnversion" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/windowssubauthority.
            public  const  string  WindowsSubAuthority =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowssubauthority" ;
            //
            // Summary:
            //     The URI for a claim that specifies the alternative phone number of an entity,
            //     http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone.
            public  const  string  OtherPhone =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone" ;
            //
            // Summary:
            //     The URI for a claim that specifies the name of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier.
            public  const  string  NameIdentifier =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" ;
            //
            // Summary:
            //     The URI for a claim that specifies the name of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name.
            public  const  string  Name =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" ;
            //
            // Summary:
            //     The URI for a claim that specifies the mobile phone number of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone.
            public  const  string  MobilePhone =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone" ;
            //
            // Summary:
            //     The URI for a claim that specifies the anonymous user; http://schemas.xmlsoap.org/ws/2005/05/identity/claims/anonymous.
            public  const  string  Anonymous =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/anonymous" ;
            //
            // Summary:
            //     The URI for a claim that specifies details about whether an identity is authenticated,
            //     http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authenticated.
            public  const  string  Authentication =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authentication" ;
            //
            // Summary:
            //     The URI for a claim that specifies the instant at which an entity was authenticated;
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant.
            public  const  string  AuthenticationInstant =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant" ;
            //
            // Summary:
            //     The URI for a claim that specifies the method with which an entity was authenticated;
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod.
            public  const  string  AuthenticationMethod =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod" ;
            //
            // Summary:
            //     The URI for a claim that specifies an authorization decision on an entity; http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authorizationdecision.
            public  const  string  AuthorizationDecision =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authorizationdecision" ;
            //
            // Summary:
            //     The URI for a claim that specifies the cookie path; http://schemas.microsoft.com/ws/2008/06/identity/claims/cookiepath.
            public  const  string  CookiePath =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/cookiepath" ;
            //
            // Summary:
            //     The URI for a claim that specifies the country/region in which an entity resides,
            //     http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country.
            public  const  string  Country =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country" ;
            //
            // Summary:
            //     The URI for a claim that specifies the date of birth of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth.
            public  const  string  DateOfBirth =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth" ;
            //
            // Summary:
            //     The URI for a claim that specifies the deny-only primary group SID on an entity;
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid.
            //     A deny-only SID denies the specified entity to a securable object.
            public  const  string  DenyOnlyPrimaryGroupSid =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid" ;
            //
            // Summary:
            //     The URI for a claim that specifies the deny-only primary SID on an entity; http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid.
            //     A deny-only SID denies the specified entity to a securable object.
            public  const  string  DenyOnlyPrimarySid =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid" ;
            //
            // Summary:
            //     The URI for a claim that specifies a deny-only security identifier (SID) for
            //     an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid.
            //     A deny-only SID denies the specified entity to a securable object.
            public  const  string  DenyOnlySid =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsuserclaim.
            public  const  string  WindowsUserClaim =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsuserclaim" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlywindowsdevicegroup.
            public  const  string  DenyOnlyWindowsDeviceGroup =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlywindowsdevicegroup" ;
            //
            // Summary:
            //     http://schemas.microsoft.com/ws/2008/06/identity/claims/dsa.
            public  const  string  Dsa =  "http://schemas.microsoft.com/ws/2008/06/identity/claims/dsa" ;
            //
            // Summary:
            //     The URI for a claim that specifies the email address of an entity, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email.
            public  const  string  Email =  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" ;

    那么我们在Asp.Net Core项目中的认证,也是比较简单的。也是通过HttpContext的扩展方法SignInAsync,来传入声明的身份信息。要使用的微软的认证组件,我们在.Net Core Web项目中,做如下改动:

    首先,在Start.cs类中,添加服务,具体代码如下:

     
    /// <summary>
    ///
    /// </summary>
    /// <param name="services"></param>
    public  void  ConfigureServices(IServiceCollection services)
    {
         services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
         .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =>
         {
             o.Cookie.Name =  "_AdminTicketCookie" ;
             o.LoginPath =  new  PathString( "/Account/Login" );
             o.LogoutPath =  new  PathString( "/Account/Login" );
             o.AccessDeniedPath =  new  PathString( "/Error/Forbidden" );
         });
         services.AddTransient<TiKu.Application.Interfaces.IAdminService, TiKu.Application.AdminService>();
         services.AddMvc();
    }

        其次,添加认证中间件

    /// <summary>
    /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    /// </summary>
    /// <param name="app"></param>
    /// <param name="env"></param>
    public  void  Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
     
         if  (env.IsDevelopment())
         {
             app.UseDeveloperExceptionPage();
         }
         else
         {
             app.UseExceptionHandler( "/Home/Error" );
         }
         app.UseStaticFiles();
         app.UseAuthentication(); //添加认证中间件
         app.UseMvc(routes =>
         {
             routes.MapRoute(
                 name:  "default" ,
                 template:  "{controller=Home}/{action=Index}/{id?}" );
         });
         
    }

      最后,在用户登录的地方,登录成功后,调用HttpContext的SignIn方法,将授权信息写入Cookie,示例代码如下:

     
    /// <summary>
    /// <![CDATA[登陆]]>
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    [HttpPost]
    [ValidateAntiForgeryToken]
    public  async Task<ActionResult> Login(Models.LoginViewModel model)
    {
         try
         {
             //模型验证通过后
             if  (ModelState.IsValid)
             {
                 model.password = TiKu.Common.Security.MD5.Md5(model.password); //MD5加密
                 TiKu.Domain.Entity.tb_Admin admin = await _AdminService.CheckAccountAndPassword(account: model.account, password: model.password);
                 //验证用户名密码
                 if  (admin !=  null )
                 {
                     var  identity =  new  ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); //一定要声明AuthenticationScheme
                     identity.AddClaim( new  Claim(ClaimTypes.Name, admin.Account));
                     identity.AddClaim( new  Claim(ClaimTypes.NameIdentifier, admin.Id.ToString()));
     
                     await HttpContext.SignInAsync(identity.AuthenticationType,
                                                   new  ClaimsPrincipal(identity),
                                                   new  AuthenticationProperties
                                                   {
                                                       IsPersistent = model.isPersistent,
                                                       RedirectUri =  "/Home/Index" ,
                                                       ExpiresUtc =  new  System.DateTimeOffset(dateTime: DateTime.Now.AddHours(6)),
                                                   });
                     //更新登陆时间
                     await _AdminService.UpdateLastLoginTime(id: admin.Id);
                 }
                 else
                 {
                     await HttpContext.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                     ModelState.AddModelError( "" "用户名或密码错误!" );
                 }
             }
         }
         catch  (Exception ex)
         {
             ModelState.AddModelError( "" "用户名或密码错误!" );
             _Logger.Error( "用户登录时发生错误!" , ex);
         }
         return  View(model);
    }

      这样就完成了Asp.net core web项目的登录认证工作。

    二、Asp.Net Core WebApi基于JWT的认证授权

          关于JWT的工作原理,大家可以自行了解(https://jwt.io/)。JWT实现了服务端无状态,在分布式服务,会话一致性,单点登录等方面,凸显优势,不占用服务端资源。使用JWT需要注意的是,令牌过期后刷新,以及更改密码后令牌未过期的处理问题。

    这里,我以JWT作为.net core webapi项目的认证方式。

    首先,我再Api项目中新建了一个名为OAuthController的控制器,定义一个Action名为Token的方法,用来让客户端获取令牌之用,具体代码如下:

    /// <summary>
    /// <![CDATA[获取访问令牌]]>
    /// </summary>
    /// <param name="user"></param>
    /// <param name="password"></param>
    /// <returns></returns>
    [HttpPost]
    public  async Task<TiKu.Domain.ValueObject.RestfulData<TiKu.Domain.ValueObject.AccessTokenObj>> Token( string  user,  string  password)
    {
         var  result =  new  TiKu.Domain.ValueObject.RestfulData<TiKu.Domain.ValueObject.AccessTokenObj>();
         try
         {
             if  ( string .IsNullOrEmpty(user))  throw  new  ArgumentNullException( "user" "用户名不能为空!" );
             if  ( string .IsNullOrEmpty(password))  throw  new  ArgumentNullException( "password" "密码不能为空!" );
     
             //验证用户名和密码
             var  userInfo = await _UserService.CheckUserAndPassword(mobile: user, password: password);
             var  claims =  new  Claim[]
             {
                 new  Claim(ClaimTypes.Name,user),
                 new  Claim(ClaimTypes.NameIdentifier,userInfo.Id.ToString()),
             };
     
             var  key =  new  SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration[ "JwtSecurityKey" ]));
             var  expires = DateTime.Now.AddDays(28); //
             var  token =  new  JwtSecurityToken(
                         issuer: Configuration[ "issuer" ],
                         audience: Configuration[ "audience" ],
                         claims: claims,
                         notBefore: DateTime.Now,
                         expires: expires,
                         signingCredentials:  new  SigningCredentials(key, SecurityAlgorithms.HmacSha256));
     
             //生成Token
             string  jwtToken =  new  JwtSecurityTokenHandler().WriteToken(token);
             result.code = 1;
             result.data =  new  Domain.ValueObject.AccessTokenObj() { AccessToken = jwtToken, Expires = TiKu.Common.Utility.Util.ToUnixTime(expires) };
             result.message =  "授权成功!" ;
             return  result;
         }
         catch  (Exception ex)
         {
             result.message = ex.Message;
             result.code = 0;
             logger.Error( "获取访问令牌时发生错误!" , ex);
             return  result;
         }
    }

      这里,我定义了一个统一返回数据格式的模型-RestfulData,其中有不返回数据data的RestfulData和带data数据的RestfulData<T>,以及返回集合类型的RestfulArray<T>,具体代码如下:

     
    /// <summary>
       ///
       /// </summary>
       public  class  RestfulData
       {
           /// <summary>
           /// <![CDATA[错误码]]>
           /// </summary>
           public  int  code {  get set ; }
     
           /// <summary>
           ///<![CDATA[消息]]>
           /// </summary>
           public  string  message {  get set ; }
     
           /// <summary>
           /// <![CDATA[相关的链接帮助地址]]>
           /// </summary>
           public  string  url {  get set ; }
     
       }
     
       /// <summary>
       ///
       /// </summary>
       /// <typeparam name="T"></typeparam>
       public  class  RestfulData<T> : RestfulData
       {
           /// <summary>
           /// <![CDATA[数据]]>
           /// </summary>
           public  virtual  T data {  get set ; }
       }
     
       /// <summary>
       /// <![CDATA[返回数组]]>
       /// </summary>
       /// <typeparam name="T"></typeparam>
       public  class  RestfulArray<T> : ResultData<IEnumerable<T>>
       {
     
       }

      

    配置JWT认证服务,在Start.cs启动类中,配置如下:

    /// <summary>
             ///
             /// </summary>
             /// <param name="services"></param>
             public  IServiceProvider ConfigureServices(IServiceCollection services)
             {
                 services.AddSingleton<IConfiguration>(Configuration);
                 services.AddMemoryCache(); //添加基于内存的缓存支持
                 services.AddAutofac();
     
                 //配置授权
                 services.AddAuthentication(options =>
                 {
                     options.DefaultAuthenticateScheme =  "JwtBearer" ;
                     options.DefaultChallengeScheme =  "JwtBearer" ;
     
                 }).AddJwtBearer( "JwtBearer" ,
                 (jwtBearerOptions) =>
                 {
                     jwtBearerOptions.TokenValidationParameters =  new  TokenValidationParameters
                     {
                         ValidateIssuerSigningKey =  true ,
                         IssuerSigningKey =  new  SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration[ "JwtSecurityKey" ])), //秘钥
                         ValidateIssuer =  true ,
                         ValidIssuer = Configuration[ "issuer" ],
                         ValidateAudience =  true ,
                         ValidAudience = Configuration[ "audience" ],
                         ValidateLifetime =  true ,
                         ClockSkew = TimeSpan.FromMinutes(5)
                     };
                 });
     
                 services.AddMvc();
     
                 //IOC Autofac
                 var  builder =  new  ContainerBuilder();
                 builder.Populate(services);
     
                 //注册应用服务
                 var  assemblyApplicationService = System.Reflection.Assembly.Load( "TiKu.Application" );
                 builder.RegisterAssemblyTypes(assemblyApplicationService).AsImplementedInterfaces();
     
                 var  container = builder.Build();
                 Container = container;
     
                 return  new  AutofacServiceProvider(container);
             }

      上面使用了IOC容器Autofac。

    其次,配置认证中间件:

    /// <summary>
    ///
    /// </summary>
    /// <param name="app"></param>
    /// <param name="env"></param>
    public  void  Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
         if  (env.IsDevelopment())
         {
             app.UseDeveloperExceptionPage();
         }
         app.UseAuthentication(); //配置授权
         //处理异常
         app.UseStatusCodePages( new  StatusCodePagesOptions()
         {
             HandleAsync = (context) =>
             {
                 if  (context.HttpContext.Response.StatusCode == 401)
                 {
                     using  (System.IO.StreamWriter sw =  new  System.IO.StreamWriter(context.HttpContext.Response.Body))
                     {
                         sw.Write(Newtonsoft.Json.JsonConvert.SerializeObject( new
                         {
                             status = 401,
                             message =  "access denied!" ,
                         }));
                     }
                 }
                 return  System.Threading.Tasks.Task.Delay(0);
             }
         });
         app.UseMvc(routes =>
         {
             routes.MapRoute(name:  "default" , template:  "api/{controller=Home}/{action=Index}/{id?}" );
             routes.MapRoute(name:  "mvc" , template:  "{controller=Home}/{action=Index}/{id?}" );
         });
    }  

    为了测试,我们给ValuesController控制器添加Authorize特性。

    /// <summary>
      ///
      /// </summary>
      [Authorize]
      [Route( "api/[controller]" )]
      public  class  ValuesController : Controller
      {
     
          // GET api/values
          [HttpGet]
          public  IEnumerable< string > Get()
          {
              return  new  string [] {  "value1" "value2"  };
          }
    }<em id= "__mceDel"  style= " font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px;" > </em>

    最后,让我们测试下API的授权,这里,我以Ajax模拟API的调用:

    <script type= "text/javascript" >
         //获取令牌
         $.post( "/oauth/token" , $.param({ user:  "lichaoqiang" , password:  "fdsfds"  })).done( function  (data) {
     
             if  (data.code === 1) {
                 localStorage.setItem( "token" , data.data.accessToken);
             }
         });
     
         //设置HTTP头
         $.ajaxSetup({
             beforeSend:  function  (xhr) {
                 if  (localStorage.getItem( "token" ) !==  null ) {
                     xhr.setRequestHeader( 'Authorization' 'Bearer '  + localStorage.getItem( "token" ));
                 }
             }
         });
     
         $.getJSON( "/api/values" function  (data) { console.log(data); }); //获取受保护的资源
    </script>

      看下效果,直接访问/api/values,会出现如下图:

        当客户请求受保护的资源时,通过HTTP header携带上token。这里需要注意的是,请求头必须是Authorization,值是Bearer空格加上token。这样访问资源时,通过HTTP header携带令牌信息,服务端,通过认证中间件,完成授权认证过程。在上面的示例中,通过向全局Ajax注册事件,将token写入请求Header。、

    至此,就完成了JWT认证授权的过程,.Net Core WebAPI配置起来也很简单。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 18:51 , Processed in 0.074792 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表