首页 > 解决方案 > 注销后未重定向到 ASP.Net MVC 客户端(.net 框架 4.6.2)

问题描述

我在 .Net core 3 中有一个 Identity Server 4 实现。我还创建了 3 个客户端:Angular、.Net Core MVC (.Net Core 3.0) 和 .Net framework MVC (.Net framework 4.6.2)。

Angular 和 .Net Core MVC 客户端可以正常工作,但 .Net 框架 MVC 客户端有问题。它不会从 Identity Server 重定向回客户端。

.Net Framework MVC 启动

private void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions {AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,});

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
        SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,

        Authority = "https://localhost:5001/",
        RequireHttpsMetadata = false,

        ResponseType = "id_token",

        RedirectUri = "https://localhost:44333/signin-oidc",
        PostLogoutRedirectUri = "https://localhost:44333/signout-callback-oidc",

        ClientId = "mvc-framework",
        SaveTokens = true
    });
}

注销代码:

[Authorize]
public ActionResult SignOut()
{
    HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType, OpenIdConnectAuthenticationDefaults.AuthenticationType);

    return RedirectToAction("Index", "Home");
}

身份服务器设置:

internal static IServiceCollection AddConfiguredIdentityServer4InMemory(this IServiceCollection services, IConfiguration configuration, IWebHostEnvironment webHostingEnvironment)
{
    var builder = services.AddIdentityServer()
        .AddInMemoryIdentityResources(InMemoryData.GetIdentityResources())
        .AddInMemoryApiResources(InMemoryData.GetApiResources())
        .AddInMemoryClients(InMemoryData.GetClients())
        .AddTestUsers(InMemoryData.GetUsers());

    if (webHostingEnvironment.IsDevelopment())
        builder.AddDeveloperSigningCredential();
    else
        throw new Exception("need to configure key material"); //ToDo: work with certificate in key vault.

    return services;

}

客户端配置:

internal static IEnumerable<Client> GetClients()
{
    return new[]
    {
        // OpenID Connect implicit flow MVC .Net Framework client
        new Client
        {
            ClientId = "mvc-framework",
            ClientName = "MVC .Net Framework Client",
            AllowedGrantTypes = GrantTypes.Implicit,
            RequireConsent = false,

            // where to redirect to after login
            RedirectUris = { "https://localhost:44333/signin-oidc" },

            // where to redirect to after logout
            PostLogoutRedirectUris = { "https://localhost:44333/signout-callback-oidc" },

            // scopes
            AllowedScopes = new List<string> {IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile}
        },

        // OpenID Connect implicit flow MVC .Net Core client
        new Client
        {
            ClientId = "mvc-core",
            ClientName = "MVC .Net Core Client",
            AllowedGrantTypes = GrantTypes.Implicit,
            RequireConsent = false,

            // where to redirect to after login
            RedirectUris = { "https://localhost:5003/signin-oidc" },

            // where to redirect to after logout
            PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },
            AllowedScopes = new List<string> {IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile}
        },
        new Client
        {

            ClientId = "angular_spa",
            ClientName = "Angular SPA",
            AllowedGrantTypes = GrantTypes.Implicit,

            RequireConsent = false,

            // where to redirect to after login
            RedirectUris = { "http://localhost:4200/auth-callback" },

            // where to redirect to after logout
            PostLogoutRedirectUris = { "http://localhost:4200/" },

            // cors
            AllowedCorsOrigins = {"http://localhost:4200"},

            AllowedScopes = new List<string> {IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile}
        }
    };
}

身份服务器帐户配置:

public class AccountOptions
{
    public static bool AllowLocalLogin = true;
    public static bool AllowRememberLogin = true;
    public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);

    public static bool ShowLogoutPrompt = false;
    public static bool AutomaticRedirectAfterSignOut = true;

    public static readonly string WindowsAuthenticationSchemeName = Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme;
    public static bool IncludeWindowsGroups = false;

    public static string InvalidCredentialsErrorMessage = "Invalid username or password";
}

当我使用 .Net 框架 MVC 客户端并注销时,我被重定向到 Identity Server,并且用户没有问题地注销,但我的浏览器卡在了:

Identity Server的LogOut页面

LoggedOutViewModel 上的 PostLogoutRedirectUri 为空,但我不知道为什么。其他两个客户端都在注销后重定向到。

为什么我的 .Net 框架 MVC(.Net 框架 4.6.2)客户端没有被重定向到的任何想法?或者为什么它的 PostLogoutRedirectUri 在 LoggedOutViewModel 上是空的?

标签: asp.netidentityserver4

解决方案


IdentityServer 需要id_token才能继续(自动)重定向。因为这没有发生,所以 id 令牌似乎不存在。

这里查看问题以获取更多信息。

要解决它,您必须在注销时包含令牌

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        RedirectToIdentityProvider = n =>
        {
            // if signing out, add the id_token_hint
            if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
            {
                var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                    if (idTokenHint != null)
                        n.ProtocolMessage.IdTokenHint = idTokenHint.Value;

                    return Task.FromResult(0);
                }
            }
        }
    }
}

要启用自动重定向,请在此处查看我的答案


推荐阅读