IdentityServer4 - 注销后重定向到 MVC 客户端

IdentityServer4 - Redirect to MVC client after Logout

我正在使用 IdenetityServer4 并且在注销后重定向到 MVC 客户端不起作用。以下是我的 MVC 客户端控制器注销操作:

public async Task Logout()
{
    await HttpContext.Authentication.SignOutAsync("Cookies");
    await HttpContext.Authentication.SignOutAsync("oidc");
}

以下是身份服务器 4 主机配置文件。

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        // other clients omitted...

        // OpenID Connect implicit flow client (MVC)
        new Client
        {
            ClientId = "mvc",
            ClientName = "MVC Client",
            AllowedGrantTypes = GrantTypes.Implicit,

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

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

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

我希望用户在从 IdentityServer 注销后重定向回 MVC 客户端。现在用户必须单击下图中显示的 link 才能重定向回 MVC 站点,但我认为用户应该自动重定向回 MVC 客户端。

您的 Config.cs 或 MVC 控制器没有问题。

转到您的 IdentityServer4 应用程序,然后在 AccountController 的注销 [HttpPost] 方法中,进行以下更改:

public async Task<IActionResult> Logout(LogoutViewModel model)
{
   ...    
  //return View("LoggedOut", vm);
  return Redirect(vm.PostLogoutRedirectUri);
}

这会将用户重定向回 MVC 应用程序(在您的情况下)。

有更好的方法来做到这一点: 您可以从 AccountOptions.cs 中设置这些选项,如下所示:

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

如果有人在使用脚手架(他们使用 Razor 页面文件),这里是根据 Akhilesh 的回答修复它的方法:

在 Areas\Identity\Pages\Account\Logout.cshtml:

首先,添加IIdentityServerInteractionService服务:

    IIdentityServerInteractionService _interaction;

    public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger, IIdentityServerInteractionService _interaction)
    {
        _signInManager = signInManager;
        _logger = logger;
        this._interaction = _interaction;
    }

您可能需要添加对 OnGet() 的支持,逻辑可能会有所不同,具体取决于您的情况,在我的情况下,Get 或 Post 无关紧要:

    public async Task<IActionResult> OnGet(string returnUrl = null)
    {
        return await this.OnPost(returnUrl);
    }

在On中添加LogoutId逻辑Post:

    public async Task<IActionResult> OnPost(string returnUrl = null)
    {
        await _signInManager.SignOutAsync();
        _logger.LogInformation("User logged out.");

        var logoutId = this.Request.Query["logoutId"].ToString();

        if (returnUrl != null)
        {
            return LocalRedirect(returnUrl);
        }
        else if (!string.IsNullOrEmpty(logoutId))
        {
            var logoutContext = await this._interaction.GetLogoutContextAsync(logoutId);
            returnUrl = logoutContext.PostLogoutRedirectUri;

            if (!string.IsNullOrEmpty(returnUrl))
            {
                return this.Redirect(returnUrl);
            }
            else
            {
                return Page();
            }
        }
        else
        {
            return Page();
        }
    }

不需要额外的代码。您应该确保 Model.AutomaticRedirectAfterSignOut=true 和 signout-redirect.js 是否存在于 wwwroot/js 和 LoggedOut.cshtml

@if (Model.AutomaticRedirectAfterSignOut)
    {
        <script src="~/js/signout-redirect.js"></script>
    }

使所有工作正常(见下面的代码)

window.addEventListener("load", function () {
    var a = document.querySelector("a.PostLogoutRedirectUri");
    if (a) {
        window.location = a.href;
    }
});

因此用户从 LoggedOut.cshtml

重定向到 mvc