在用户注册后的Web Api 2 Identity 2应用程序中,我在单个表中有一条记录:AspNetUsers。我使用以下http请求获取令牌:
POST https://localhost:44304/Token HTTP/1.1
Accept: application/json
Content-type: application/x-www-form-urlencoded
Accept-Encoding: gzip
Content-Length: 68
Host: localhost:44304
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
grant_type=password&username=somemail@gmail.com&password=123456
我得到了access_token的响应:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 695
Content-Type: application/json;charset=UTF-8
Expires: -1
Server: Microsoft-IIS/8.0
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcU2VyZ2V5XERvY3VtZW50c1xWaXN1YWwgU3R1ZGlvIDIwMTNcUHJvamVjdHNcbXZjX3dlYmFwaVxXZWJBcHBsaWNhdGlvblxXZWJBcHBsaWNhdGlvblxUb2tlbg==?=
X-Powered-By: ASP.NET
Date: Tue, 25 Nov 2014 17:40:07 GMT
{"access_token":"gsvW23e1...}
获得令牌后,没有一条记录被添加到数据库中。表AspNetUsers中只有单一记录。没有关于已颁发令牌的信息存储在数据库的任何表中。
我在web api控制器中使用以下代码来验证用户身份:
var currentUser = manager.FindById(User.Identity.GetUserId());
if (currentUser == null)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return ResponseMessage(response);
}
之后我执行密码更改并尝试使用旧的access_token(我在密码更改之前获得)调用一些web api控制器方法,并且access_token仍然有效! currentUser不为null! 我已经在stackoverflow上读了另一个线程 ASP.Net Identity sign-out all sessions ASP.Net Identity Logout 和博客 https://timmlotter.com/blog/asp-net-identity-invalidate-all-sessions-on-securitystamp-update/ 但我仍然不明白存储有关已发行令牌的信息的位置。 所以我的问题是: 1)服务器上存储的access_token信息在哪里? 2)为什么密码更改后我仍然可以使用密码更改前服务器发出的access_token? 3)如何使密码更改前发出的所有access_token无效?
答案 0 :(得分:5)
1)令牌不存储在数据库或本地存储中的任何位置。这意味着令牌不会存储在服务器中的任何位置。
2)实际上,密码重置令牌是使用SecurityStamp生成的,并针对用户的SecurityStamp进行验证。除非您没有设置该用户的过期时间或更新的SecurityStamp,否则令牌不会过期。
可以在身份配置类的userManager属性上设置过期时间。以下示例显示令牌生命周期为1小时。查看this文章。
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>
(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = TimeSpan.FromHours(1)
};
}
您可以使用自己的机制检查以前使用过的令牌。
3)更新SecurityStamp。这将使为该用户发布的所有令牌无效,包括cookie。最好使用自己的想法来使密码重置令牌过期。
作为示例,您可以使用另一列来存储数据库中任何生成的密码重置令牌并对其进行验证(可能有更好的方法)。
请记住,登录access_token的生成方式不同,并且它具有您在Owin启动承载令牌到期时间设置的到期时间。
希望这有帮助。