最近花了一点时间,阅读了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. 第一零二天上课 PHP TP框架 引入文件路径问题和调用验证码的方式

    外部文件引入到视图模板的方式       1,将外部文件放在Public文件夹下,用load标签引入       2,在模板出书写引入代码(方法有很多,只有以下方法不容易出问题) <load h ...

  2. MapReudce中常见join的方案

    两表join在业务开发中是经常用到,了解了大数据join的原理,对于开发有很大的好处. 1.reduce side join reduce side join是一种简单的join的方法,具体思想如下: ...

  3. archlinux pacman 常用选项

    pacman -S package_name #安装软件包pacman -R package_name #删除软件包 pacman -Rs package_name #顺便删除软件包相关依赖pacma ...

  4. {CSDN}{英雄会}{砍树、石子游戏}

    砍树 思路: 可以将题目意图转化为:给定一棵树,求其中最接近总权值一半的子树. DFS求每个节点的所有子节点的权值和,遍历每个节点,最接近总权值一半的即为答案.复杂度O(N). 石子游戏: 思路: 一 ...

  5. MS SQL Server之光标、存储过程和触发器

    光标 通常数据库操作被认为是以数据集为基础的操作,但是光标被用于以记录为单位来进行操作,来获取数据库中的数据的子集.光标一般用于过程化程序里的嵌入的SQL语句. 对光标的定义如下: DECLARE C ...

  6. PHP调试总结

    PHP调试总结一,环境方面,比如查看安装扩展是否生效,是总支持某扩展.可以在web目录中建一个phpinfo.php在里面输入<?phpphpinfo();?>在浏览器上访问一下,会输出P ...

  7. Bias and Variance

    以下内容参考 cousera 吴恩达 机器学习课程 1. Bias 和 Variance 的定义 Bias and Variance 对于改进算法具有很大的帮助作用,在bias和Variance的指引 ...

  8. 转 Eric Raymond对于几大开发语言的评价

    原文见:http://blog.jobbole.com/79421/ [译注]:Eric Raymond是开源运动的领袖人物,对于UNIX开发有很深的造诣,主持开发了fetchmail.他的<大 ...

  9. 纯手工打造(不使用IDE)java web 项目

    必备环境 1.编译器:jdk 2.web服务器:tomcat 3.文本编辑器:sublime,编写java文件和jsp文件,没有的话用记事本也行. 一.建立工程目录结构,如下图 在操作系统下完成即可, ...

  10. python第十二天-----RabbitMQ

    有一位小伙伴说让我去A站写博客可能会有很多人喜欢,真是搞不懂,北方哪里有卖萌?北方默认状态就是这么萌的!再者说了,这明明就是很专注于技术的博客嘛,能不能严肃点!知不知道什么叫帧? 学习到了数据库的相关 ...