Esempio n. 1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            var a = OpenIdConnectDefaults.DisplayName; //OpenIdConnect

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = "Cookies";
                //默认,没有登陆走oidc处理,即下面的OpenID Connect
                options.DefaultChallengeScheme = OpenIdConnectDefaults.DisplayName;
                //options.DefaultChallengeScheme = "oidc";
                //options.DefaultAuthenticateScheme = "oidc";
            })
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddOpenIdConnect(OpenIdConnectDefaults.DisplayName, "OpenID Connect", options =>
            {
                options.SignInScheme = "Cookies";
                //options.SignInScheme = OpenIdConnectDefaults.DisplayName;
                options.Authority            = "http://192.168.1.102:5001"; //授权服务器地址
                options.RequireHttpsMetadata = false;
                options.ClientId             = "oidc";
                options.ClientSecret         = "secret";
                options.SaveTokens           = true;
                //options.Scope.Add("openid");
                //options.Scope.Add("profile");
                //options.Scope.Add("email");
                options.Scope.Add("offline_access");
                options.Scope.Add("OtherInfo");                        //api权限
                options.ResponseType = OpenIdConnectResponseType.Code; // "id_token code";// OpenIdConnectResponseType.CodeIdToken;

                //注册事件
                options.Events = new OpenIdConnectEvents
                {
                    /*
                     * 远程异常触发
                     * 在授权服务器取消登陆或者取消授权
                     */
                    OnRemoteFailure = OAuthFailureHandler =>
                    {
                        //跳转首页
                        OAuthFailureHandler.Response.Redirect("/");
                        OAuthFailureHandler.HandleResponse();
                        return(Task.FromResult(0));
                    },
                };
            });
        }
Esempio n. 2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            //配置DbContext
            services.AddDbContext <ApplicationDbContext>(options =>
            {
                //配置文件前面必须是;ConnectionStrings
                //因为默认是:GetSection("ConnectionStrings")[name].
                options.UseSqlServer(Configuration.GetConnectionString("conn"));
                //options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
            });
            services.AddIdentity <ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores <ApplicationDbContext>()
            .AddDefaultTokenProviders();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);


            //依赖注入初始化
            services.AddAuthentication(options =>
            {
                /*
                 * 要想使用认证系统,必要先注册Scheme
                 * 而每一个Scheme必须指定一个Handler
                 * AuthenticationHandler 负责对用户凭证的验证
                 * 这里指定的默认认证是cookie认证
                 * Scheme可以翻译为方案,即默认的认证方案
                 *
                 * 因为这里用到了多个中间件,(AddAuthentication,AddCookie,AddOpenIdConnect)
                 * OpenIdConnectDefaults.DisplayName 的默认值是oidc
                 * 指定AddOpenIdConnect是默认中间件,在AddOpenIdConnect配置了很多选项
                 *
                 * 如果只用了一个中间件,则可以不写,是否还记得cookie认证
                 * //     services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                 * //     .AddCookie(option =>
                 * //     {
                 * //         ///Account/Login?ReturnUrl=%2Fadmin
                 * //         option.LoginPath = "/login/index";
                 * //         //option.ReturnUrlParameter = "params"; //指定参数名称
                 * //         //option.Cookie.Domain
                 * //         option.AccessDeniedPath = "/login/noAccess";
                 * //         option.Cookie.Expiration = TimeSpan.FromSeconds(4);
                 * //         option.Events = new CookieAuthenticationEvents
                 * //         {
                 * //             OnValidatePrincipal = LastChangedValidator.ValidateAsync
                 * //         };
                 * //     });
                 *
                 */

                //options.DefaultScheme = "Cookies";

                //默认的认证方案:cookie认证,信息是保存在cookie中的
                options.DefaultAuthenticateScheme = "Cookies";
                //oidc 就是openidConnect


                //名字随便取,只要AddOpenIdConnect中的的oidc名字一样即可,
                //这样才能找到,默认使用oidc
                //options.DefaultChallengeScheme = "oidc";

                /*
                 * 但我想,我的的网站没有登陆,跳转到自己的登陆页面,
                 * 但用户可以指定第三方登陆,所以,这样不使用oidc,用的时候指定
                 * 使用myCookies中间件
                 */
                options.DefaultChallengeScheme = "Cookies";



                //options.DefaultChallengeScheme = "oidc";
                //默认使用oidc中间件
                //options.DefaultChallengeScheme = OpenIdConnectDefaults.DisplayName;
            })
            .AddCookie("Cookies", options =>
            {
                options.LoginPath = "/Account/Login";
            })
            .AddOAuth("OAuth", options =>
            {
                options.SignInScheme          = "Cookies";
                options.ClientId              = "OAuth.Client";
                options.ClientSecret          = "secret";
                options.AuthorizationEndpoint = "http://localhost:5003/connect/authorize";
                options.TokenEndpoint         = "http://localhost:5003/connect/token";
                options.CallbackPath          = new PathString("/OAuth");
                options.SaveTokens            = true;
                options.Scope.Add("OAuth1");
                options.Scope.Add("OAuth2");
                options.Scope.Add("OAuth3");
                //options.Scope.Add("offline_access");
                options.Events = new OAuthEvents()
                {
                    //远程异常触发
                    OnRemoteFailure = OAuthFailureHandler =>
                    {
                        //var msg = OAuthFailureHandler.Failure.Message;
                        var authProperties = options.StateDataFormat.Unprotect(OAuthFailureHandler.Request.Query["state"]);
                        var redirectUrl    = authProperties.RedirectUri;
                        if (redirectUrl.Contains("/"))
                        {
                            redirectUrl = string.Format($"{redirectUrl.Substring(0, redirectUrl.LastIndexOf("/") + 1)}#");// redirectUrl.Substring(0, redirectUrl.IndexOf("/") + 1);
                        }
                        //"http://localhost:5001/#"
                        OAuthFailureHandler.Response.Redirect(redirectUrl);
                        OAuthFailureHandler.HandleResponse();
                        return(Task.FromResult(0));
                    }
                };
            })
            //.AddGoogle("googole", options => {
            //    options.ClientId = "";
            //    options.ClientSecret = "";

            //})
            .AddOpenIdConnect("oidc", "OpenID Connect", options =>
            {
                //options.SignOutScheme = OpenIdConnectDefaults.DisplayName;
                options.SignInScheme = "Cookies";

                //options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                //options.SignOutScheme = IdentityServerConstants.SignoutScheme;


                //默认值start
                //options.CallbackPath = new PathString("/signin-oidc");
                //options.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
                //options.RemoteSignOutPath = new PathString("/signout-oidc");
                //options.Scope.Add("openid");
                //options.Scope.Add("profile");
                //options.ResponseMode = OpenIdConnectResponseMode.FormPost;
                //默认值end


                options.Authority            = "http://localhost:5003";
                options.RequireHttpsMetadata = false;
                options.ClientId             = "oidc";
                options.ClientSecret         = "secret";
                options.SaveTokens           = true;

                /*
                 * 这样会去请求UserInfoEndpoint获取到信息后绑定到User.Claims
                 * 同时access_token也会有
                 */
                //options.GetClaimsFromUserInfoEndpoint = true;
                //options.ClaimActions.MapJsonKey("sub", "sub");
                //options.ClaimActions.MapJsonKey("preferred_username", "preferred_username");
                //options.ClaimActions.MapJsonKey("avatar", "avatar");
                //options.ClaimActions.MapCustomJson("role", job => job["role"].ToString());
                ////////////////////////////////////

                //options.Scope.Add("OAuth1");
                options.Scope.Add("offline_access");
                options.Scope.Add("OtherInfo");
                options.Scope.Add("email");

                /*
                 * 默认值是:id_token
                 */
                options.ResponseType = "id_token code";// OpenIdConnectResponseType.CodeIdToken;
                options.Events       = new OpenIdConnectEvents
                {
                    //OnMessageReceived = received => {
                    //    received.HttpContext.ChallengeAsync("oidc");
                    //    received.HandleResponse();
                    //    return Task.FromResult(0);
                    //},
                    //OnRedirectToIdentityProviderForSignOut = re => {
                    //    var ck =await re.HttpContext.AuthenticateAsync();


                    //},

                    /*
                     * 远程异常触发
                     * 在授权服务器取消登陆或者取消授权
                     */
                    OnRemoteFailure = OAuthFailureHandler =>
                    {
                        //跳转首页
                        OAuthFailureHandler.Response.Redirect("/");
                        OAuthFailureHandler.HandleResponse();
                        return(Task.FromResult(0));
                    },
                    //未授权时,重定向到OIDC服务器时触发
                    //OnRedirectToIdentityProvider = identity => {
                    //    //这里不跳转到授权服务器,跳转到登陆页面
                    //    identity.Response.Redirect("/Account");
                    //    identity.HandleResponse();
                    //    return Task.FromResult(0);
                    //}
                };
            });

            #region OAuth认证
            //services.AddAuthentication(options =>
            //{
            //    //options.DefaultAuthenticateScheme=OAuthDefaults.DisplayName
            //    //options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            //    options.DefaultAuthenticateScheme = "Cookies";
            //    options.DefaultSignInScheme = "Cookies";
            //    //options.DefaultSignOutScheme = "Cookies";
            //    options.DefaultChallengeScheme = "OAuth";
            //})
            //.AddCookie()
            //.AddOAuth("OAuth", options =>
            //{
            //    options.ClientId = "OAuth.Client";
            //    options.ClientSecret = "secret";
            //    options.AuthorizationEndpoint = "http://localhost:5003/connect/authorize";
            //    options.TokenEndpoint = "http://localhost:5003/connect/token";
            //    options.CallbackPath = new PathString("/OAuth");
            //    options.SaveTokens = true;
            //    options.Scope.Add("OAuth1");
            //    options.Scope.Add("OAuth2");
            //    options.Scope.Add("OAuth3");
            //    //options.Scope.Add("offline_access");
            //    options.Events = new OAuthEvents()
            //    {
            //        //OnRedirectToAuthorizationEndpoint = t =>
            //        //{
            //        //    t.Response.Redirect("http://localhost:5001/Account/userinfo");
            //        //    return Task.FromResult(0);
            //        //},

            //        //远程异常触发
            //        OnRemoteFailure = OAuthFailureHandler =>
            //        {
            //            //var msg = OAuthFailureHandler.Failure.Message;
            //            var authProperties = options.StateDataFormat.Unprotect(OAuthFailureHandler.Request.Query["state"]);
            //            var redirectUrl = authProperties.RedirectUri;
            //            if (redirectUrl.Contains("/"))
            //            {
            //                redirectUrl = string.Format($"{redirectUrl.Substring(0, redirectUrl.LastIndexOf("/") + 1)}#");// redirectUrl.Substring(0, redirectUrl.IndexOf("/") + 1);
            //            }
            //            //"http://localhost:5001/#"
            //            OAuthFailureHandler.Response.Redirect(redirectUrl);
            //            OAuthFailureHandler.HandleResponse();
            //            return Task.FromResult(0);
            //        }
            //    };


            //});
            #endregion
        }
Esempio n. 3
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region 解释记载
            // services.AddAuthentication(option =>
            // {
            //     /*
            //      要想使用认证系统,必要先注册Scheme
            //      而每一个Scheme必须指定一个Handler
            //      AuthenticationHandler 负责对用户凭证的验证
            //      这里指定的默认认证是cookie认证
            //      Scheme可以翻译为方案,即默认的认证方案
            //      */
            //     option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            //     //option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            //     //option.DefaultChallengeScheme = OAuthDefaults.DisplayName;

            //     /*
            //      因为这里用到了多个中间件,(AddAuthentication,AddCookie,AddOAuth)
            //      所以要设置一个默认中间件OAuthDefaults.DisplayName 的默认值是OAuth
            //      指定AddOAuth是默认中间件,在AddOAuth配置了很多选项

            //     如果只用了一个中间件,则可以不写,是否还记得cookie认证
            //     services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            //     .AddCookie(option =>
            //     {
            //         ///Account/Login?ReturnUrl=%2Fadmin
            //         option.LoginPath = "/login/index";
            //         //option.ReturnUrlParameter = "params"; //指定参数名称
            //         //option.Cookie.Domain
            //         option.AccessDeniedPath = "/login/noAccess";
            //         option.Cookie.Expiration = TimeSpan.FromSeconds(4);
            //         option.Events = new CookieAuthenticationEvents
            //         {
            //             OnValidatePrincipal = LastChangedValidator.ValidateAsync
            //         };
            //     });
            //      */
            //     option.DefaultChallengeScheme = OAuthDefaults.DisplayName;
            // })
            //.AddCookie()
            //.AddOAuth(OAuthDefaults.DisplayName,
            //option => {
            //    option.ClientId = "oauth";
            //    option.ClientSecret = "secret";
            //    option.AuthorizationEndpoint = "http://localhost:5000/connect/authorize";
            //    option.TokenEndpoint = "http://localhost:5000/connect/token";
            //    option.CallbackPath = "/signin-oauth";
            //     //option.Scope.Clear();
            //     option.Scope.Add("api");
            //     // 事件执行顺序 :
            //     // 1.创建Ticket之前触发
            //     //option.Events.OnCreatingTicket = context => Task.CompletedTask;
            //     // 2.创建Ticket失败时触发
            //     //option.Events.OnRemoteFailure = context => Task.CompletedTask;
            //     // 3.Ticket接收完成之后触发
            //     //option.Events.OnTicketReceived = context => Task.CompletedTask;
            //     // 4.Challenge时触发,默认跳转到OAuth服务器
            //     // options.Events.OnRedirectToAuthorizationEndpoint = context => context.Response.Redirect(context.RedirectUri);
            // });
            #endregion

            services.AddMvc();

            services.AddAuthentication(options =>
            {
                //options.DefaultAuthenticateScheme=OAuthDefaults.DisplayName
                //options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultAuthenticateScheme = "Cookies";
                options.DefaultSignInScheme       = "Cookies";
                options.DefaultChallengeScheme    = "OAuth";
            })
            .AddCookie()
            .AddOAuth("OAuth", optins =>
            {
                optins.ClientId              = "OAuth.Client";
                optins.ClientSecret          = "secret";
                optins.AuthorizationEndpoint = "http://localhost:5000/connect/authorize";
                optins.TokenEndpoint         = "http://localhost:5000/connect/token";
                optins.SaveTokens            = true;
                optins.CallbackPath          = "/Account/PostAuthorize";
                optins.Scope.Add("OAuth1");
                optins.Scope.Add("OAuth2");
                optins.Scope.Add("OAuth3");

                optins.Events = new OAuthEvents()
                {
                    //OnRemoteFailure = HandleOnRemoteFailure,

                    //远程异常触发
                    OnRemoteFailure = OAuthFailureHandler =>
                    {
                        var msg            = OAuthFailureHandler.Failure.Message;
                        var authProperties = optins.StateDataFormat.Unprotect(OAuthFailureHandler.Request.Query["state"]);

                        var redirectUrl = authProperties.RedirectUri;
                        if (redirectUrl.Contains("/"))
                        {
                            redirectUrl = string.Format($"{redirectUrl.Substring(0, redirectUrl.LastIndexOf("/") + 1)}#");// redirectUrl.Substring(0, redirectUrl.IndexOf("/") + 1);
                        }
                        //"http://localhost:5001/#"
                        OAuthFailureHandler.Response.Redirect(redirectUrl);
                        OAuthFailureHandler.HandleResponse();
                        return(Task.FromResult(0));
                    }
                };
            });
        }
Esempio n. 4
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //    services
            //.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            /*
             * 注意:注册的更好方法IHttpContextAccessor是调用AddHttpContextAccessor Extension方法,
             */
            //services.AddHttpContextAccessor();

            //services.AddHttpClient();
            //services.Configure<AuthServiceSettings>(Configuration);

            //services.add
            services.AddSingleton(serviceProvider =>
            {
                var configuration = serviceProvider.GetRequiredService <IConfiguration>();
                return(configuration.GetSection("AuthServiceSettings"));
            });

            services.AddSingleton <IDiscoveryCache>(serviceProvider =>
            {
                //var authServiceConfig = serviceProvider.GetRequiredService<AuthServiceSettings>();
                //var factory = serviceProvider.GetRequiredService<IHttpClientFactory>();
                //return new DiscoveryCache(authServiceConfig.Authority, () => factory.CreateClient());

                //var factory = serviceProvider.GetRequiredService<IHttpClientFactory>();
                return(new DiscoveryCache("http://localhost:5008"));
            });

            services
            .AddTransient <CustomCookieAuthenticationEvents>()
            .AddTransient <ITokenRefresher, TokenRefresher>()
            .AddTransient <AccessTokenHttpMessageHandler>()
            .AddTransient <HttpClient>()
            .AddHttpContextAccessor();

            //services
            //    .AddHttpClient<ITokenRefresher, TokenRefresher>();


            //JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            /*
             * Add-Migration init -Context InfoDbContext
             * Update-Database -Context InfoDbContext
             */
            var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

            services.AddControllersWithViews();
            services.AddDbContext <InfoDbContext>(_ =>
            {
                _.UseSqlServer(Configuration.GetConnectionString("InfoDb"));
            });
            var oidc   = OpenIdConnectDefaults.DisplayName; //OpenIdConnect
            var cookie = CookieAuthenticationDefaults.AuthenticationScheme;

            services.AddAuthentication(options =>
            {
                /*
                 * 使用cookie作为本地登录用户
                 */
                options.DefaultScheme = cookie;

                /*
                 * 当需要用户登录时,我们将使用cookie协议
                 * 将会执行AddCookie()的处理程序
                 */
                options.DefaultChallengeScheme = cookie;

                /*
                 * 指定oidc为默认登录方式
                 * 也就是说没有授权则执行oidc的Handler
                 */
                //options.DefaultChallengeScheme = "oidc";

                //options.DefaultAuthenticateScheme = "Cookies";
                //默认,没有登陆走oidc处理,即下面的OpenID Connect
                //options.DefaultChallengeScheme = OpenIdConnectDefaults.DisplayName;
                //options.DefaultChallengeScheme = "oidc";
                //options.DefaultAuthenticateScheme = "oidc";
            })
            .AddCookie(cookie, options =>
            {
                /*
                 * 第三方登录成功,没有设置cookie过期时间
                 * 那么该cookie是会话级别的。即。浏览器不关闭,会一直在线
                 */
                options.LoginPath = "/account";
                //options.ExpireTimeSpan = TimeSpan.FromSeconds(30);
                //options.EventsType = typeof(CustomCookieAuthenticationEvents);
            })
            // .AddMicrosoftAccount(microsoftOptions =>
            //{
            //    //https://www.netnr.com/home/list/109
            //    microsoftOptions.ClientId = Configuration["Authentication:Microsoft:ClientId"];
            //    microsoftOptions.ClientSecret = Configuration["Authentication:Microsoft:ClientSecret"];
            //})
            .AddGitHub(GitHubDefaults.AuthenticationScheme, GitHubDefaults.DisplayName, options =>
            {
                options.ClientId     = "8b4e1c7979b3b9705109";
                options.ClientSecret = "643aa3afb7b5a5d7e38685dd8be308278fc506d5";
            })
            //.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,options =>
            //{
            //    //options.LoginPath = new PathString(Constants.SignIn);
            //    //options.LogoutPath = new PathString(Constants.SignOut);
            //    options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
            //})
            //.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            //openid connect协议的处理程序
            .AddOpenIdConnect(oidc, "OpenID Connect", options =>
            {
                var authServiceConfig = Configuration.Get <AuthServiceSettings>();
                var app = Configuration.Get <AuthServiceSettings>();

                //options.SignInScheme = "Cookies";
                //options.SignInScheme = OpenIdConnectDefaults.DisplayName;
                options.Authority            = "http://localhost:5008"; //授权服务器地址
                options.RequireHttpsMetadata = false;
                options.ClientId             = "5440496238";
                options.ClientSecret         = "saQR67zTYy";
                //来自identityserver的令牌持久化在cookie中
                options.SaveTokens = true;

                /*
                 * 指示身份验证会话生存期(例如cookies)应匹配
                 *
                 * 身份验证令牌的。如果令牌不提供生存期信息
                 *
                 * 然后将使用正常会话生存期。这在默认情况下是禁用的。
                 */
                //options.UseTokenLifetime = true;
                // options.JwtValidationClockSkew = TimeSpan.FromSeconds(0);


                //options.AccessDeniedPath = "";
                //options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                //{

                //};
                //options.Scope.Clear(); //这会删除所有默认的scope

                //options.AccessDeniedPath //定义远程登录取消页面??
                //options.Scope.Add("openid");
                //options.Scope.Add("profile");

                //向服务器发起,我想要的权限和用户信息,前提的服务器允许
                //options.Scope.Add("email");
                options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess);
                //options.Scope.Add("offline_access");

                options.Scope.Add("comment"); //api权限
                //options.Scope.Add("info");
                //options.ResponseType = OpenIdConnectResponseType.Code;// "id_token code";// OpenIdConnectResponseType.CodeIdToken;
                //或者
                options.ResponseType = ResponseTypes.Code;

                /*
                 * 这样会去请求UserInfoEndpoint获取到信息后绑定到access_token中
                 */
                options.GetClaimsFromUserInfoEndpoint = true;

                /*
                 * 通过ClaimActions.MapJsonKey("自定义key名","JwtClaimTypes.Subject")
                 * 把ProfileService返回的Claims映射到User.Claims
                 * 前提是GetClaimsFromUserInfoEndpoint=true
                 */
                options.ClaimActions.MapJsonKey("sub89", "sub");
                options.ClaimActions.MapJsonKey("subject", JwtClaimTypes.Subject);
                //options.ClaimActions.MapJsonKey("preferred_username", "preferred_username");
                //options.ClaimActions.MapJsonKey("email", "email");
                //options.ClaimActions.MapJsonKey("name", "name");
                options.ClaimActions.MapCustomJson("role", jobject => jobject.GetString("role"));
                options.ClaimActions.MapCustomJson("所有Claim", all => all.ToString());
                //options.CallbackPath = $"/signin-oidc-{provider.Key}";
                //options.SignedOutCallbackPath = $"/signout-callback-oidc-{provider.Key}";
                //options.SignedOutCallbackPath = "/signin-oidc/home";
                //注册事件
                options.Events = new OpenIdConnectEvents
                {
                    /*
                     * 远程异常触发
                     * 在授权服务器取消登陆或者取消授权
                     */
                    OnRemoteFailure = OAuthFailureHandler =>
                    {
                        //跳转首页
                        OAuthFailureHandler.Response.Redirect("/");
                        OAuthFailureHandler.HandleResponse();
                        return(Task.FromResult(0));
                    },
                    //https://blog.codingmilitia.com/2019/06/22/aspnet-024-from-zero-to-overkill-integrating-identityserver4-part4-back-for-front
                    //在重定向到身份提供程序进行身份验证之前调用
                    //OnRedirectToIdentityProvider = context =>
                    //{
                    //    /*
                    //     如果是SPA页面,直接请求某个页面,可以捕获
                    //     */
                    //    if (!context.HttpContext.Request.Path.StartsWithSegments("/auth/login"))
                    //    {
                    //        context.HttpContext.Response.StatusCode = 401;
                    //        context.HandleResponse();
                    //    }
                    //    return Task.CompletedTask;
                    //}
                };
            });
        }