我当前的用例是:我有一个前端应用程序,用户通过 Keycloak 登录。我想在这个前端(https://www.eclipse.org/ditto/http-api-doc.html)中实现 Ditto HTTP API 的某些部分。
例如,我想为授权创建策略( https://www.eclipse.org/ditto/basic-policy.html )。我在文档中读到可以使用符合 OpenID Connect 的提供程序,其形式为:(https://www.eclipse.org/ditto/basic-policy.html#who-can-be-addressed)。
页面底部有基本的身份验证示例,在这种情况下似乎使用用户名。
{
"policyId": "my.namespace:policy-a",
"entries": {
"owner": {
"subjects": {
"nginx:ditto": {
"type": "nginx basic auth user"
}
},
...
}
我的问题是:如果我想使用 Keycloak,子声明到底是什么?它也是我要授予权限的用户的用户名吗?以及如何在我想指定之后将其发送到 Ditto 的策略的前端中获取此信息?
更新 1:
我尝试在 Ditto 中启用 keycloak 身份验证,如下所示,如下所述:https ://www.eclipse.org/ditto/installation-operating.html#openid-connect
因为我使用 Docker Compose 运行 Ditto,所以我在第 136 行的 ditto/deployment/docker/docker-compose.yml 中添加了以下行作为环境变量:- Dditto.gateway.authentication.oauth.openid-connect-issuers.keycloak=http://localhost:8090/auth/realms/twin
此 URL 与我的令牌的颁发者声明中的相同'我从 keycloak 接收。
现在,如果我尝试使用 Postman 向 {{basePath}}/things 发出例如发布请求,我会收到以下错误:
<html>
<head>
<title>401 Authorization Required</title>
</head>
<body bgcolor="white">
<center>
<h1>401 Authorization Required</h1>
</center>
<hr>
<center>nginx/1.13.12</center>
</body>
</html>
我在 Postman 中选择了 Bearer Token 作为 Auth 并粘贴了一个新的令牌。具有默认同上用户的基本身份验证仍在工作。
我之前是否必须在同上指定新主题/我的用户?
更新 2:
我设法通过在 nginx.conf 中注释掉“auth_basic”和“auth_basic_user_file”来关闭 nginx 中的基本身份验证!
它现在似乎被转发到同上,因为现在我收到 Postman 的以下错误:
{
"status": 401,
"error": "gateway:jwt.issuer.notsupported",
"message": "The JWT issuer 'localhost:8090/auth/realms/twin' is not supported.",
"description": "Check if your JWT is correct."
}
更新 3:
我在 gateway.conf 中的配置现在看起来像这样:
oauth {
protocol = "http"
openid-connect-issuers = {
keycloak = "localhost:8090/auth/realms/twin"
}
}
我还尝试在 docker-compose.yml 中添加这两行:
- Dditto.gateway.authentication.oauth.protocol=http
- Dditto.gateway.authentication.oauth.openid-connect-issuers.keycloak=localhost:8090/auth/realms/twin
不幸的是,我仍然没有运气,与上述相同的错误:/似乎用户之前在 keycloak 上遇到过类似的问题(https://gitter.im/eclipse/ditto?at=5de3ff186a85195b9edcb1a6),但遗憾的是他没有提到解决方案。
编辑:事实证明,我以错误的方式指定了这些变量,正确的解决方案是将它们作为command: java ...
更多信息的一部分添加到此处
更新 4:
我尝试在本地构建 Ditto 而不是使用最新的 docker 映像,我想我现在可能更进一步,看起来我的 oauth 配置正在工作。我现在得到:
{
"status": 503,
"error": "gateway:publickey.provider.unavailable",
"message": "The public key provider is not available.",
"description": "If after retry it is still unavailable, please contact the service team."
}
日志中的错误消息是:
gateway_1 | 2020-11-05 15:33:18,669 WARN [] o.e.d.s.g.s.a.j.DittoPublicKeyProvider - Got Exception from discovery endpoint <http://localhost:8090/auth/realms/twin/.well-known/openid-configuration>.
gateway_1 | akka.stream.StreamTcpException: Tcp command [Connect(localhost:8090,None,List(),Some(10 seconds),true)] failed because of java.net.ConnectException: Connection refused
gateway_1 | Caused by: java.net.ConnectException: Connection refused
...
gateway_1 | java.util.concurrent.CompletionException: org.eclipse.ditto.services.gateway.security.authentication.jwt.PublicKeyProviderUnavailableException [message='The public key provider is not available.', errorCode=gateway:publickey.provider.unavailable, statusCode=SERVICE_UNAVAILABLE, description='If after retry it is still unavailable, please contact the service team.', href=null, dittoHeaders=ImmutableDittoHeaders [{}]]
...
gateway_1 | Caused by: org.eclipse.ditto.services.gateway.security.authentication.jwt.PublicKeyProviderUnavailableException [message='The public key provider is not available.', errorCode=gateway:publickey.provider.unavailable, statusCode=SERVICE_UNAVAILABLE, description='If after retry it is still unavailable, please contact the service team.', href=null, dittoHeaders=ImmutableDittoHeaders [{}]]
...
gateway_1 | Caused by: akka.stream.StreamTcpException: Tcp command [Connect(localhost:8090,None,List(),Some(10 seconds),true)] failed because of java.net.ConnectException: Connection refused
gateway_1 | Caused by: java.net.ConnectException: Connection refused
我的 keyloak 肯定在运行,我可以获得代币。如果我正在打开http://localhost:8090/auth/realms/twin/.well-known/openid-configuration
第一条错误消息中的内容,我可以从 keycloak 配置中看到我的 openid 配置。编辑:似乎我的网关容器无法到达我的 keycloak 容器,将尝试解决这个问题。
最后更新:
来自网关 docker 容器的无法访问的 keycloak docker 容器是问题所在。我现在正在使用 traefik:
- Keycloak 容器具有以下别名:keycloak.localhost
- 网关中的 Oauth 配置如下所示:
oauth {
protocol = "http"
openid-connect-issuers = {
keycloak = "keycloak.localhost/auth/realms/twin"
}
}
- 现在网关可以通过别名找到 keycloak 容器,我仍然可以使用本地主机中的 keycloak admin ui:http://keycloak.localhost:8090/auth/admin/
附加信息:Traefic 博客