在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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" , "用户名不能为空!" );
全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论