[ASP.NET] ASP.NET Identity 中 ClaimsIdentity 解析
各位好 : )
最近筆者在嘗試改用ASP.NET Identity做為新系統的認證方式,發現到網路上給的資訊,不是很完整,所以做為一個工程屍,為了避免大家遇到一樣的問題。特地將一些有趣的地方記錄下來
首先如果你是舊的專案,想要用ASP.NET Identity ,你必需要利用NuGet安裝以下幾個套件
Microsoft.Owin.Host.SystemWeb
Microsoft.AspNet.Identity.Owin
接下來,我是在App_Start資料夾中加入Startup.cs檔,加入以下程式碼 (這裡是直接參考有用Identity的專案中的設定,但專案中是有將Startup.cs拆成兩個class ,這裡我僅用一個class檔)
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
// Cookie Auth
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Home/Index")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ApplicationCookie);
}
再來微調一下專案中的Web.config檔
<system.web>
<authentication mode="None" />
------------------------------------------------------
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
</modules>
在實際要進行登入時,有二種寫法。二種都是可以的,但接下來我會講到幾個點要注意
//AuthenticationManager的獲取方式
HttpContext.GetOwinContext().Authentication;
//清除先前的登錄資訊
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
//第一種
IList<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, Request["userName"].ToString()));
claims.Add(new Claim(ClaimTypes.Name, Request["userName"].ToString()));
claims.Add(new Claim(ClaimTypes.Role, "Users"));
ClaimsIdentity identity = new ClaimsIdentity(claims,
DefaultAuthenticationTypes.ApplicationCookie);
//第二種
ClaimsIdentity claimsIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie,ClaimTypes.NameIdentifier, ClaimTypes.Role);
claimsIdentity.AddClaim(new Claim( ClaimTypes.NameIdentifier, "MyCustomID"));
claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, "MyCustomUser"));
claimsIdentity.AddClaim(new Claim(
ClaimTypes.NameIdentifier, Request["userName"].ToString(),
"http://www.w3.org/2001/XMLSchema#string"));
claimsIdentity.AddClaim(
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
"My Identity", "http://www.w3.org/2001/XMLSchema#string"));
//這裡強烈建議用第二種的寫法, 原因是如果你的頁面有利用antiforgerytoken 來防CSRF攻擊時,第一種寫法會產生錯誤
//但如果用第二種寫法,並加上identityprovider 這一個Claim 。就能正常使用了,不過在本篇最下方也有提到,可以透過Global.asax.cs加入參數設定,如果是透過Global.asax.cs的話,則以上兩種寫法都是沒有問題的 : )
//登錄
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true },identity);
-----------------------------重點來了-------------------------------
我在找資料時發現在StackOverFlow上有的回應居然是錯的…
比如說像以下這篇
private async Task SignInAsync(ApplicationUser user, bool isPersistent) {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
其實他提到的並沒有很完整,問題在哪裡呢?問題在於我們的Startup.cs中
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Home/Index")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
//其實這一段內部實作來說跟上面是一樣的
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
其實ClaimsIdentity 最後是會用粗體的地方做為Cookie的名稱,而也是因為這樣,如果你在SignOut的方法裡指定的名稱跟Startup.cs中設定的不一樣。會導致你無法正常的登出先前使用者的資訊喔!(很重要)
有興趣可以參考這篇
CookieAuthenticationMiddelware 对cookie的加密方式
至於剛剛提到的Startup.cs ,嚴格來說其實app.UseExternalSignInCookie與app.UseCookieAuthentication只要選一種實作就可以了。參考一下UseExternalSignInCookie原始碼會發現其實他做的事情真的跟UseCookieAuthentication是差不多的
public static void UseExternalSignInCookie(this IAppBuilder app, string externalAuthenticationType) {
if (app == null) {
throw new ArgumentNullException("app");
}
app.SetDefaultSignInAsAuthenticationType(externalAuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = externalAuthenticationType,
AuthenticationMode = AuthenticationMode.Passive,
CookieName = CookiePrefix + externalAuthenticationType,
ExpireTimeSpan = TimeSpan.FromMinutes(5),
});
}
根據上面我們提到的CookieName設定,也可以知道我們如果是利用ClaimsIdentity要做登入時,CookieName也要跟Startup.cs設定的一樣,不然你會發現,明明程式碼都是對的,為什麼就是登入不了 (  ̄ c ̄)y▂ξ
ClaimsIdentity claimsIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie,ClaimTypes.NameIdentifier, ClaimTypes.Role);
另外,如果又不小心遇到AntiForgery錯誤的話 (這是微軟提供一種防CSRF攻擊的方法)
可以在Global.asax.cs檔中在Appliccation_Start加入這段。ClaimTypes就端看你的ClaimsIdentity有什麼樣的Types能用
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
以上是簡單的ClaimsIdentity心得,我們下回見 : )
參考 :
https://github.com/MohammadYounes/MVC5-MixedAuth/issues/20
http://dotnetcodr.com/2013/02/11/introduction-to-claims-based-security-in-net4-5-with-c-part-1/
http://stackoverflow.com/questions/19977833/anti-forgery-token-issue-mvc-5
[ASP.NET] ASP.NET Identity 中 ClaimsIdentity 解析的更多相关文章
- 在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数,以及如何根据URL解析出匹配到MVC路由的Controller和Action
目前项目中有个需求,需要在WebForm中去构造MVC的URL信息,这里写了一个帮助类可以在ASP.NET非MVC环境中(WebForm中)构造MVC的URL信息,主要就是借助当前Http上下文去构造 ...
- asp.net core使用identity+jwt保护你的webapi(三)——refresh token
前言 上一篇已经介绍了identity的注册,登录,获取jwt token,本篇来完成refresh token. 开始 开始之前先说明一下为什么需要refresh token. 虽然jwt toke ...
- ASP.NET Core 之 Identity 入门(一)
前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...
- [转]ASP.NET Core 之 Identity 入门(一)
本文转自:http://www.cnblogs.com/savorboard/p/aspnetcore-identity.html 前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里 ...
- ASP.NET Core和ASP.NET Framework共享Identity身份验证
.NET Core 已经热了好一阵子,1.1版本发布后其可用性也越来越高,开源.组件化.跨平台.性能优秀.社区活跃等等标签再加上"微软爸爸"主推和大力支持,尽管现阶段对比.net ...
- 理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文
这篇英文博文是 Andrew Lock 写的 Introduction to Authentication with ASP.NET Core . 以下是简单的阅读笔记: -------------- ...
- ASP.NET Core 和 ASP.NET Framework 共享 Identity 身份验证
.NET Core 已经热了好一阵子,1.1版本发布后其可用性也越来越高,开源.组件化.跨平台.性能优秀.社区活跃等等标签再加上"微软爸爸"主推和大力支持,尽管现阶段对比.net ...
- 【转】理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文
这篇英文博文是 Andrew Lock 写的 Introduction to Authentication with ASP.NET Core . 以下是简单的阅读笔记: -------------- ...
- ASP.NET Core 之 Identity 入门(转载)
原文地址:https://www.cnblogs.com/gongap/p/9504562.html 前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库 ...
随机推荐
- ajax一些东西
jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...
- 【数据结构】红黑树与跳表-(SortSet)-(TreeMap)-(TreeSet)
SortSet 有序的Set,其实在Java中TreeSet是SortSet的唯一实现类,内部通过TreeMap实现的:而TreeMap是通过红黑树实现的:而在Redis中是通过跳表实现的: Skip ...
- Mesos源码分析(9): Test Framework的启动
我们以Test Framework为例子解释Framework的启动方式. Test Framework的代码在src/examples/test_framework.cpp中的main函数 首先要指 ...
- 【安富莱专题教程第5期】工程调试利器RTT实时数据传输组件,替代串口调试,速度飞快,可以在中断和多任务中随意调用
说明:1.串口作为经典的调试方式已经存在好多年了,缺点是需要一个专门的硬件接口.现在有了SEGGER的RTT(已经发布有几年了),无需占用系统额外的硬件资源,而且速度超快,是替代串口调试的绝佳方式.2 ...
- 数据库sql常见优化方法
以前刚开始做项目的时候,开发经验尚浅,每次遇到查询比较慢时,项目经理就会问:是不是又用select * 了?查询条件有没有加索引?一语惊醒梦中人,赶紧检查..果然如此! 有时我们写sql语句时,没有考 ...
- Ubuntu 16.04安装Nginx
在Ubuntu下安装Nginx有以下方法,但是如果想要安装最新版本的就必须下载源码包编译安装. 一.基于APT源安装 sudo apt-get install nginx 安装好的文件位置: /usr ...
- [Swift]LeetCode443. 压缩字符串 | String Compression
Given an array of characters, compress it in-place. The length after compression must always be smal ...
- [Swift]LeetCode746. 使用最小花费爬楼梯 | Min Cost Climbing Stairs
On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay ...
- 46道史上最全Redis面试题,面试官能问的都被我找到了(含答案)
Redis高性能缓存数据库 1.什么是 Redis?简述它的优缺点? Redis 的全称是:Remote Dictionary.Server,本质上是一个 Key-Value 类型的内存数据库,很像m ...
- 第四周 IP通信基础回顾
传输层的作用:分割上层数据:在应用主机程序之间建立到端的连接:流量控制:面向连接与面向非连接. URG=1,紧急指针字段有效. 窗口字段- 占2个字节,用来让对方设置发送窗口的依据,单位为字节. TC ...