i我可以使用KeyCloak登录解决方案,以检索我的验证令牌,以及针对后端API的身份验证。
但是,解决方案并未完全实施注销机制,因此我决定自己尝试实施它。我遇到的问题是,当我通过NAVLINK导航到登录端点时,我将被重定向到KeyCloak,并且将删除KeyCloak中的会话,但是,将重定向到我的水疗中心不起作用,因为我得到了错误来自KeyCloak.
我找到了另一个Stackoverflow帖子,该帖子将在OpenIDConnect配置中设置
Missing parameters: id_token_hint
,但是这已经在我的配置中设置了,并且仍然不起作用。我还有其他需要配置的才能正常工作吗? program.cs
中的openidconnect配置
options.SaveTokens = true
oopenidConnect Enpoint配置
var oidcScheme = OpenIdConnectDefaults.AuthenticationScheme;
builder.Services.AddAuthentication(oidcScheme)
.AddKeycloakOpenIdConnect("keycloak", realm: "WeatherShop", oidcScheme, options =>
{
options.ClientId = "WeatherWeb";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("weather:all");
options.RequireHttpsMetadata = false;
options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
options.SaveTokens = true;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
Keycloak客户端config
internal static IEndpointConventionBuilder MapLoginAndLogout(this IEndpointRouteBuilder endpoints)
{
var group = endpoints.MapGroup("authentication");
// This redirects the user to the Keycloak login page and, after successful login, redirects them to the home page.
group.MapGet("/login", () => TypedResults.Challenge(new AuthenticationProperties { RedirectUri = "/" }))
.AllowAnonymous();
// This logs the user out of the application and redirects them to the home page.
group.MapGet("/logout", () => TypedResults.SignOut(new AuthenticationProperties { RedirectUri = "/" },
[CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme]));
return group;
}
要使用KeyCloak作为OpenID Connect Provider在.NET应用程序中正确实现注销机制,则需要确保在注销请求中包含ID_TOKEN_HINT参数。 KeyCloak使用此参数来识别需要终止的用户会话。在这里实现这一目标:
避免ID令牌:确保在用户登录时保存ID令牌。这可以通过在OpenIDConnect配置中设置
options.savetokens= true来完成,您已经完成了。重新解放ID令牌:当用户注销时,从身份验证属性中检索保存的ID令牌。 complude在注销请求中的ID令牌:将ID令牌作为logout请求中的id_token_hint参数传递给keycloak.
步长1:修改OpenIDConnect配置 确保通过设置
options.savetokens =true
:来保存ID令牌:
{
"id" : "016c17d1-8e0f-4a67-9116-86b4691ba99c",
"clientId" : "WeatherWeb",
"name" : "",
"description" : "",
"rootUrl" : "",
"adminUrl" : "",
"baseUrl" : "",
"surrogateAuthRequired" : false,
"enabled" : true,
"alwaysDisplayInConsole" : false,
"clientAuthenticatorType" : "client-secret",
"redirectUris" : [ "https://localhost:7058/signin-oidc" ],
"webOrigins" : [ "https://localhost:7058" ],
"notBefore" : 0,
"bearerOnly" : false,
"consentRequired" : false,
"standardFlowEnabled" : true,
"implicitFlowEnabled" : false,
"directAccessGrantsEnabled" : false,
"serviceAccountsEnabled" : false,
"publicClient" : true,
"frontchannelLogout" : true,
"protocol" : "openid-connect",
"attributes" : {
"oidc.ciba.grant.enabled" : "false",
"post.logout.redirect.uris" : "https://localhost:7058/signout-callback-oidc",
"oauth2.device.authorization.grant.enabled" : "false",
"backchannel.logout.session.required" : "true",
"backchannel.logout.revoke.offline.tokens" : "false"
},
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : true,
"nodeReRegistrationTimeout" : -1,
"defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "weather:all", "microprofile-jwt" ]
}
步长2:检索ID令牌并将其包含在注销请求中 修改注销端点以检索ID令牌并将其包含在注销请求中:
builder.Services.AddAuthentication(oidcScheme)
.AddKeycloakOpenIdConnect("keycloak", realm: "WeatherShop", oidcScheme, options =>
{
options.ClientId = "WeatherWeb";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("weather:all");
options.RequireHttpsMetadata = false;
options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
options.SaveTokens = true;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
步骤3:确保您的KeyCloak客户端配置包含正确的后期重定向URI:
internal static IEndpointConventionBuilder MapLoginAndLogout(this IEndpointRouteBuilder endpoints)
{
var group = endpoints.MapGroup("authentication");
// This redirects the user to the Keycloak login page and, after successful login, redirects them to the home page.
group.MapGet("/login", () => TypedResults.Challenge(new AuthenticationProperties { RedirectUri = "/" }))
.AllowAnonymous();
// This logs the user out of the application and redirects them to the home page.
group.MapGet("/logout", async (HttpContext context) =>
{
var authResult = await context.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var idToken = authResult.Properties.GetTokenValue("id_token");
if (idToken == null)
{
// Handle the case where the ID token is not found
return Results.BadRequest("ID token not found.");
}
var logoutProperties = new AuthenticationProperties
{
RedirectUri = "/",
Items =
{
{ "id_token_hint", idToken }
}
};
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Results.SignOut(logoutProperties, [CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme]);
});
return group;
}
通过遵循以下步骤,您应该能够使用KeyCloak作为OpenID Connect Provider在.NET应用程序中正确实现注销机制。
参数将包含在注销请求中,从而允许KeyCloak正确识别并终止用户会话。