我需要更新一个使用 Keycloak 并具有与 Keycloak 19 兼容的表单身份验证的应用程序。以前使用的是 Keycloak 17。注销后,浏览器使用
redirect_uri
参数重定向到应用程序登录页面。
由于 Keycloak 19 不再支持用于注销的
redirect_uri
参数,我需要使用 id_token_hint
和 post_logout_redirect_uri
参数来实现与 Keycloak 17 类似的行为。到目前为止,我已将参数 post_logout_redirect_uri
添加到我的注销 URL,如下所示:https://realm/protocol/openid-connect/logout?post_logout_redirect_uri=https://my-application/UserLogin.aspx
。但是,这会出现错误“缺少参数:id_token_hint
”。
我需要帮助获取应添加到注销 URL 的
id_token_hint
参数的值。我的代码是用 C# 编写的。
目前,
UserLogin.aspx
中的代码如下所示:
public partial class CustomLogin : Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Check if sign out required
if (SignOut)
{
ExecuteSignOut(Request, Response);
}
else
{
ExecuteSignIn(Request, Response);
}
}
public static void ExecuteSignOut(HttpRequest request, HttpResponse response)
{
var redirectUri = request.Url.AbsoluteUri;
var signOutUri = $"{Realm}/protocol/openid-connect/logout?" +
$"post_logout_redirect_uri={HttpUtility.UrlEncode(redirectUri)}";
response.Redirect(signOutUri, false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
最后,注销 URL 应如下所示:
https://realm/protocol/openid-connect/logout?id_token_hint=value_of_id_token&post_logout_redirect_uri=https://my-application/UserLogin.aspx
。
为了回答我的问题,我是这样做的:
//First, read code from request.
var code = request.QueryString["code"];
// Redirect URI was saved when user opened the sign in of the application. User was redirected to Keycloack.
var redirectUri = request.Cookies["RedirectUriCookieName"].value;
var tokens = JwtHelper.GetOAuth2TokensByCode(code, redirectUri);
var idtoken = tokens["id_token"].Value<string>();
其中 GetOAuth2TokensByCode 类似于
public static JObject GetOAuth2TokensByCode(string code, string redirectUri)
{
var targetUrl = "https://_Keycloack_URL_/auth" + "/protocol/openid-connect/token";
try
{
using (var client = new WebClient())
{
client.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
var parameters = new System.Collections.Specialized.NameValueCollection
{
{ "grant_type", "authorization_code" },
{ "client_id", OAuth2ClientId },
{ "client_secret", OAuth2ClientSecret },
{ "code", code },
{ "redirect_uri", redirectUri }
};
var response = client.UploadValues(targetUrl, "POST", parameters);
var result = Encoding.UTF8.GetString(response);
return JObject.Parse(result);
}
}
catch (WebException e)
{
}
}