我正在通过 OpenID Connect (OIDC) 提供程序构建具有基于 cookie 的身份验证的 Blazor Server ASP.NET Core 应用程序。注销时,我希望重定向到本地主机 URI:https://localhost:44378/signout-oidc。这是在 OIDC 提供商处注册为注销后重定向 URI 的路径。
当我注销时,我通过 Connect 提供商的注销流程发送,他们的日志状态为“结束会话请求验证成功”,但我最终得到 URI:https://localhost:44378/signout-oidc ?state=CfDJ8LdQ[...] 这是一个空白页。如果我在登录时尝试访问 https://localhost:44378/signout-oidc ,则会收到 Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Error: The Remote Signout request was Beenigned because the 'sid' parameter was丢失,这可能表示未经请求的注销。
我尝试了无数种不同的覆盖
SignedOutRedirectUri
、SignedOutCallbackPath
、RemoteSignOutPath
等的不同组合,以及重定向到其他页面 - 都无济于事。我的想法已经用完了,希望得到各种意见。
我添加了OpenID认证配置的代码:
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
opt.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddCookie("Cookies", options =>
{
options.Cookie.SameSite = SameSiteMode.None;
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = configuration.GetSection("AuthorizationStrings")["Authority"];
options.ClientId = configuration.GetSection("AuthorizationStrings")["ClientId"];
options.ClientSecret = configuration.GetSection("AuthorizationStrings")["ClientSecret"];
options.ResponseType = "code";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.UseTokenLifetime = false;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name" };
options.SignedOutCallbackPath = "/signout-oidc";
通过注销按钮启动的注销流程的代码。重定向 URI 的格式是 OIDC 提供商期望的格式(状态参数是可选的,因此我将其省略):
public async Task OnGetAsync()
{
var ac = await HttpContext.GetTokenAsync("access_token");
String uri = String.Format("[CONNECT PROVIDER URI]/endsession?id_token_hint={0}&post_logout_redirect_uri=https://localhost:44378/signout-oidc", ac);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var prop = new AuthenticationProperties
{
RedirectUri = uri
};
await HttpContext.SignOutAsync("oidc", prop);
}
您可能需要设置 LogoutPath,因为它必须与“Logout”链接的 URL 匹配;如果它们匹配,则 RedirectUri 将被接受。
}).AddCookie(options =>
{
options.LogoutPath = "/User/Logout";
...
});
请参阅此答案此处了解更多详细信息。
这是我的 /User/Logout 的注销代码
/// <summary>
/// Do the logout
/// </summary>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Logout()
{
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
//Important, this method should never return anything.
}