首页 > 解决方案 > OIDC SignOut AuthenticationProperties 参数未反映在 IdentityServer 注销上下文中

问题描述

我有一个在 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属性,但没有任何区别)

标签: asp.net-coreidentityserver4openid-connect

解决方案


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

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

    /// <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";
  })

推荐阅读