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