最近花了一点时间,阅读了IdentityServer的源码,大体了解项目总体的抽象思惟、面向对象的重要性; 生产环境若是要使用 IdentityServer3 ,主要涉及受权服务,资源服务的部署负载的问题,客户端(clients),做用域(scopes),票据(token)必定都要持久化, 客户端与做用域的持久化只须要实现 IClientStore 与 IScopeStore 的接口,能够本身实现,也能够直接使用 IdentityServer3 自身的扩展 IdentityServer3.EntityFramework 。html
核心类库
Install-Package IdentityServer3
IdentityServer 核心库,只支持基于内存的客户端信息与用户信息配置git
配置信息持久化
客户端,做用域,票据的持久化 ,支持的扩展有两个,一个基于 EF,另一个使用MongoDb(社区支持)
Install-Package IdentityServer3.EntityFramework
Install-Package IdentityServer.v3.MongoDbgithub
用户持久化redis
用户的持久化支持 MembershipReboot 与 ASP.NET Identity 两种
Install-Package IdentityServer3.MembershipReboot
Install-Package IdentityServer3.AspNetIdentitysql
其余插件数据库
WS-Federation
Install-Package IdentityServer3.WsFederation
Access token validation middleware(验证中间件)
Install-Package IdentityServer3.AccessTokenValidation缓存
国际化服务器
https://github.com/johnkors/IdentityServer3.Contrib.Localizationapp
缓存async
https://github.com/AliBazzi/IdentityServer3.Contrib.RedisStore
客户端
https://github.com/IdentityModel/IdentityModel2
客户端(clients)与做用域(scopes)的持久化
客户端与做用域的持久化只须要实现 IClientStore 与 IScopeStore 的接口,默认EF 在 IdentityServerServiceFactory 实现了 RegisterClientStore 与 RegisterScopeStore 两个扩展方法,也能够使用 RegisterConfigurationServices 方法,默认包含以上两个扩展方法合集;RegisterOperationalServices 扩展方法实现 IAuthorizationCodeStore, ITokenHandleStore, IRefreshTokenStore, and IConsentStore 功能等。
能够在 IdentityServer3.EntityFramework 的项目中找到数据库的初始SQL ,
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 = 60) { if (options == null) throw new ArgumentNullException("options"); if (interval < 1) 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); } } }
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, 20); 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 } }
客户端模式问题
REFER:
Deployment
https://identityserver.github.io/Documentation/docsv2/advanced/deployment.html