auth.liyouming.com 全部配

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); #region 業務數據庫 services.AddOptions(); services.AddDbContext<CustomContext>(builder => { builder.UseSqlServer(this.Configuration["ConnectionString"], options => { options.UseRowNumberForPaging(); options.MigrationsAssembly("LYM.OAuth2OpenId"); }); }, ServiceLifetime.Transient); #endregion #region IdentityServer4 By liyouming Add At 2017-11-28 //結合EFCore生成IdentityServer4數據庫 // 項目工程文件最后添加 <ItemGroup><DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /></ItemGroup> //dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb //dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb //黎又銘 Add 2017-11-28 添加IdentityServer4對EFCore數據庫的支持 //但是這里需要初始化數據 默認生成的數據庫中是沒有配置數據 const string connectionString = @"Data Source=192.168.0.42;Initial Catalog=A.IdentityServer4;User ID=sa;password=lym123!@#;Integrated Security=false;"; var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; string customUrl = this.Configuration["Authority"]; //"http://192.168.0.42:5000"; #region 添加對IdentiyServer4配置內容處理 By Liyouming 2017-11-29 services.AddIdentityServer(idroptions => { //設置將在發現文檔中顯示的頒發者名稱和已發布的JWT令牌。建議不要設置此屬性,該屬性從客戶端使用的主機名中推斷頒發者名稱 //idroptions.IssuerUri = ""; //設置認證 idroptions.Authentication = new IdentityServer4.Configuration.AuthenticationOptions { //監控瀏覽器cookie不難發現lym.Cookies=8660972474e55224ff37f7421c79a530 實際是cookie記錄服務器session的名稱 CheckSessionCookieName = "lym.SessionId", // CookieAuthenticationDefaults.AuthenticationScheme,//用於檢查會話端點的cookie的名稱 CookieLifetime = new TimeSpan(1, 0, 0),//身份驗證Cookie生存期(僅在使用IdentityServer提供的Cookie處理程序時有效) CookieSlidingExpiration = true,//指定cookie是否應該滑動(僅在使用IdentityServer提供的cookie處理程序時有效) RequireAuthenticatedUserForSignOutMessage = true //指示是否必須對用戶進行身份驗證才能接受參數以結束會話端點。默認為false }; //活動事件 允許配置是否應該將哪些事件提交給注冊的事件接收器 idroptions.Events = new IdentityServer4.Configuration.EventsOptions { RaiseErrorEvents = true, RaiseFailureEvents = true, RaiseSuccessEvents = true, RaiseInformationEvents = true }; //允許設置各種協議參數(如客戶端ID,范圍,重定向URI等)的長度限制 //idroptions.InputLengthRestrictions = new IdentityServer4.Configuration.InputLengthRestrictions //{ // //可以看出下面很多參數都是對長度的限制 // AcrValues = 100, // AuthorizationCode = 100, // ClientId = 100, // /* // .. // .. // .. // */ // ClientSecret = 1000 //}; //用戶交互頁面定向設置處理 idroptions.UserInteraction = new IdentityServer4.Configuration.UserInteractionOptions { LoginUrl = customUrl + "/Account/Login",//【必備】登錄地址 LogoutUrl = customUrl + "/Account/Logout",//【必備】退出地址 ConsentUrl = customUrl + "/Consent/Index",//【必備】允許授權同意頁面地址 ErrorUrl = customUrl + "/Error/Index", //【必備】錯誤頁面地址 LoginReturnUrlParameter = "returnUrl",//【必備】設置傳遞給登錄頁面的返回URL參數的名稱。默認為returnUrl LogoutIdParameter = "logoutId", //【必備】設置傳遞給注銷頁面的注銷消息ID參數的名稱。缺省為logoutId ConsentReturnUrlParameter = "returnUrl", //【必備】設置傳遞給同意頁面的返回URL參數的名稱。默認為returnUrl ErrorIdParameter = "errorId", //【必備】設置傳遞給錯誤頁面的錯誤消息ID參數的名稱。缺省為errorId CustomRedirectReturnUrlParameter = "returnUrl", //【必備】設置從授權端點傳遞給自定義重定向的返回URL參數的名稱。默認為returnUrl CookieMessageThreshold = 5 //【必備】由於瀏覽器對Cookie的大小有限制,設置Cookies數量的限制,有效的保證了瀏覽器打開多個選項卡,一旦超出了Cookies限制就會清除以前的Cookies值 }; //緩存參數處理 緩存起來提高了效率 不用每次從數據庫查詢 idroptions.Caching = new IdentityServer4.Configuration.CachingOptions { ClientStoreExpiration = new TimeSpan(1, 0, 0),//設置Client客戶端存儲加載的客戶端配置的數據緩存的有效時間 ResourceStoreExpiration = new TimeSpan(1, 0, 0),// 設置從資源存儲加載的身份和API資源配置的緩存持續時間 CorsExpiration = new TimeSpan(1, 0, 0) //設置從資源存儲的跨域請求數據的緩存時間 }; //IdentityServer支持一些端點的CORS。底層CORS實現是從ASP.NET Core提供的,因此它會自動注冊在依賴注入系統中 idroptions.Cors = new IdentityServer4.Configuration.CorsOptions { CorsPaths = new List<PathString>() { new PathString("/") }, //支持CORS的IdentityServer中的端點。默認為發現,用戶信息,令牌和撤銷終結點 CorsPolicyName = "default", //【必備】將CORS請求評估為IdentityServer的CORS策略的名稱(默認為"IdentityServer4")。處理這個問題的策略提供者是ICorsPolicyService在依賴注入系統中注冊的。如果您想定制允許連接的一組CORS原點,則建議您提供一個自定義的實現ICorsPolicyService PreflightCacheDuration = new TimeSpan(1, 0, 0)//可為空的<TimeSpan>,指示要在預檢Access-Control-Max-Age響應標題中使用的值。默認為空,表示在響應中沒有設置緩存頭 }; }) #endregion #region 添加IdentityServer4 認證證書相關處理 By Liyouming 2017-11-29 //AddSigningCredential 添加登錄證書 這個是掛到IdentityServer4中間件上 提供多種證書處理 RsaSecurityKey\SigningCredentials //這里可以采用IdentiServe4的證書封裝出來 //添加一個簽名密鑰服務,該服務將指定的密鑰材料提供給各種令牌創建/驗證服務。您可以從證書存儲中傳入X509Certificate2一個SigningCredential或一個證書引用 //.AddSigningCredential(new System.Security.Cryptography.X509Certificates.X509Certificate2() //{ // Archived = true, // FriendlyName = "", // PrivateKey = System.Security.Cryptography.AsymmetricAlgorithm.Create("key") //}) //AddDeveloperSigningCredential在啟動時創建臨時密鑰材料。這是僅用於開發場景,當您沒有證書使用。 //生成的密鑰將被保存到文件系統,以便在服務器重新啟動之間保持穩定(可以通過傳遞來禁用false)。 //這解決了在開發期間client / api元數據緩存不同步的問題 .AddDeveloperSigningCredential() //添加驗證令牌的密鑰。它們將被內部令牌驗證器使用,並將顯示在發現文檔中。 //您可以從證書存儲中傳入X509Certificate2一個SigningCredential或一個證書引用。這對於關鍵的轉換場景很有用 //.AddValidationKeys(new AsymmetricSecurityKey[] { //}) #endregion #region 添加IdentityServer4用戶緩存數據 By Liyouming 2017-11-29 //添加配置數據全部配置到內存中 如果有EFCore數據庫持久化這里不會配置 只需要配置 AddConfigurationStore、AddOperationalStore 數據倉儲服務 //寄存器IClientStore和ICorsPolicyService實現基於內存中的Client配置對象集合。 //.AddInMemoryClients(IdrConfig.IdrConfigurations.GetClient()) //IResourceStore基於IdentityResource配置對象的內存中收集來注冊實現。 //.AddInMemoryIdentityResources(IdrConfig.IdrConfigurations.GetIdentityResources()) //IResourceStore基於ApiResource配置對象的內存中收集來注冊實現。 //.AddInMemoryApiResources(IdrConfig.IdrConfigurations.GetApiResources()) //添加測試用戶 //.AddTestUsers(new List<IdentityServer4.Test.TestUser>() { // new IdentityServer4.Test.TestUser{ // SubjectId=Guid.NewGuid().ToString(), // Username="liyouming", // Password="liyouming" // } //}) #endregion #region 添加對IdentityServer4 EF數據庫持久化支持 By Liyouming 2017-11-29 //黎又銘 Add 2017-11-28 添加IdentityServer4對EFCore數據庫的支持 .AddConfigurationStore(options => { options.ConfigureDbContext = builder => { builder.UseSqlServer(connectionString, builderoptions => { builderoptions.MigrationsAssembly(migrationsAssembly); }); }; }) .AddOperationalStore(options => { options.ConfigureDbContext = builder => { builder.UseSqlServer(connectionString, builderoptions => { builderoptions.MigrationsAssembly(migrationsAssembly); }); }; options.EnableTokenCleanup = true; //允許對Token的清理 options.TokenCleanupInterval = 1800; //清理周期時間Secends }) #endregion ; #endregion //services.AddScoped<IUserService, UserService>(); #region 添加授權驗證方式 這里是Cookies & OpenId Connect JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication( options => { options.DefaultScheme = "lym.oauth.cookies"; options.DefaultChallengeScheme = "oidc"; } ) .AddCookie("lym.oauth.cookies", options=> { options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.Cookie.Name = "lym.idrserver"; }) //監控瀏覽器Cookies不難發現有這樣一個 .AspNetCore.lym.Cookies 記錄了加密的授權信息 .AddOpenIdConnect("oidc", options => { options.Authority = customUrl; options.ClientId = "lym.clienttest"; options.ClientSecret = "lym.clienttest"; options.RequireHttpsMetadata = false; options.SaveTokens = true; options.ResponseType = "code id_token"; //布爾值來設置處理程序是否應該轉到用戶信息端點檢索。額外索賠或不在id_token創建一個身份收到令牌端點。默認為“false” options.GetClaimsFromUserInfoEndpoint = true; options.CallbackPath = new PathString("/oidc/login-callback"); options.SignInScheme = "lym.oauth.cookies"; options.SignOutScheme = "lym.oauth.cookies"; options.RemoteSignOutPath = new PathString("/oidc/front-channel-logout-callback"); options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("cloudservices"); options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = OnRedirectToIdentityProvider, OnRemoteSignOut = OnRemoteSignOut, OnRemoteFailure = OnRemoteFailure, OnAuthenticationFailed = OnAuthenticationFailed, OnRedirectToIdentityProviderForSignOut = OnRedirectToIdentityProviderForSignOut, OnAuthorizationCodeReceived = OnAuthorizationCodeReceived, OnMessageReceived = OnMessageReceived, OnTicketReceived = OnTicketReceived, OnTokenResponseReceived = OnTokenResponseReceived, OnTokenValidated = OnTokenValidated, OnUserInformationReceived = OnUserInformationReceived }; }); #endregion } #region Events事件 private static Task OnRedirectToIdentityProvider(RedirectContext context) { if (context.HttpContext.Items.ContainsKey("idp")) { var idp = context.HttpContext.Items["idp"]; context.ProtocolMessage.AcrValues = "idp:" + idp; } return Task.FromResult(0); } private static Task OnRemoteSignOut(RemoteSignOutContext context) { return Task.FromResult(0); } private static Task OnRemoteFailure(RemoteFailureContext context) { return Task.FromResult(0); } private static Task OnAuthenticationFailed(AuthenticationFailedContext context) { return Task.FromResult(0); } private static Task OnRedirectToIdentityProviderForSignOut(RedirectContext context) { context.ProtocolMessage.PostLogoutRedirectUri = context.Request.Scheme + "://" + context.Request.Host; return Task.FromResult(0); } private static Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) { return Task.FromResult(0); } private static Task OnMessageReceived(MessageReceivedContext context) { return Task.FromResult(0); } private static Task OnTicketReceived(TicketReceivedContext context) { return Task.FromResult(0); } private static Task OnTokenResponseReceived(TokenResponseReceivedContext context) { return Task.FromResult(0); } private static Task OnTokenValidated(TokenValidatedContext context) { return Task.FromResult(0); } private static Task OnUserInformationReceived(UserInformationReceivedContext context) { return Task.FromResult(0); } #endregion public void ConfigureContainer(ContainerBuilder builder) { //Autofac 注入 builder.RegisterInstance(this.Configuration).AsImplementedInterfaces(); //builder.RegisterType<RedisProvider>().As<IRedisProvider>().SingleInstance(); builder.AddUnitOfWork(provider => { provider.Register(new LYM.Data.EntityFramework.ClubUnitOfWorkRegisteration()); }); builder.RegisterModule<CoreModule>() .RegisterModule<EntityFrameworkModule>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseAuthentication(); app.UseStaticFiles(); app.UseIdentityServer(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); // app.UseMvcWithDefaultRoute(); } }
web.liyouming.com 全部配置

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { #region 數據庫連接 string customUrl = this.Configuration["Authority"]; services.AddMvc(); services.AddOptions(); services.AddDbContext<CustomContext>(builder => { builder.UseSqlServer(this.Configuration["ConnectionString"], options => { options.UseRowNumberForPaging(); options.MigrationsAssembly("LYM.WebSite"); }); }, ServiceLifetime.Transient); #endregion #region 添加授權驗證方式 這里是Cookies & OpenId Connect JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication( options => { options.DefaultScheme = "lym.oauth.cookies";// CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = "oidc"; } ) .AddCookie("lym.oauth.cookies", options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.Cookie.Name = "lym.website"; }) //監控瀏覽器Cookies不難發現有這樣一個 .AspNetCore.lym.Cookies 記錄了加密的授權信息 .AddOpenIdConnect("oidc", options => { options.Authority = customUrl; options.ClientId = "lym.clienttest1"; options.ClientSecret = "lym.clienttest"; options.RequireHttpsMetadata = false; options.SaveTokens = true; options.ResponseType = "code id_token"; //布爾值來設置處理程序是否應該轉到用戶信息端點檢索。額外索賠或不在id_token創建一個身份收到令牌端點。默認為“false” options.GetClaimsFromUserInfoEndpoint = true; options.CallbackPath = new PathString("/oidc/login-callback"); options.SignInScheme = "lym.oauth.cookies"; options.SignOutScheme = "lym.oauth.cookies"; options.RemoteSignOutPath = new PathString("/oidc/front-channel-logout-callback"); options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("cloudservices"); options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = OnRedirectToIdentityProvider, OnRemoteSignOut = OnRemoteSignOut, OnRemoteFailure = OnRemoteFailure, OnAuthenticationFailed = OnAuthenticationFailed, OnRedirectToIdentityProviderForSignOut = OnRedirectToIdentityProviderForSignOut, OnAuthorizationCodeReceived = OnAuthorizationCodeReceived, OnMessageReceived = OnMessageReceived, OnTicketReceived = OnTicketReceived, OnTokenResponseReceived = OnTokenResponseReceived, OnTokenValidated = OnTokenValidated, OnUserInformationReceived = OnUserInformationReceived }; }); #endregion #region Cap配置 //services.AddDbContext<CapApiContext>(builder => //{ // builder.UseSqlServer(this.Configuration["CapConnectionString"]); //}, ServiceLifetime.Transient); //services.AddCap(x => //{ // //EF實體框架 // x.UseEntityFramework<CapApiContext>(); // // Dapper // // x.UseSqlServer("Your ConnectionStrings"); // // RabbitMQ 消息 // //x.UseRabbitMQ(rabbitMQOption => // //{ // // #region UseRabbitMQ 參數說明 // // //HostName 宿主地址 string localhost // // //UserName 用戶名 string guest // // //Password 密碼 string guest // // //VirtualHost 虛擬主機 string / // // //Port 端口號 int -1 // // //TopicExchangeName CAP默認Exchange名稱 string cap.default.topic // // //RequestedConnectionTimeout RabbitMQ連接超時時間 int 30,000 毫秒 // // //SocketReadTimeout RabbitMQ消息讀取超時時間 int 30,000 毫秒 // // //SocketWriteTimeout RabbitMQ消息寫入超時時間 int 30,000 毫秒 // // //QueueMessageExpires 隊列中消息自動刪除時間 int(10天) 毫秒 // // #endregion // // rabbitMQOption.HostName = "192.168.0.42"; // // //rabbitMQOption.VirtualHost = "/rabbit"; // // //rabbitMQOption.UserName = "lym123"; // // //rabbitMQOption.Password = "lym123"; // // rabbitMQOption.Port = 5672; // // // rabbitmq options. // //}); // x.UseRabbitMQ("localhost"); // // Kafka 消息 // // x.UseKafka("localhost:5003"); // // 執行失敗消息時的回調函數,詳情見下文 Action<MessageType,string,string> // //x.FailedCallback = null; // //處理消息的線程默認輪詢等待時間(秒) 15 秒 // x.PollingDelay = 15; // //啟動隊列中消息的處理器個數 2 // x.QueueProcessorCount = 2; // //失敗重試次數 // x.FailedRetryCount = 3; // //失敗重試時間間隔 // x.FailedRetryInterval = 15; //}); #endregion } #region Events事件 private static Task OnRedirectToIdentityProvider(RedirectContext context) { if (context.HttpContext.Items.ContainsKey("idp")) { var idp = context.HttpContext.Items["idp"]; context.ProtocolMessage.AcrValues = "idp:" + idp; } return Task.FromResult(0); } private static Task OnRemoteSignOut(RemoteSignOutContext context) { return Task.FromResult(0); } private static Task OnRemoteFailure(RemoteFailureContext context) { return Task.FromResult(0); } private static Task OnAuthenticationFailed(AuthenticationFailedContext context) { return Task.FromResult(0); } private static Task OnRedirectToIdentityProviderForSignOut(RedirectContext context) { context.ProtocolMessage.PostLogoutRedirectUri = context.Request.Scheme + "://" + context.Request.Host; return Task.FromResult(0); } private static Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) { return Task.FromResult(0); } private static Task OnMessageReceived(MessageReceivedContext context) { return Task.FromResult(0); } private static Task OnTicketReceived(TicketReceivedContext context) { return Task.FromResult(0); } private static Task OnTokenResponseReceived(TokenResponseReceivedContext context) { return Task.FromResult(0); } private static Task OnTokenValidated(TokenValidatedContext context) { return Task.FromResult(0); } private static Task OnUserInformationReceived(UserInformationReceivedContext context) { return Task.FromResult(0); } #endregion public void ConfigureContainer(ContainerBuilder builder) { //Autofac 注入 builder.RegisterInstance(this.Configuration).AsImplementedInterfaces(); //builder.RegisterType<RedisProvider>().As<IRedisProvider>().SingleInstance(); builder.AddUnitOfWork(provider => { provider.Register(new LYM.Data.EntityFramework.ClubUnitOfWorkRegisteration()); }); builder.RegisterModule<CoreModule>() .RegisterModule<EntityFrameworkModule>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); // app.UseCap(); //Cap配置 } }
centos7.0 環境
SSO登錄,SSO退出 搞定
下面是登錄視頻演示:
項目目錄結構