【问题标题】:IdentityServer4 - Redirect to MVC client after LogoutIdentityServer4 - 注销后重定向到 MVC 客户端
【发布时间】:2017-09-01 18:15:45
【问题描述】:

我正在使用 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 客户端。现在用户必须点击下图中的链接显示重定向回 MVC 站点,但我认为用户应该自动重定向回 MVC 客户端。

【问题讨论】:

  • 请分享错误和其他日志。

标签: identityserver4


【解决方案1】:

不需要额外的代码。您应该确保 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

【讨论】:

    【解决方案2】:

    如果有人在使用 Scaffolding(他们使用 Razor Page 文件),根据 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() 的支持,逻辑可能因您的情况而异,在我的情况下,获取或发布无关紧要:

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

    在 OnPost 中添加 LogoutId 逻辑:

        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();
            }
        }
    

    【讨论】:

    • 就脚手架方案而言,这是正确的反应。感谢分享。我正在努力弄清楚为什么 post_logout_redirect_uri / returnUrl 没有被传递给我的注销操作。
    • 在我的情况下,Request.Query["logoutId"] 返回空,即使我可以在请求 url 中看到它。你能帮我解决这个问题吗?
    【解决方案3】:

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

    转到您的 IdentityServer4 应用程序,然后在 AccountController 的 Logout [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;
    

    【讨论】:

    • 我的客户端配置与 @Sandeep 相同,包括 PostLogoutRedirectUris,但是当我在调试模式下启动项目时,我可以看到 vm.PostLogoutRedirectUri 为空。知道为什么吗?
    • 需要更多说明。您是否在调试时尝试从客户端注销?因为,vm.PostLogoutRedirectUri 将在从任何配置的客户端收到注销请求时设置。
    • 这里一样 vm.PostLogoutRedirectUri 为空
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2021-10-02
    • 2018-05-06
    相关资源
    最近更新 更多