【问题标题】:OIDC SignOut AuthenticationProperties Parameters not reflected on IdentityServer sign-out ContextOIDC SignOut AuthenticationProperties 参数未反映在 IdentityServer 注销上下文中
【发布时间】:2021-06-02 05:23:22
【问题描述】:

我有一个在 ASP.Net Core 3.1 中运行的 IdentityServer4 服务器(使用脚手架的 ASP.Net Core Identity)并验证我的单独 ASP.Net Core 3.1 Web 应用程序的用户。

我的问题在于注销,其中 IdentiyServer 注销上下文未反映在客户端定义的参数。

设置如下: 客户端的注销控制器方法结束如下:

var ap = new AuthenticationProperties();
ap.Parameters.Add("Reason", reason);
ap.Parameters.Add("TenantId", profileId.ToString());
return SignOut(ap, CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme);

我有一个这样定义的自定义 OpenIdConnectEvents 类:

public class CustomOpenIdConnectEvents : OpenIdConnectEvents
{
  public override async Task RedirectToIdentityProviderForSignOut(RedirectContext context)
  {
    await base.RedirectToIdentityProviderForSignOut(context);
    //a breakpoint on the above line confirms that the context.Properties.Parameters contains the values defined in the Controller logout method
  }
}

在客户端的Startup.cs中挂接如下:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    //irrelevant cookie options here
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.EventsType = typeof(CustomOpenIdConnectEvents);
    //other option settings here
});

在 IdentityServer 上,Logout Page 被调用,OnGet() 方法如下所示:

public async Task<IActionResult> OnGet()
{
    var context = await _interaction.GetLogoutContextAsync(logoutId);
    //at this point I expect context.Parameters to reflect the parameters sent from the client, but the .Parameters is empty.

    //other code
}

为什么OIDC Client 端定义的Parameters 没有传递给OIDC Server?我错过了什么? (顺便说一句,在客户端上,我也尝试填充 .Items 属性而不是 .Parameters 属性,但没有任何区别)

【问题讨论】:

  • 我显然在我的方法中遗漏了一些基本的东西,因为我已经设法在 IdentityServer4 QuickStart 2 上复制了这个问题。将做进一步的调查并恢复。
  • 我明白了!添加解决方案作为答案!

标签: asp.net-core identityserver4 openid-connect


【解决方案1】:

注销方法不应该返回任何东西,因为注销方法本身会创建自己的响应。

所以它应该看起来像这样:

    /// <summary>
    /// Do the logout
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task Logout()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);

        //Important, this method should never return anything.
    }

也许您还需要设置 LogoutPath?它是我培训课程幻灯片中的一项安全功能:

在 Addcookie 处理程序上设置注销路径。

.AddCookie(options =>
  {
      options.LogoutPath = "/User/Logout";
      options.AccessDeniedPath = "/User/AccessDenied";
  })

【讨论】:

  • 感谢您提供有关如何完成客户端注销的提示。可悲的是,它无助于解决我所问的问题。我在客户端 SignOut 处指定的参数仍未传递到 Identity Server 的 SignOut 机制。
  • 谢谢。但我的问题不在于没有调用 Identity Server 上的 SignOut 页面。重定向都按预期发生。我的问题是 IdentityServer 的注销页面中的上下文没有反映我从客户端发送的参数。
【解决方案2】:

我明白了!!!

在我的CustomOpenIdConnectEvents 类中,我必须将参数添加到context.ProtocolMessage,如下所示:

public override Task RedirectToIdentityProviderForSignOut(RedirectContext context)
{
  foreach (var item in context.Properties.Parameters)
    context.ProtocolMessage.SetParameter(item.Key, item.Value.ToString());
  return base.RedirectToIdentityProviderForSignOut(context);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-13
    • 2021-04-11
    • 2018-07-18
    • 2021-11-11
    • 1970-01-01
    • 2019-02-17
    • 2023-03-09
    • 2018-06-10
    相关资源
    最近更新 更多