Keycloak 客户端没有可用于访问类型公共的秘密

Posted

技术标签:

【中文标题】Keycloak 客户端没有可用于访问类型公共的秘密【英文标题】:Keycloak Client doesn't have secret available with Access Type Public 【发布时间】:2018-08-08 09:51:26 【问题描述】:

我正在使用 Keycloak 3.4.3 并保护基于 Spring 的 Rest 服务。

下面是Keycloak客户端配置:

Client Protocol: openid-connect<br>
Access Type: public<br>
Standard Flow Enabled: ON<br>
Implicit Flow<br>
Direct Access Grants Enabled: ON<br>
Authorization Enabled: OFF<br>

提供具有公开访问类型的机密是否重要。如果是,我该如何提供秘密,因为我在 Keycloak 客户端配置中找不到任何选项。请帮忙。

2018-02-28 15:19:10.216 警告 7813 --- [nio-8080-exec-2] a.a.ClientIdAndSecretCredentialsProvider:客户端“democlientid” 没有可用的秘密 2018-02-28 15:19:10.375 错误 7813 --- [nio-8080-exec-2] okadapters.OAuthRequestAuthenticator : 失败 把代码变成token

java.net.ConnectException:连接被拒绝(连接被拒绝) 在 java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na] 在 java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400) 〜[无:无] 在 java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243) 〜[无:无] 在 java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225) 〜[无:无] 在 java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402) 〜[无:无] 在 java.base/java.net.Socket.connect(Socket.java:591) ~[na:na] 在 org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.5.jar!/:4.5.5] 在 org.keycloak.adapters.ServerRequest.invokeAccessCodeToToken(ServerRequest.java:111) ~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final] 在 org.keycloak.adapters.OAuthRequestAuthenticator.resolveCode(OAuthRequestAuthenticator.java:336) ~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final] 在 org.keycloak.adapters.OAuthRequestAuthenticator.authenticate(OAuthRequestAuthenticator.java:281) ~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final] 在 org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:139) ~[keycloak-adapter-core-3.4.3.Final.jar!/:3.4.3.Final] 在 org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.authenticateInternal(AbstractKeycloakAuthenticatorValve.java:203) ~[spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final] 在 org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve.authenticate(KeycloakAuthenticatorValve.java:50) [spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final] 在 org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve.doAuthenticate(KeycloakAuthenticatorValve.java:57) [spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final] 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:586) [tomcat-embed-core-8.5.27.jar!/:8.5.27] 在 org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181) ~[spring-boot-container-bundle-3.4.3.Final.jar!/:3.4.3.Final] 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.27.jar!/:8.5.27]

【问题讨论】:

【参考方案1】:

如果其他人发现这个问题 - 答案似乎是公共访问类型仅用于使用 Keycloak 的 UI 进行浏览器登录。例如,您不能将 Spring UI 与 Keycloak 插件一起使用 - 它们必须使用机密访问类型(在这种情况下,您会在管理 UI 的 Clients 部分中获得一个“Credentials”选项卡来提供机密)。

查看https://www.keycloak.org/docs/4.8/server_admin/#oidc-clients 并向下滚动到“访问类型”

【讨论】:

【参考方案2】:

如果您检查master 领域下的客户端admin-cli,您将很容易理解为什么默认为该客户端提及access-type=public。 仅供参考,请从官方文件中查看以下详细信息

访问类型

这定义了 OIDC 客户端的类型。

    机密访问类型适用于需要执行浏览器登录并在将访问代码转换为访问令牌时需要客户端密码的服务器端客户端(有关详细信息,请参阅 OAuth 2.0 规范中的访问令牌请求细节)。这种类型应该用于服务器端应用程序。 公开

    公共访问类型适用于需要执行浏览器登录的客户端客户端。对于客户端应用程序,无法保证机密安全。相反,通过为客户端配置正确的重定向 URI 来限制访问非常重要。

    Bearer-only 访问类型意味着应用程序只允许不记名令牌请求。如果开启,此应用程序将无法参与浏览器登录。

所以您的客户具有公共访问类型,因此这意味着您要登录客户端站点应用程序,因此对于公共访问类型,keyclock 不会提供密钥。

除了你的问题,另一个好处是,用户也可以在命令提示符下使用 keyclock。你可以这样登录

/opt/keycloak/bin/kcadm.sh config credentials --server https://<IP ADDRESS>:8666/auth --realm master --user admin --password admin --client admin-cli

您可以执行类似的管理任务

    创建一个新领域。 在新领域下创建客户端 创建用户/组等

【讨论】:

我知道这是一个小小的旧线程,但我在这里有一个问题。我想在 keycloak 中启用授权,这需要将 keycloak 客户端设置为机密。在这种情况下,我的 webapp 客户端将如何在这里工作(因为他们无法使用秘密)? Webapp 客户端在身份验证后从服务器获取会话 ID(其中 keycloak 使用 oidc 登录运行),但它不适用于具有不同 uri 的其他 rest 调用。【参考方案3】:

你有一个配置错误;服务器地址不对。

【讨论】:

以上是关于Keycloak 客户端没有可用于访问类型公共的秘密的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从公共客户端发出的令牌查询 keycloak 资源权限

Keycloak - 密码重置后自动登录

撤销 Keycloak 访问令牌

Keycloak 注销不适用于公开 REST 服务的“仅承载”应用程序

Keycloak公共客户端和授权

Keycloak 使用不同的客户端重新验证经过身份验证的用户