首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Keycloak桌面java适配器删除KEYCLOAK_IDENTITY cookie。

Keycloak桌面java适配器删除KEYCLOAK_IDENTITY cookie。
EN

Stack Overflow用户
提问于 2021-08-31 15:16:01
回答 1查看 299关注 0票数 2

我对Keycloak java适配器有问题。我尝试将桌面应用程序与Keycloak集成起来,并在其他几个web应用程序之间启用SSO。问题是,当我尝试登录到Keycloak时,一切都很完美和流畅,我可以获得有关正确身份验证的信息,获得令牌,甚至可以在没有任何问题的情况下解析它,但是在WebBrowser中没有创建会话(没有会话,也没有cookie)。这意味着,我不能使用刚创建的会话与其他应用程序在同一个密钥披风领域,即使会话在键盘斗篷正确地创建。

更重要的是,之前由其他应用程序创建和存储的cookie在我的桌面适配器“成功”登录尝试之后也会被删除(我指的是KEYCLOAK_IDENTITY和KEYCLOAK_INDENTITY_LEGACY)。当我检查浏览器cookie时,有一些警告语句说,cookie由于过期而被拒绝。

我使用的是KeycloakInstalled适配器(最新版本为15.0.2版本)。我使用页面上的指令配置它:https://www.keycloak.org/docs/latest/securing_apps/

在本例中,我认为最重要的代码是:

代码语言:javascript
复制
            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文件中,一些属性(如领域、auth url、资源和机密)会被垃圾数据填充,因为它们是稍后动态设置的。

代码语言:javascript
复制
{
  "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的客户端配置,我设置如下:

配置

如何避免使用桌面适配器删除会话cookie?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-03 11:00:26

我已经解决了我的问题。这一切都是关于适配器认证机制。它的工作原理是:

  1. 适配器连接到keycloak以验证用户身份。
  2. 然后从标记为redirect_url的第一个url的参数中进行重定向,以告诉适配器身份验证是肯定的。注意,到目前为止,每个cookie的设置都是正确的。
  3. 然后还有另一个重定向到/delegated端点,这使得所有会话cookie都过期了。这一切都是由于Keycloak存储库中的代码片段造成的:
代码语言:javascript
复制
    @Path("delegated")
    public Response kcinitBrowserLoginComplete(@QueryParam("error") boolean error) {
        AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection);
        AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), clientConnection);
        ...
    }

来源:https://github.com/keycloak/keycloak/blob/d29d945cc4f5674ecff58cf5bf6bb65933f65cad/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java#L295

我所做的是创建自己的CustomKeycloakInstalled类,扩展原始的KeycloakInstalled,在该类中复制键方法loginDesktop()和其他一些必要的方法,让loginDesktop()正常工作--最重要的是,用自己的函数返回返回最后重定向url (/delegated)的函数:

代码语言:javascript
复制
        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服务器中没有/我的端点,所以最后一步是实现和部署它。我在下面使用了KeycloakResourceProvider示例:https://github.com/keycloak/keycloak/tree/master/examples/providers/rest

这真的很简单,所以我所做的是将get()方法替换为已委托的Keycloak端点的实现,但没有到期的cookie片段:

代码语言:javascript
复制
    @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中部署。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69001263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档