.Net Identity OAuth 2.0 SecurityStamp 使用
起源:
近期帮别人做项目,涉及到OAuth认证,服务端主动使token失效,要使对应用户不能再继续访问,只能重新登陆,或者重新授权。
场景:
这种场景OAuth2.0是支持的,比如用户修改了密码,那所有之前保留在各个客户端的token均失效,要求用户重新提供凭证。
原因:
在之前的项目中,一旦授权服务AuthorizationServer发放了token,所有的资源服务只会通过统一的加密解密算法,解析出token中的信息包括用户身份等,就直接使用了。这样因为不和数据库或外部存储介质交互,所以效率会比较高。以下是在所有资源服务、包括认证服务Web.config中的配置,machineKey必须相同。
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<machineKey decryptionKey="B7E121C5839A624E" validation="SHA1" validationKey="C2B8DF31AB96asd428066DFDA1A479542825F3B48865C4E47AF6A026F2" />
</system.web>
这样效率是提高了,但是每次验证不与后端(尤指存储)交互,所以token一旦发出,除非客户端主动清除或着超出有效时间,否则都有效,有一定的失窃风险。
分析:
.Net在IdentityServer3.0在用户表中使用SecurityStamp字段,作为安全标识,去识别是否失效。默认情况是没有开启验证的,否则就像之前说的每次都会和数据库交互,降低性能。关于SecurityStamp的说明,大家可以看一下这篇文章:
What is ASP.NET Identity's IUserSecurityStampStore<TUser> interface?
This is meant to represent the current snapshot of your user's credentials. So if nothing changes, the stamp will stay the same. But if the user's password is changed, or a login is removed (unlink your google/fb account), the stamp will change. This is needed for things like automatically signing users/rejecting old cookies when this occurs, which is a feature that's coming in 2.0.
Edit: Updated for 2.0.0. So the primary purpose of the
SecurityStamp
is to enable sign out everywhere. The basic idea is that whenever something security related is changed on the user, like a password, it is a good idea to automatically invalidate any existing sign in cookies, so if your password/account was previously compromised, the attacker no longer has access.In 2.0.0 we added the following configuration to hook the
OnValidateIdentity
method in theCookieMiddleware
to look at theSecurityStamp
and reject cookies when it has changed. It also automatically refreshes the user's claims from the database everyrefreshInterval
if the stamp is unchanged (which takes care of things like changing roles etc)
文章中给出的代码如下:
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider {
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
虽然这篇文章大致讲明白了,这是个什么东西和怎么用,但是仔细想想,还是有问题,因为我们是使用Bearer方式,这里只是Cookie,所以还差点什么。在资源服务中的配置如下:
namespace ResourceServer
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseOAuthBearerAuthentication(new Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationOptions());
}
}
}
所以我们应该更改的是OAuthBearerAuthenticationOptions这个对象。有找到文章参考如下:
Using bearer tokens (ASP.NET Identity 2.0) with WCF Data Services
总结:
在资源服务中,引入Microsoft.AspNet.Identity.Owin包,在Startup中,更改如下代码:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
Provider = new OAuthBearerAuthenticationProvider()
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager, User>(
validateInterval: TimeSpan.FromMinutes(),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
}
}
查看SecurityStampValidator类的源码:
public static Func<CookieValidateIdentityContext, Task> OnValidateIdentity<TManager, TUser, TKey>(
TimeSpan validateInterval, Func<TManager, TUser, Task<ClaimsIdentity>> regenerateIdentityCallback,
Func<ClaimsIdentity, TKey> getUserIdCallback)
where TManager : UserManager<TUser, TKey>
where TUser : class, IUser<TKey>
where TKey : IEquatable<TKey>
{
.....
var user = await manager.FindByIdAsync(userId).WithCurrentCulture();
var reject = true;
// Refresh the identity if the stamp matches, otherwise reject
if (user != null && manager.SupportsUserSecurityStamp)
{
var securityStamp =
context.Identity.FindFirstValue(Constants.DefaultSecurityStampClaimType);
if (securityStamp == await manager.GetSecurityStampAsync(userId).WithCurrentCulture())
{
reject = false;
// Regenerate fresh claims if possible and resign in
if (regenerateIdentityCallback != null)
{
var identity = await regenerateIdentityCallback.Invoke(manager, user).WithCurrentCulture();
if (identity != null)
{
// Fix for regression where this value is not updated
// Setting it to null so that it is refreshed by the cookie middleware
context.Properties.IssuedUtc = null;
context.Properties.ExpiresUtc = null;
context.OwinContext.Authentication.SignIn(context.Properties, identity);
}
}
}
}
.....
};
}
它会自己判断token中解析出来的securityStamp是否与数据库之前保存的一致,至此,完全解决。
问题:
- 我们之前说过的,每次请求认证都会请求数据库,降低性能。
- 资源服务不能独立,必须与用户库绑定。
.Net Identity OAuth 2.0 SecurityStamp 使用的更多相关文章
- [转]An introduction to OAuth 2.0 using Facebook in ASP.NET Core
本文转自:http://andrewlock.net/an-introduction-to-oauth-2-using-facebook-in-asp-net-core/ This is the ne ...
- Identity Server 4 预备知识 -- OAuth 2.0 简介
OAuth 2.0 简介 OAuth有一些定义: OAuth 2.0是一个委托协议, 它可以让那些控制资源的人允许某个应用以代表他们来访问他们控制的资源, 注意是代表这些人, 而不是假冒或模仿这些人. ...
- Identity Server 4 原理和实战(完结)_----选看 OAuth 2.0 简介(上)
https://www.yuque.com/yuejiangliu/dotnet/cg95ni 代表资源所有者的凭据 授权 Authorization Grant 授权是一个代表着资源所有者权限的凭据 ...
- ASP.NET WebApi OWIN 实现 OAuth 2.0
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...
- NET WebApi OWIN 实现 OAuth 2.0
NET WebApi OWIN 实现 OAuth 2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和 ...
- 基于 IdentityServer3 实现 OAuth 2.0 授权服务数据持久化
最近花了一点时间,阅读了IdentityServer的源码,大致了解项目整体的抽象思维.面向对象的重要性; 生产环境如果要使用 IdentityServer3 ,主要涉及授权服务,资源服务的部署负载的 ...
- 基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】
密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码.客户端使用这些信息,向"服务商提供商"索要授权 ...
- 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】
github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...
- 我也想聊聊 OAuth 2.0 —— Access Token
这是一篇待在草稿箱半年之久的文章 连我自己都不知道我的草稿箱有多少未发布的文章了.这应该是我在上一家公司未解散之前写的,记得当时是要做一个开发者中心,很不幸. 今天,打开草稿箱有种莫名的伤感,看到这个 ...
随机推荐
- zabbix添加对tomcat线程池的监控
在zabbix模板中添加以下监控项: 可以参考文档:http://www.fblinux.com/?p=616
- 【DVWA】Web漏洞实战之File Upload
File Upload File Upload,即文件上传漏洞,一般的上传漏洞可能是未验证上传后缀 或者是验证上传后缀被bypass 或者是上传的文件验证了上传后缀但是文件名不重命名. LOW 直接上 ...
- MFC之自绘控件
在描绘MFC界面时,MFC自带的控件样式是绝对不满足界面的需求的. 所以我们就要在MFC自带控件基础上对控件样式进行重绘. 在采用自绘前界面样式 采用自绘后界面样式 是不是自绘控件后看起来正常了很多? ...
- 如何使用 SSH 连接 VMWare 虚拟机中的 Ubuntu
环境:VMWare Player 5.0.2,Ubuntu 13.10 VMWare共有3种网络连接模式,分别是: 1. bridged(桥接模式):虚拟机将直接连接到物理局域网,使自身独立于宿主机 ...
- 【Spring系列】Spring IoC
前言 IoC其实有两种方式,一种是DI,而另一种是DL,即Dependency Lookup(依赖查找),前者是当前软件实体被动接受其依赖的其他组件被IOc容器注入,而后者是当前软件实体主动去某个服务 ...
- storm事务
1. storm 事务 对于容错机制,Storm通过一个系统级别的组件acker,结合xor校验机制判断一个msg是否发送成功,进而spout可以重发该msg,保证一个msg在出错的情况下至少被重发一 ...
- Sencha Touch 实战开发培训 视频教程 第二期 第二节
2014.4.9晚上8:00分开课. 本节课耗时接近1个半小时,需要一点耐心来观看. 本期培训一共八节,前两节免费,后面的课程需要付费才可以观看. 本节内容: 了解Container: 了解card布 ...
- openstack-networking-neutron(二)---tun/tap
本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 简介 虚拟网卡Tun/tap驱动是一个开源项目,支持很多的类UNIX平台,Ope ...
- JVM学习--开启应用的gc日志功能
一.开启方法 For Java 1.4, 5, 6, 7, 8 pass this JVM argument to your application: -XX:+PrintGCDetails -XX: ...
- 2527: [Poi2011]Meteors[整体二分]
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MB Submit: 1528 Solved: 556 [Submit][S ...