Keycloak 桌面 java 适配器删除 KEYCLOAK_IDENTITY cookie
Keycloak desktop java adapter deletes KEYCLOAK_IDENTITY cookies
Keycloak java 适配器有问题。我尝试将桌面应用程序与 Keycloak 集成,并在其他一些 Web 应用程序之间启用 SSO。问题是,当我尝试登录到 Keycloak 时,一切都完美而流畅,我获得了有关正确身份验证的信息,获得了令牌,甚至可以毫无问题地解析它,但是在 WebBrowser 中没有创建会话(没有会话,没有 cookie) .这意味着即使正确创建了 Keycloak 中的会话,我也不能将刚刚创建的会话与同一 Keycloak 领域中的其他应用程序一起使用。
在我的桌面适配器“成功”登录尝试后,其他应用程序之前创建和存储的更多 cookie 也被删除(我指的是 KEYCLOAK_IDENTITY 和 KEYCLOAK_INDENTITY_LEGACY 的 cookie)。当我检查浏览器 cookie 时,有一些警告声明说 cookie 因过期而被拒绝。
我用的是KeycloakInstalled适配器(最新,15.0.2版本)。我使用页面上的说明配置它:https://www.keycloak.org/docs/latest/securing_apps/
我认为本例中最重要的一段代码:
KeycloakInstalled keycloak = new KeycloakInstalled();
AdapterConfig config = new AdapterConfig();
Map<String, Object> credentials = new HashMap<String, Object>();
credentials.put("secret", secret);
config.setAuthServerUrl(url);
keycloak.getDeployment().setRealm(realm);
keycloak.getDeployment().setAuthServerBaseUrl(config);
keycloak.getDeployment().setResourceName(resource);
keycloak.getDeployment().setResourceCredentials(credentials);
keycloak.getDeployment().setClientAuthenticator(ClientCredentialsProviderUtils.bootstrapClientAuthenticator(keycloak.getDeployment()));
keycloak.loginDesktop();
在这种情况下,一些 Keycloak 属性在 keycloak.json 文件中静态设置,一些在 Java 中动态设置(如上例)。在 keycloak.json 文件中,一些属性如 realm, auth-server-url, resource 和 secret 都是垃圾数据, 刚好, 因为后面动态设置.
{
"realm": "<realm>",
"auth-server-url": "<url>",
"ssl-required": "external",
"resource": "<keycloak-client>",
"use-resource-role-mappings": true,
"credentials" : {
"secret" : "abc"
},
"truststore" : "<file>.jks",
"truststore-password" : "<password>"
}
Keycloak 的客户端配置我是这样设置的:
Keycloak_configuration
如何避免使用我的桌面适配器删除会话 cookie?
我已经解决了我的问题。一切都与适配器身份验证机制有关。它是这样工作的:
- 适配器连接到 keycloak 以验证用户。
- 然后从第一个 url 标记为 redirect_url 的参数中重定向到地址,以告诉适配器身份验证是肯定的。
请注意,到目前为止,每个 cookie 都已正确设置。
- 然后有另一个重定向到 /delegated 端点,这使所有会话 cookie 都已过期。这一切都归功于Keycloak存储库中的这段代码:
@Path("delegated")
public Response kcinitBrowserLoginComplete(@QueryParam("error") boolean error) {
AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection);
AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), clientConnection);
...
}
我所做的是创建我自己的 CustomKeycloakInstalled class 扩展原始 KeycloakInstalled 我在其中复制了关键方法 loginDesktop() 和其他一些让 loginDesktop() 正常工作的必要方法 - 最重要的是,覆盖函数返回最后一次重定向 url (/delegated) 和我自己的:
private String getRedirectUrl() {
String redirectUrl = CustomKeycloakInstalled.this.getDeployment().getTokenUrl()
.replace("/protocol/openid-connect/token", "/my-endpoint");
if (this.error != null) {
redirectUrl = redirectUrl + "?error=true";
}
return redirectUrl;
}
现在每个 cookie 都已正确设置并且 SSO 工作正常,但 Keycloak 服务器中没有 /my-endpoint 因此最后一步是实施和部署它。我在下面使用了 KeycloakResourceProvider 示例:
https://github.com/keycloak/keycloak/tree/master/examples/providers/rest
这真的很简单,所以我所做的就是用 Keycloak 的端点 delegated 的实现替换 get() 方法,但没有使 cookie 片段过期:
@GET
@Produces("text/plain; charset=utf-8")
public Response get(@QueryParam("error") boolean error) {
if (error) {
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class);
return forms
.setAttribute("messageHeader", forms.getMessage(Messages.DELEGATION_FAILED_HEADER))
.setAttribute(Constants.SKIP_LINK, true).setError(Messages.DELEGATION_FAILED).createInfoPage();
} else {
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class);
return forms
.setAttribute("messageHeader", forms.getMessage(Messages.DELEGATION_COMPLETE_HEADER))
.setAttribute(Constants.SKIP_LINK, true)
.setSuccess(Messages.DELEGATION_COMPLETE).createInfoPage();
}
}
然后编译并部署到Keycloak中。
Keycloak java 适配器有问题。我尝试将桌面应用程序与 Keycloak 集成,并在其他一些 Web 应用程序之间启用 SSO。问题是,当我尝试登录到 Keycloak 时,一切都完美而流畅,我获得了有关正确身份验证的信息,获得了令牌,甚至可以毫无问题地解析它,但是在 WebBrowser 中没有创建会话(没有会话,没有 cookie) .这意味着即使正确创建了 Keycloak 中的会话,我也不能将刚刚创建的会话与同一 Keycloak 领域中的其他应用程序一起使用。
在我的桌面适配器“成功”登录尝试后,其他应用程序之前创建和存储的更多 cookie 也被删除(我指的是 KEYCLOAK_IDENTITY 和 KEYCLOAK_INDENTITY_LEGACY 的 cookie)。当我检查浏览器 cookie 时,有一些警告声明说 cookie 因过期而被拒绝。
我用的是KeycloakInstalled适配器(最新,15.0.2版本)。我使用页面上的说明配置它:https://www.keycloak.org/docs/latest/securing_apps/
我认为本例中最重要的一段代码:
KeycloakInstalled keycloak = new KeycloakInstalled();
AdapterConfig config = new AdapterConfig();
Map<String, Object> credentials = new HashMap<String, Object>();
credentials.put("secret", secret);
config.setAuthServerUrl(url);
keycloak.getDeployment().setRealm(realm);
keycloak.getDeployment().setAuthServerBaseUrl(config);
keycloak.getDeployment().setResourceName(resource);
keycloak.getDeployment().setResourceCredentials(credentials);
keycloak.getDeployment().setClientAuthenticator(ClientCredentialsProviderUtils.bootstrapClientAuthenticator(keycloak.getDeployment()));
keycloak.loginDesktop();
在这种情况下,一些 Keycloak 属性在 keycloak.json 文件中静态设置,一些在 Java 中动态设置(如上例)。在 keycloak.json 文件中,一些属性如 realm, auth-server-url, resource 和 secret 都是垃圾数据, 刚好, 因为后面动态设置.
{
"realm": "<realm>",
"auth-server-url": "<url>",
"ssl-required": "external",
"resource": "<keycloak-client>",
"use-resource-role-mappings": true,
"credentials" : {
"secret" : "abc"
},
"truststore" : "<file>.jks",
"truststore-password" : "<password>"
}
Keycloak 的客户端配置我是这样设置的:
Keycloak_configuration
如何避免使用我的桌面适配器删除会话 cookie?
我已经解决了我的问题。一切都与适配器身份验证机制有关。它是这样工作的:
- 适配器连接到 keycloak 以验证用户。
- 然后从第一个 url 标记为 redirect_url 的参数中重定向到地址,以告诉适配器身份验证是肯定的。 请注意,到目前为止,每个 cookie 都已正确设置。
- 然后有另一个重定向到 /delegated 端点,这使所有会话 cookie 都已过期。这一切都归功于Keycloak存储库中的这段代码:
@Path("delegated")
public Response kcinitBrowserLoginComplete(@QueryParam("error") boolean error) {
AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection);
AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), clientConnection);
...
}
我所做的是创建我自己的 CustomKeycloakInstalled class 扩展原始 KeycloakInstalled 我在其中复制了关键方法 loginDesktop() 和其他一些让 loginDesktop() 正常工作的必要方法 - 最重要的是,覆盖函数返回最后一次重定向 url (/delegated) 和我自己的:
private String getRedirectUrl() {
String redirectUrl = CustomKeycloakInstalled.this.getDeployment().getTokenUrl()
.replace("/protocol/openid-connect/token", "/my-endpoint");
if (this.error != null) {
redirectUrl = redirectUrl + "?error=true";
}
return redirectUrl;
}
现在每个 cookie 都已正确设置并且 SSO 工作正常,但 Keycloak 服务器中没有 /my-endpoint 因此最后一步是实施和部署它。我在下面使用了 KeycloakResourceProvider 示例: https://github.com/keycloak/keycloak/tree/master/examples/providers/rest
这真的很简单,所以我所做的就是用 Keycloak 的端点 delegated 的实现替换 get() 方法,但没有使 cookie 片段过期:
@GET
@Produces("text/plain; charset=utf-8")
public Response get(@QueryParam("error") boolean error) {
if (error) {
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class);
return forms
.setAttribute("messageHeader", forms.getMessage(Messages.DELEGATION_FAILED_HEADER))
.setAttribute(Constants.SKIP_LINK, true).setError(Messages.DELEGATION_FAILED).createInfoPage();
} else {
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class);
return forms
.setAttribute("messageHeader", forms.getMessage(Messages.DELEGATION_COMPLETE_HEADER))
.setAttribute(Constants.SKIP_LINK, true)
.setSuccess(Messages.DELEGATION_COMPLETE).createInfoPage();
}
}
然后编译并部署到Keycloak中。