最近花了一点时间,阅读了IdentityServer的源码,大致了解项目整体的抽象思维、面向对象的重要性; 生产环境如果要使用 IdentityServer3 ,主要涉及授权服务,资源服务的部署负载的问题,客户端(clients),作用域(scopes),票据(token)一定都要持久化, 客户端与作用域的持久化只需要实现 IClientStore 与 IScopeStore 的接口,可以自己实现,也可以直接使用 IdentityServer3 自身的扩展 IdentityServer3.EntityFramework 。

Package

核心类库
Install-Package IdentityServer3
IdentityServer 核心库,只支持基于内存的客户端信息与用户信息配置

配置信息持久化
客户端,作用域,票据的持久化 ,支持的扩展有两个,一个基于 EF,另外一个使用MongoDb(社区支持)
Install-Package IdentityServer3.EntityFramework
Install-Package IdentityServer.v3.MongoDb

用户持久化

用户的持久化支持 MembershipReboot 与 ASP.NET Identity 两种
Install-Package IdentityServer3.MembershipReboot
Install-Package IdentityServer3.AspNetIdentity

其他插件

WS-Federation
Install-Package IdentityServer3.WsFederation
Access token validation middleware(验证中间件)
Install-Package IdentityServer3.AccessTokenValidation

国际化

https://github.com/johnkors/IdentityServer3.Contrib.Localization

缓存

https://github.com/AliBazzi/IdentityServer3.Contrib.RedisStore

客户端

https://github.com/IdentityModel/IdentityModel2

配置信息持久化(Entity Framework support for Clients, Scopes, and Operational Data)

客户端(clients)与作用域(scopes)的持久化

客户端与作用域的持久化只需要实现 IClientStore 与 IScopeStore 的接口,默认EF 在 IdentityServerServiceFactory 实现了 RegisterClientStore 与 RegisterScopeStore 两个扩展方法,也可以使用 RegisterConfigurationServices 方法,默认包含以上两个扩展方法合集;RegisterOperationalServices 扩展方法实现 IAuthorizationCodeStore, ITokenHandleStore, IRefreshTokenStore, and IConsentStore 功能等。

可以在 IdentityServer3.EntityFramework 的项目中找到数据库的初始SQL ,

ER 关系项目结构

IdentityServerServiceFactoryExtensions 类扩展 IdentityServerServiceFactory 实现方法来持久化信息,最后 Registration 到接口上

public static class IdentityServerServiceFactoryExtensions
{
public static void RegisterOperationalServices(this IdentityServerServiceFactory factory, EntityFrameworkServiceOptions options)
{
if (factory == null) throw new ArgumentNullException("factory");
if (options == null) throw new ArgumentNullException("options"); factory.Register(new Registration<IOperationalDbContext>(resolver => new OperationalDbContext(options.ConnectionString, options.Schema)));
factory.AuthorizationCodeStore = new Registration<IAuthorizationCodeStore, AuthorizationCodeStore>();
factory.TokenHandleStore = new Registration<ITokenHandleStore, TokenHandleStore>();
factory.ConsentStore = new Registration<IConsentStore, ConsentStore>();
factory.RefreshTokenStore = new Registration<IRefreshTokenStore, RefreshTokenStore>();
} public static void RegisterConfigurationServices(this IdentityServerServiceFactory factory, EntityFrameworkServiceOptions options)
{
factory.RegisterClientStore(options);
factory.RegisterScopeStore(options);
} public static void RegisterClientStore(this IdentityServerServiceFactory factory, EntityFrameworkServiceOptions options)
{
if (factory == null) throw new ArgumentNullException("factory");
if (options == null) throw new ArgumentNullException("options"); factory.Register(new Registration<IClientConfigurationDbContext>(resolver => new ClientConfigurationDbContext(options.ConnectionString, options.Schema)));
factory.ClientStore = new Registration<IClientStore, ClientStore>();
factory.CorsPolicyService = new ClientConfigurationCorsPolicyRegistration(options);
} public static void RegisterScopeStore(this IdentityServerServiceFactory factory, EntityFrameworkServiceOptions options)
{
if (factory == null) throw new ArgumentNullException("factory");
if (options == null) throw new ArgumentNullException("options"); factory.Register(new Registration<IScopeConfigurationDbContext>(resolver => new ScopeConfigurationDbContext(options.ConnectionString, options.Schema)));
factory.ScopeStore = new Registration<IScopeStore, ScopeStore>();
}
}

TokenCleanup 类负责定时清除过期的票据信息

public class TokenCleanup
{
private readonly static ILog Logger = LogProvider.GetCurrentClassLogger(); EntityFrameworkServiceOptions options;
CancellationTokenSource source;
TimeSpan interval; public TokenCleanup(EntityFrameworkServiceOptions options, int interval = )
{
if (options == null) throw new ArgumentNullException("options");
if (interval < ) throw new ArgumentException("interval must be more than 1 second"); this.options = options;
this.interval = TimeSpan.FromSeconds(interval);
} public void Start()
{
if (source != null) throw new InvalidOperationException("Already started. Call Stop first."); source = new CancellationTokenSource();
Task.Factory.StartNew(()=>Start(source.Token));
} public void Stop()
{
if (source == null) throw new InvalidOperationException("Not started. Call Start first."); source.Cancel();
source = null;
} public async Task Start(CancellationToken cancellationToken)
{
while (true)
{
if (cancellationToken.IsCancellationRequested)
{
Logger.Info("CancellationRequested");
break;
} try
{
await Task.Delay(interval, cancellationToken);
}
catch
{
Logger.Info("Task.Delay exception. exiting.");
break;
} if (cancellationToken.IsCancellationRequested)
{
Logger.Info("CancellationRequested");
break;
} await ClearTokens();
}
} public virtual IOperationalDbContext CreateOperationalDbContext()
{
return new OperationalDbContext(options.ConnectionString, options.Schema);
} private async Task ClearTokens()
{
try
{
Logger.Info("Clearing tokens");
using (var db = CreateOperationalDbContext())
{
var query =
from token in db.Tokens
where token.Expiry < DateTimeOffset.UtcNow
select token; db.Tokens.RemoveRange(query); await db.SaveChangesAsync();
}
}
catch(Exception ex)
{
Logger.ErrorException("Exception cleaning tokens", ex);
}
}
}

配置Idsv授权服务

Startup 类

 public class Startup
{
/// <summary>
/// 配置Idsv授权服务
/// </summary>
/// <param name="app"></param>
public void Configuration(IAppBuilder app)
{
#region OAuth 2.0 服务端初始化
//配置EF
var ef = new EntityFrameworkServiceOptions
{
ConnectionString = DbSetting.OAuth2,
}; var factory = new IdentityServerServiceFactory();
//注册Client与Scope的实现
factory.RegisterConfigurationServices(ef);
//注册Token实现
factory.RegisterOperationalServices(ef);
//自定义用户服务
factory.UserService = new Registration<IUserService>(resolver => AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<IdSvrUserService>());
//自定义视图
factory.ViewService = new Registration<IViewService, IdSvrMvcViewService<LoginController>>(); factory.Register(new Registration<HttpContext>(resolver => HttpContext.Current));
factory.Register(new Registration<HttpContextBase>(resolver => new HttpContextWrapper(resolver.Resolve<HttpContext>())));
//注册Request
factory.Register(new Registration<HttpRequestBase>(resolver => resolver.Resolve<HttpContextBase>().Request));
//注册Response
factory.Register(new Registration<HttpResponseBase>(resolver => resolver.Resolve<HttpContextBase>().Response));
factory.Register(new Registration<HttpServerUtilityBase>(resolver => resolver.Resolve<HttpContextBase>().Server));
//注册Session
factory.Register(new Registration<HttpSessionStateBase>(resolver => resolver.Resolve<HttpContextBase>().Session)); /*
//注册 Redis 服务
factory.Register(new Registration<IDatabaseAsync>(resolver => ConnectionMultiplexer.Connect(CacheSetting.Redis).GetDatabase()));
factory.AuthorizationCodeStore = new Registration<IAuthorizationCodeStore, IdentityServer3.Contrib.RedisStore.Stores.AuthorizationCodeStore>();
factory.TokenHandleStore = new Registration<ITokenHandleStore, IdentityServer3.Contrib.RedisStore.Stores.TokenHandleStore>();
factory.RefreshTokenStore = new Registration<IRefreshTokenStore, IdentityServer3.Contrib.RedisStore.Stores.RefreshTokenStore>();
*/ /*
//客户端信息缓存
var clientStoreCache = new ClientStoreCache(redis);
//作用域信息缓存
var scopeStoreCache = new ScopeStoreCache(redis);
//用户信息缓存
var userServiceCache = new UserServiceCache(redis);
//注册客户端缓存-
factory.ConfigureClientStoreCache(new Registration<ICache<Client>>(clientStoreCache));
//注册作用域缓存
factory.ConfigureScopeStoreCache(new Registration<ICache<IEnumerable<Scope>>>(scopeStoreCache));
//注册用户缓存
// factory.ConfigureUserServiceCache(new Registration<ICache<IEnumerable<Claim>>>(userServiceCache));
// factory.ConfigureUserServiceCache(TimeSpan.FromMilliseconds(1000 * 10));
*/ //Idsv 配置
app.UseIdentityServer(new IdentityServerOptions
{
SiteName = "Embedded Homeinns PMS 2.0 OAuth2 Service",
EnableWelcomePage = true,
Factory = factory,
RequireSsl = Constants.RequireSsl,
PublicOrigin = Constants.PublicOrigin,
LoggingOptions = new LoggingOptions()
{
EnableHttpLogging = true,
// EnableKatanaLogging = true,
// EnableWebApiDiagnostics = true,
// WebApiDiagnosticsIsVerbose = true,
},
SigningCertificate = new X509Certificate2(string.Format(@"{0}\IdSvr\idsrv3test.pfx", AppDomain.CurrentDomain.BaseDirectory), "idsrv3test"),
EventsOptions = new EventsOptions
{
RaiseSuccessEvents = true,
RaiseErrorEvents = true,
RaiseFailureEvents = true,
RaiseInformationEvents = true,
},
CspOptions = new CspOptions
{
Enabled = false,
},
AuthenticationOptions = new AuthenticationOptions
{
CookieOptions = new IdentityServer3.Core.Configuration.CookieOptions
{
SlidingExpiration = true,
},
EnablePostSignOutAutoRedirect = true,
EnableLocalLogin = true,
EnableSignOutPrompt = false
}
});
//启动清除过期票据定时器
var cleanToken = new TokenCleanup(ef, );
cleanToken.Start();
#endregion #region OAuth 2.0 管理后台 初始化
/*
//管理员功能 初始化
app.Map("/admin", adminApp =>
{
var factoryAdmin = new IdentityAdmin.Configuration.IdentityAdminServiceFactory();
//注入配置
factoryAdmin.Configure();
//注册管理员
adminApp.UseIdentityAdmin(new IdentityAdmin.Configuration.IdentityAdminOptions
{
Factory = factoryAdmin,
//AdminSecurityConfiguration =
});
});
*/
#endregion
}
}

客户端模式问题

  • 客户端,作用域,票据的持久化 [OK]
  • 限制客户端每天获得新票据的次数
  • 票据过期删除的策略 [OK]
  • 授权服务器客户端信息缓存策略 [OK]
  • 资源服务器票据验证的缓存策略 [OK]
  • 作用域权限范围控制
  • ClientId 与 ClientSecret 的生成规则 [OK]
  • 密码模式用户的身份验证 https://github.com/IdentityServer/IdentityServer3.AspNetIdentity

REFER:
Deployment
https://identityserver.github.io/Documentation/docsv2/advanced/deployment.html

基于 IdentityServer3 实现 OAuth 2.0 授权服务数据持久化的更多相关文章

  1. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】

    密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码.客户端使用这些信息,向"服务商提供商"索要授权 ...

  2. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】

    github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...

  3. Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端 目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Se ...

  4. 理解OAuth 2.0授权

    一.什么是OAuth 二.什么场景下会用到OAuth授权 三.OAuth 2.0中的4个成员 四.OAuth 2.0授权流程 五.OAuth 2.0授权模式 1.    authorization c ...

  5. React + Node 单页应用「二」OAuth 2.0 授权认证 & GitHub 授权实践

    关于项目 项目地址 预览地址 记录最近做的一个 demo,前端使用 React,用 React Router 实现前端路由,Koa 2 搭建 API Server, 最后通过 Nginx 做请求转发. ...

  6. 转 OAuth 2.0授权协议详解

    http://www.jb51.net/article/54948.htm 作者:阮一峰 字体:[增加 减小] 类型:转载 时间:2014-09-10我要评论 这篇文章主要介绍了OAuth 2.0授权 ...

  7. Spring Security实现OAuth2.0授权服务 - 进阶版

    <Spring Security实现OAuth2.0授权服务 - 基础版>介绍了如何使用Spring Security实现OAuth2.0授权和资源保护,但是使用的都是Spring Sec ...

  8. OAuth 2.0授权框架详解

    目录 简介 OAuth的构成 refresh Token Authorization Code模式 隐式授权 Resource Owner 授权密码认证 Client 认证授权 github的OAut ...

  9. SimpleSSO:使用Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Security.SimpleSSO模拟OpenID认证 通过authorization co ...

随机推荐

  1. LeftoverDataException.

    在用java poi 3.8操作excel的时候,在打开一个已有excel文件时,有时候会报错: org.apache.poi.hssf.record.RecordInputStream$Leftov ...

  2. web开发-给即将毕业实习生的一点面试经验

    简历投递: 智联招聘51job 像赶集网和58同城最好别去投 面试的公司,特别是深圳这边,面试的时候公司小,很多人,八九不离十是那种搞培训的,很多时候,有些公司会主动打电话来教你去面试,这些绝大多数也 ...

  3. Python2和Python3在windows下共存

    Python2.7 和 Python3不兼容,两种环境可能都会用到.ubuntu14.04中已经默认安装了这两个版本,在shell中输入python会自动进入Python2.7的交互环境,输入Pyth ...

  4. maven提示invalid LOC header (bad signature)的解决办法

    今天执行mvn test的时候提示: 错误:读取 /home/subaochen/.m2/repository/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.ja ...

  5. maven 加入本地jar包

    Apache Maven,由Apache软件基金会所提供.基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建.报告和文档等步骤.曾是Jakarta项目的子项目,现 ...

  6. linux C学习笔记01--makefile

    不知不觉毕业五年了,以前学的linux基本都忘了,重新温习起来吧! 下面是自己写的makefile文件,供新手和自己回头时查阅 CC=gcc EXE=c.out CCC=g++ EEE=cc.out ...

  7. vsnprintf

    http://www.cplusplus.com/reference/cstdio/vsnprintf/ int vsnprintf (char * s, size_t n, const char * ...

  8. Linux内核分析第五周学习总结:扒开系统调用的三层皮(下)

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuO ...

  9. Python全栈--7模块--random os sys time datetime hashlib pickle json requests xml

    模块分为三种: 自定义模块 内置模块 开源模块 一.安装第三方模块 # python 安装第三方模块 # 加入环境变量 : 右键计算机---属性---高级设置---环境变量---path--分号+py ...

  10. hibernate进行多表联合查询

    hibernate是按照hql语句来进行查询的, 里面所使用的表名, 其实是实体类的名字, hql语句的写法并没有多大差别, 是在返回结果的时候要稍微做一些处理 //使用hibernate进行多表查询 ...