最近花了一点时间,阅读了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. 解决ewebeditor for php在IE8下报editor.js错误的解决方案

    打开editor.js,寻找如下代码: if (element.YUSERONCLICK) eval(element.YUSERONCLICK + "anonymous()"); ...

  2. Redmine2.5+CentOS6+Apache2

    redmine是使用ruby开发的一款无任何商业限制且可自行部署的项目管理软件,其简洁的界面比较符合程序猿的定位,使用起来比较方便,由于我之前装3X没 成功,各版本之间的依存和配置都不一样,所以最后参 ...

  3. C 数据类型 长度

    ----数据类型长度 C99标准并不规定具体数据类型的长度大小.计算机具有不同位数的处理器,16,32和更高位的64位处理器,在这些不同的平台上,同一种数据类型具有不同的长度. char,short, ...

  4. memory allocation

    1 malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符. 2,malloc, 必须 包含头文件<stdlib.h> 3, nt* p_scalar = ...

  5. How to Shorten the Paper

    . Remember: you are writing for an expert. Cross out all that is trivial or routine. . Avoid repetit ...

  6. Linux内核分析第一周学习总结:计算机是如何工作的?

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

  7. 根据excel表格中的内容更新Sql数据库

    关于[无法创建链接服务器 "(null)" 的 OLE DB 访问接口 SQL Server 2008读取EXCEL数据时,可能会报这个错误:无法创建链接服务器 "(nu ...

  8. 一个前辈对FPGA的理解

    接下来对比一下我原来和现在对于FPG A的认识:原来从单片机转型到FPG A时,并没有摸清这趟河水的深浅,而在不知深浅的情况下,我已经开始下水了.当时我认为FPG A和单片机一样,它是由一个超级经典的 ...

  9. Exception异常规范

    把异常的栈轨迹以String形式返回 /** * 把异常的栈轨迹以String形式返回,而不是直接打印到console * @author King * @time 2015-04-29 * @ret ...

  10. MATLAB - 练习程序,直方图均衡化

    直方图均衡化的作用是图像增强. 有两个问题比较难懂,一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布. 第一个问题.均衡化过程中,必须要保证两个条件:①像素无论怎么映射, ...