IdentityServer4 重定向到注销页面而不是 PostLogoutRedirectUri
Posted
技术标签:
【中文标题】IdentityServer4 重定向到注销页面而不是 PostLogoutRedirectUri【英文标题】:IdentityServer4 redirects to Logout page instead of PostLogoutRedirectUri 【发布时间】:2021-06-15 23:22:15 【问题描述】:我创建了 AspNetCore 3.1 项目并为 SSO 添加了 IdentityServer4(添加了“Microsoft.AspNetCore.ApiAuthorization.IdentityServer”包)。登录可以正常工作,但注销不行。
在 Startup.cs 中,我对 IdentityServer 进行了以下配置:
public void ConfigureServices(IServiceCollection services)
...
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
...
var client = new Client
ClientName = "ssotestclient",
ClientId = "ssotestclient",
ClientSecrets = new Secret("somesecret".Sha256()) ,
AllowedGrantTypes = GrantTypes.Code.Union(GrantTypes.ResourceOwnerPasswordAndClientCredentials).ToArray(),
RequirePkce = false,
RequireClientSecret = false,
AllowOfflineAccess = false,
AlwaysSendClientClaims = true,
UpdateAccessTokenClaimsOnRefresh = true,
AlwaysIncludeUserClaimsInIdToken = true,
AllowedScopes = new List<string>
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess
,
RequireConsent = false,
RedirectUris = "https://mytestsite.local/signin-oidc" ,
PostLogoutRedirectUris = "https://mytestsite.local/signout-callback-oidc"
options.Clients.Add(client);
);
客户端网站是一个带有“Microsoft.AspNetCore.Authentication.OpenIdConnect”包的 AspNetCore MVC 项目。 Startup.cs 中的客户端初始化
public void ConfigureServices(IServiceCollection services)
services.AddAuthentication(options =>
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
)
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://myssoserver.local";
options.RequireHttpsMetadata = false;
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
options.BackchannelHttpHandler = handler;
options.ClientId = "ssotestclient";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("email");
options.Scope.Add("profile");
options.SaveTokens = true;
);
services.AddAuthorization();
services.AddRazorPages();
services.AddControllers();
客户端网站上的注销按钮有以下代码:
public async Task OnPostAsync(string returnUrl = null)
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
在此之后,浏览器被重定向到具有以下位置的 SSO 服务器:
https://myssoserver.local/connect/endsession?post_logout_redirect_uri=https%3A%2F%2Fmytestsite.local%2Fsignout-callback-oidc&id_token_hint=<token>&state=<state>&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0
token 和 state 的实际值从这篇文章中被删减,因为它们太长了。
如您所见,post_logout_redirect_uri、id_token_hint 和 state 参数被传递到服务器 endsession 端点。 在 SSO 服务器端,我看到它已通过验证的消息:
info: IdentityServer4.Validation.EndSessionRequestValidator[0]
End session request validation success
"ClientId": "sso_test_client",
"ClientName": "sso_test_client",
"SubjectId": "f3693d8c-6095-4f1a-9f8f-bdc7440e9395",
"PostLogOutUri": "https://mytestsite.local/signout-callback-oidc",
"State": "<state>",
"Raw":
"post_logout_redirect_uri": "https://mytestsite.local/signout-callback-oidc",
"id_token_hint": "***REDACTED***",
"state": "<state>",
"x-client-SKU": "ID_NETSTANDARD2_0",
"x-client-ver": "5.5.0.0"
然而,在此请求之后,浏览器会收到 302 重定向到 https://myssoserver.local/Identity/Account/Logout 页面,而不是提供的 post_logout_redirect_uri。 并且不会发生实际的注销,因为只调用了 OnGet() 处理程序,它什么都不做
在网上找不到类似的问题。
可能出了什么问题?为什么我会被重定向到注销页面而不是回调 uri?我搜索了项目代码,除了注销页面本身之外,找不到任何与“注销”字样的引用
【问题讨论】:
【参考方案1】:一种想法是您需要设置 LogoutPath。
.AddCookie(选项 => options.LogoutPath = "/用户/注销"; )
LogoutPath 是一项安全功能,正如我的一个培训课程中的这张图片所示:
【讨论】:
问题是浏览器在 SSO 服务器的注销页面上没有调用 POST。它使用 GET 重定向 您可以忽略我图片中的 HttpPost 属性,但是,让注销按钮发布而不是 GET 是最佳做法。见security.stackexchange.com/questions/62769/… 我不想让用户单击应用程序服务器上的注销按钮,然后单击 SSO 服务器上的注销按钮。我想要应用程序服务器上的注销按钮,该按钮也会从 SSO 中注销用户。 这里不调用两者 await HttpContext.SignOutAsync("Cookies");等待 HttpContext.SignOutAsync("oidc");让你从两者中退出?一般来说应该。 应该,但没有。仅从客户端服务器注销,而不是从 SSO 服务器注销。所以下次我刷新客户端服务器页面时,我会自动从 SSO 获取一个新令牌,因为我仍然处于登录状态。以上是关于IdentityServer4 重定向到注销页面而不是 PostLogoutRedirectUri的主要内容,如果未能解决你的问题,请参考以下文章
是否可以将 IdentityServer4 中的用户注销为其他用户?
登录到网站后,它会根据检查“网络”重定向到正确的页面,但是会注销并重新加载登录页面
带有 docker-compose 的 Identity Server 4 在 /connect/authorize/callback 之后重定向到登录页面