Asp.net core mvc 注销不会重定向到站点主页

Asp.net core mvc 注销不会重定向到站点主页,asp.net-core-mvc,openid-connect,asp.net-core-3.0,Asp.net Core Mvc,Openid Connect,Asp.net Core 3.0,我正在尝试设置一个ASP.net Core 3 MVC应用程序,它使用OIDC连接到我公司的SSO门户(OpenAM) 我使用Visual Studio 2019 project generator创建了一个没有身份验证的基本应用程序,然后按照中的步骤添加了OIDC客户端功能。 登录非常有效,对Startup类的更改非常少: public void ConfigureServices(IServiceCollection services) { services.

我正在尝试设置一个ASP.net Core 3 MVC应用程序,它使用OIDC连接到我公司的SSO门户(OpenAM)

我使用Visual Studio 2019 project generator创建了一个没有身份验证的基本应用程序,然后按照中的步骤添加了OIDC客户端功能。 登录非常有效,对Startup类的更改非常少:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        // Setup Identity Server client
        JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

        services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.Authority = "https://mycompany.com/ssoservice/oauth2";
                options.RequireHttpsMetadata = false;

                options.ClientId = "openIdClient";
                options.ClientSecret = "secret";
                options.ResponseType = "code";
                options.ProtocolValidator.RequireNonce = false;

                options.SaveTokens = true;
            });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            IdentityModelEventSource.ShowPII = true;
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

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

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            // endpoints.MapDefaultControllerRoute();
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
我还设置了注销控制器操作:

    [Authorize]
    public IActionResult Logout()
    {
        return SignOut("Cookies", "oidc");
    }
该操作实际上是有效的,即当激活时,cookie被删除,用户从SSO门户注销,但当浏览器重定向到/signout回调oidc端点时,它接收到一个HTTP 200响应,而没有任何内容。我希望它能自动重定向到站点主页“/”,这是OpenIdConnectOptions.SignedOutRedirectUri属性的默认值

我遗漏了什么?

您返回注销

相反,注销用户并返回RedirectToAction(“主页”、“索引”)

返回注销


相反,注销用户并返回RedirectToAction(“Home”、“Index”)

好的,在花了一些时间之后,我发现这是由于最新的社区OpenAM版本(以及当前的付费OpenAM版本)中缺少一个草案实现的结果,但他们正在处理:)。基本上,
/signout callback oidc
的.net核心处理程序依赖于使用
state
参数来重定向,如注释中提到的Ruard van Elburg:

OpenAM不会发回我的日志中报告的
状态
参数。因此,我们需要自己执行重定向-最直接的方法似乎是使用
OnSignedOutCallbackRedirect
事件:

Startup.cs

    services.AddAuthentication(...)
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", options =>
        {
            ...
            options.Events.OnSignedOutCallbackRedirect += context =>
            {
                context.Response.Redirect(context.Options.SignedOutRedirectUri);
                context.HandleResponse();

                return Task.CompletedTask;
            };
            ...
        });

感谢所有回复讨论的用户,您的贡献让我找到了正确解决方案的线索。

好的,在花了一些时间之后,我发现这是由于最新的社区OpenAM版本(以及当前的付费OpenAM版本)中缺少一个实现草案造成的,但他们正在研究:). 基本上,
/signout callback oidc
的.net核心处理程序依赖于使用
state
参数来重定向,如注释中提到的Ruard van Elburg:

OpenAM不会发回我的日志中报告的
状态
参数。因此,我们需要自己执行重定向-最直接的方法似乎是使用
OnSignedOutCallbackRedirect
事件:

Startup.cs

    services.AddAuthentication(...)
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", options =>
        {
            ...
            options.Events.OnSignedOutCallbackRedirect += context =>
            {
                context.Response.Redirect(context.Options.SignedOutRedirectUri);
                context.HandleResponse();

                return Task.CompletedTask;
            };
            ...
        });

感谢所有回复讨论的用户,您的贡献让我找到了正确解决方案的线索。

不,不是这样。这是第24行。如果您要注销,请呼叫您的服务和注销用户,然后重定向到其他操作。请注意标签:
IdentityServer4
。如何使用signout语句没有问题,如IdentityServer的de-sample代码所示。OP想知道为什么它不起作用,而不是是否有其他解决方案。这是他最后一次打电话,所以在注销时他可以在注销后重定向,或者注销并重定向。结果证明JS是正确的:IdentityServer4在这里不起作用(我将相应地编辑第一篇文章):事实上,它只提供服务器功能;客户端是.net核心框架的一部分,后者本身不需要任何类型的重定向。我误解了IdentityServer4的文档,并从中错误地推断。不,不是这样。这是第24行。如果您要注销,请呼叫您的服务和注销用户,然后重定向到其他操作。请注意标签:
IdentityServer4
。如何使用signout语句没有问题,如IdentityServer的de-sample代码所示。OP想知道为什么它不起作用,而不是是否有其他解决方案。这是他最后一次打电话,所以在注销时他可以在注销后重定向,或者注销并重定向。结果证明JS是正确的:IdentityServer4在这里不起作用(我将相应地编辑第一篇文章):事实上,它只提供服务器功能;客户端是.net核心框架的一部分,后者本身不需要任何类型的重定向。我误解了IdentityServer4的文档,并从中错误地推断。不,该项目是vanilla Visual Studio MVC模板。Startup.Configure方法已在上面发布。我对ASP.net Core MVC有点陌生,因此如果我误解了您的请求,我深表歉意。调试输出:ASP.net Core Web服务器输出:感谢您的耐心。日志中的行表明您正在直接调用url,而没有传递状态:
请求启动HTTP/2.0 GEThttps://localhost:44301/signout-回调oidc
。这应该是:
https://localhost:44301/signout-回调oidc?state=CfDJ8OM…
那么问题是,为什么省略状态?你能在IdentityServer中显示Account.Logout中的代码吗?我认为你在IdentityServer(
Account.Logout
)中重定向用户的方式是问题所在。在我的回答中,我解释了如何自动将用户重定向到客户端。id_标记不是问题所在,因此您可以跳过答案的第一部分。我不清楚服务器是否不是IdentityServer的实现,但这毕竟无关紧要,因为它都是关于实现相同的规范。不,该项目是vanilla Visual Studio MVC模板。Startup.Configure方法已在上面发布。我对ASP.net Core MVC有点陌生,因此如果我误解了您的请求,我深表歉意。调试输出:ASP.net Core Web服务器输出:感谢您的耐心。日志中的行表明您正在直接调用url,而没有传递状态:
请求启动HTTP/2.0 GEThttps://localhost:44301/signout-回调oidc