OWIN如何配置/ signout-oidc删除cookie

时间:2019-06-06 14:26:41

标签: c# .net owin openid oidc

我正在创建由个人运行的OIDC服务器授权的应用程序。 服务器使用Openiddict库,而应用程序使用OWIN进行配置。这是因为OIDC服务器在.Net核心上运行,而应用程序在.Net框架上运行。

当尝试从这些应用程序注销时,我重定向到OIDC服务器/ Account / Logout,这将依次获取所有已登录的应用程序,并使用前通道注销URL(/ signout-oidc)打开iframe。 / p>

注销时,它将显示未找到404,表示尚未创建网址“ example.com/signout-oidc”。

该应用程序使用的库为:

  • Microsoft.Owin.Security
  • Microsoft.Owin.Security.Cookies
  • Microsoft.Owin.Security.OpenIdConnect
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.Use(async (Context, next) =>
            {
                Debug.WriteLine("1 ==>request, before cookie auth");
                await next.Invoke();
                Debug.WriteLine("6 <==response, after cookie auth");
            });

            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.Use(async (Context, next) =>
            {
                Debug.WriteLine("2 ==>after cookie, before OIDC");
                await next.Invoke();
                Debug.WriteLine("5 <==after OIDC");
            });

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions()
                {
                    ClientId = "application-client-id",
                    ClientSecret = "application-client-secret",
                    Scope = "openid profile email",
                    Authority = "personal-oidc-link",
                    AuthenticationMode = AuthenticationMode.Active,
                    ResponseType = OpenIdConnectResponseType.IdToken,
                    RedirectUri = "https://example.com/signin-oidc",
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        NameClaimType = ClaimTypes.NameIdentifier
                    },
                });
            app.Use(async (Context, next) =>
            {
                Debug.WriteLine("3 ==>after OIDC, before leaving the pipeline");
                await next.Invoke();
                Debug.WriteLine("4 <==after entering the pipeline, before OIDC");
            });

服务器配置:

services.AddOpenIddict()
                .AddCore(options =>
                {
                    // Configure OpenIddict to use the Entity Framework Core stores and entities.
                    options.UseEntityFrameworkCore()
                        .UseDbContext<DataContext>()
                        .ReplaceDefaultEntities<CompanyApplication, CompanyAuthorization, CompanyScope, CompanyToken, Guid>();
                })
                .AddServer(options =>
                {
                    options.UseMvc();

                    options.UseJsonWebTokens();
                    options.AddEphemeralSigningKey("RS512");
                    // options.AddDevelopmentSigningCertificate();

                    if (this.environment.IsDevelopment())
                    {
                        options.DisableHttpsRequirement();
                    }

                    // Enable the authorization, logout, token and userinfo endpoints.
                    options
                        .EnableAuthorizationEndpoint("/oidc/authorize")
                        .EnableLogoutEndpoint("/Account/Logout")
                        .EnableTokenEndpoint("/oidc/token")
                        .EnableUserinfoEndpoint("/oidc/userinfo");

                    options
                        .AllowAuthorizationCodeFlow()
                        .AllowImplicitFlow()
                        .AllowRefreshTokenFlow();

                    options.RegisterClaims(
                        CompanyClaims.FriendlyName,
                        CompanyClaims.Email,
                        CompanyClaims.EmailVerified,
                        CompanyClaims.Sub,
                        CompanyClaims.Group,
                        CompanyClaims.GivenName,
                        CompanyClaims.MiddleName,
                        CompanyClaims.FamilyName);

                    // Mark the "email", "profile" and "roles" scopes as supported scopes.
                    options.RegisterScopes(
                        OpenIddictConstants.Scopes.Email,
                        OpenIddictConstants.Scopes.Profile,
                        OpenIddictConstants.Scopes.Roles);
                });
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    o =>
                    {
                        o.AccessDeniedPath = "/Home/Denied";
                        o.LoginPath = "/Account/Login";
                        o.LogoutPath = "/Account/Logout";

                        o.Cookie.SameSite = SameSiteMode.Strict;
                        o.Cookie.Name = "session";
                        o.Cookie.Expiration = TimeSpan.FromHours(24);
                        o.ExpireTimeSpan = TimeSpan.FromHours(24);
                    });
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseAuthentication();

            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseResponseCaching();

            app.UseMvcWithDefaultRoute();
        }   

我希望OWIN生成/ signout-oidc路由,并在调用时删除身份验证cookie。

编辑:添加了更多配置文件。

2 个答案:

答案 0 :(得分:0)

您需要使用

PostLogoutRedirectUri = ""

答案 1 :(得分:0)

我没有使用openiddict库的经验。但是我正在使用IdentityServer库。

我了解到,在使用OpenChannel注销退出OpenId Connect流程中删除Cookie时,您需要:

o.Cookie.SameSite = SameSiteMode.None;

这样做,由OpenId服务器启动的对/ signout-oidc的GET请求将包含当前注销用户的身份验证cookie。因此,处理/ signout-oidc请求的中间件知道哪个用户正在注销并能够注销该用户。

您可以在浏览器中使用开发人员工具(使用Chrome时不要忘记启用“保留日志”)来查找GET / signout-oidc请求,并查看其中是否包含身份验证Cookie。

第二种选择是使用反向通道注销流程进行选择,不知道openiddict是否支持该流程。