一步一步學習IdentityServer4 (7) IdentityServer4成功配置全部配置


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();


        }
    }
auth.liyouming.com

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配置
        }
    }
web.liyouming.com

 

centos7.0 環境 

 

 

 

 SSO登錄,SSO退出 搞定

下面是登錄視頻演示:

 

項目目錄結構

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM