關於ASP.Net Core Web及API身份認證的解決方案

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

 

.NetCore自發布以來,頗受關注,如今.Net Core2.0已經正式發佈,邊火燒眉毛的將.Net跨平臺移植的工做進行到底。想來,也費不了多少事兒。我常常和同事們說,要勇於嘗試新鮮事物,不陰損守舊,方能使本身不斷進步,站在隊伍的前列。下面就關於Asp.Net Core在Web 及API項目上身份認證的問題作下簡單的闡述。html

1、Asp.Net Core Web項目的登陸認證java

    在MVC Web項目中,作用戶登陸受權,是必不可少的工做,不知道你們平時是怎麼作的,我想,大多朋友仍是使用微軟提供的一套認證機制,能夠省去不少功夫。從WebForm時代的Form身份認證,無非是經過客戶端Cookie中存儲認證票據,在請求受保護的資源時,經過Cookie中攜帶的身份票據,再有Asp.net的認證模塊,完整對請求者的身份認證。這一過程,是很清晰簡單的了。在MVC中,大可能是經過中間件(MiddleWare)來完整認證受權過程。在ASP.NETMVC中,咱們瞭解到基於聲明的受權認證(Claim),這種認證方式,好處在於,咱們想在用戶受權時,存儲多個屬性信息,只須要添加多個聲明便可,咱們在微軟的認證中間件中,看到的都是定義好的常量,固然,咱們能夠定義本身的ClaimTypes。然咱們看看微軟在.NetCore中定義的一些聲明吧:web

    // 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項目中,作以下改動:ajax

首先,在Start.cs類中,添加服務,具體代碼以下:windows

 
/// <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();
}

    其次,添加認證中間件api

/// <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項目的登陸認證工做。緩存

2、Asp.Net Core WebApi基於JWT的認證受權cookie

      關於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配置起來也很簡單。

相關文章
相關標籤/搜索