Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 为什么OpenIdConnectHandler.HandleSignOutCallbackAsync会劫持对SignedOutCallbackPath的任何请求_Asp.net Core_Asp.net Identity_Identityserver4_Openid Connect - Fatal编程技术网

Asp.net core 为什么OpenIdConnectHandler.HandleSignOutCallbackAsync会劫持对SignedOutCallbackPath的任何请求

Asp.net core 为什么OpenIdConnectHandler.HandleSignOutCallbackAsync会劫持对SignedOutCallbackPath的任何请求,asp.net-core,asp.net-identity,identityserver4,openid-connect,Asp.net Core,Asp.net Identity,Identityserver4,Openid Connect,我有一个软件身份服务器(v5.0.0-preview2.13),在ASPNetCore 5.0下运行,并使用HttpSys作为web服务器(没有Kestrel或IIS)。我还有第二个网站(称之为protectedsite),它使用隐式流对Identity Server进行身份验证。它也是HttpSys中托管的ASPNetCore 5.0。 我可以在我的protectedsite上登录并进行身份验证调用。我可以通过调用protectedsite中的以下代码来注销 [AllowAnonymous]

我有一个软件身份服务器(v5.0.0-preview2.13),在ASPNetCore 5.0下运行,并使用HttpSys作为web服务器(没有Kestrel或IIS)。我还有第二个网站(称之为protectedsite),它使用隐式流对Identity Server进行身份验证。它也是HttpSys中托管的ASPNetCore 5.0。 我可以在我的protectedsite上登录并进行身份验证调用。我可以通过调用protectedsite中的以下代码来注销

[AllowAnonymous]
public IActionResult Logout ()
{
  return SignOut(new AuthenticationProperties
  {
     RedirectUri = "/home/loggedout"
  }, "Cookies", "oidc");
}
    AddOpenIdConnect("oidc", options =>
      {
        options.Authority = "https://IDS:443";
        options.ClientId = "mvc";
        options.ClientSecret = "secret";
        options.GetClaimsFromUserInfoEndpoint = true;
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.Scope.Add("api1");
        options.Scope.Add("offline_access");
        options.Scope.Add("profile");
        options.SignInScheme = "Cookies";
        options.SignedOutCallbackPath = 
          Microsoft.AspNetCore.Http.PathString.FromUriComponent("/home/loggedout");
 //     options.SignedOutRedirectUri = "https://protectedsite/home/loggedout";
      });
问题出现在呼叫总部/日志中。OpenIdConnectHandler.HandleSignOutCallbackAsync中的代码在任何时候向home/Loggedout发出请求时都会接收控制,并且不会调用实际操作。拦截是在IDS中的注销代码完成后完成的,即使我完成了https://ProtectedSite/Home/LoggedOut 甚至连身份证都不碰

似乎OpenIdConnectHandler.HandleSignOutCallbackAsync将拦截任何看起来像OpenIdConnectOptions.SignedOutCallbackPath的url。如果在启动时删除SignedOutCallbackPath设置,则不会拦截请求并运行操作,但IDS会声明我的PostLogoutRedirectUri无效,因为https://protectedsite/signout-callback-oidc 不在有效的注销后URL列表中

在这一点上,我的底线问题是,我可以从ID重定向到我的受保护站点,但实际上不起作用(在屏幕上留下一个空白页),或者我可以放弃重定向到受保护站点,并在Duende IDS站点上显示标准Duende注销消息。我不希望用户留在Duende站点上

protectedsite中的OIDC设置

[AllowAnonymous]
public IActionResult Logout ()
{
  return SignOut(new AuthenticationProperties
  {
     RedirectUri = "/home/loggedout"
  }, "Cookies", "oidc");
}
    AddOpenIdConnect("oidc", options =>
      {
        options.Authority = "https://IDS:443";
        options.ClientId = "mvc";
        options.ClientSecret = "secret";
        options.GetClaimsFromUserInfoEndpoint = true;
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.Scope.Add("api1");
        options.Scope.Add("offline_access");
        options.Scope.Add("profile");
        options.SignInScheme = "Cookies";
        options.SignedOutCallbackPath = 
          Microsoft.AspNetCore.Http.PathString.FromUriComponent("/home/loggedout");
 //     options.SignedOutRedirectUri = "https://protectedsite/home/loggedout";
      });

这是一个典型的问题,您希望从注销操作方法返回一些内容

但是注销的正确方法是不从该方法返回任何内容。内部SignOutAsync将生成自己的响应

因此,正确的方法是执行以下操作:

/// <summary>
/// Do the logout
/// </summary>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Logout()
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}
//
///注销
/// 
/// 
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务注销()
{
等待HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
等待HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}

这是一段旅程,因为文档不好/缺少,示例不好。注意()显示注销操作没有返回。这似乎是解决方案中非常重要的一部分。同样在回答这个问题之后,我偶然发现了一篇文章,其中描述了通过AsNetIdentity进行注销重定向的路径。这里无法对其进行总结,但只要链接可用,就应该咨询它。如果我早两天找到它,我就可以省下一天半的代码

我的问题很多。
经验教训:不返回注销操作的结果

请注意下面对在受保护站点中启动所做的更改

AddOpenIdConnect("oidc", options =>
      {
        options.Authority = "https://IDS:443";
        options.ClientId = "mvc";
        options.ClientSecret = "secret";
        options.GetClaimsFromUserInfoEndpoint = true;
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.Scope.Add("api1");
        options.Scope.Add("offline_access");
        options.Scope.Add("profile");
        options.SignInScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
//        options.SignedOutCallbackPath = Microsoft.AspNetCore.Http.PathString.FromUriComponent("/home/loggedout");
        options.SignedOutRedirectUri = "/home/loggedout";
      });
经验教训是SignedOutCallbackPath是回调后将在受保护站点上调用的uri。它默认为/signout回调oidc,据我所知,应该保留为默认值,只需确保您将IDS客户机配置的postLogoutRedecturis设置为相同的值


最后,我提供这张便条。我不知道是否可以在注销操作中提供重定向URI,并将其作为运行时决策使用。我目前的观点是,当且仅当在IDS客户端配置的PostLogoutRedirectURI中也设置了URI时,才可以。我也相信,但不知道,如果重定向到的站点尊重已签名的UtredRecturi,那么重定向URI选择的站点将遵循该规则,但我没有试图证明这两种理论。

感谢您的回复。您的代码和现有配置使我重定向到protectedsite上的默认页面。一些工作终于让我重定向了我想要的,并给出它需要几个代码的变化,我要张贴自己的答案,但我认为你的答案是非常有益的。