【发布时间】:2020-10-31 17:56:36
【问题描述】:
我当前的用例是:我有一个用户通过 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)。
页面底部有基本的auth示例,在这种情况下似乎使用了用户名。
{
"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 ... 的一部分更多信息here
更新 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 管理 ui:http://keycloak.localhost:8090/auth/admin/
其他信息:Traefic Blog
【问题讨论】:
-
401好像是nginx发出的。你还在nginx里配置基本的auth吗?如果是这种情况,请求永远不会到达同上。
-
docker-compose.yml 中的 ENABLE_DUMMY_AUTH=true 仍然打开。这是你的意思吗?我把它关掉了,所以默认的同上用户不再使用基本身份验证。另外我设置了 ENABLE_PRE_AUTHENTICATION=false。但是当我切换到 Bearer 时,它仍然是和以前一样的错误消息。我不知道如何正确禁用基本身份验证,您能否再给我一个提示?我必须调整文件 nginx.conf 吗?
-
我更新了 openid-connect-issuer 的配置部分。似乎该方案不能成为发行人配置的一部分,但需要在 oauth 级别进行配置(适用于所有发行人)。我不建议在这里使用http。
-
我解决了并更新了解决方案!再次感谢您!
-
我很乐意提供帮助!但我仍然想知道为什么我不能让它与预先构建的 docker 图像一起使用。似乎我的环境变量根本不起作用,因此它说仍然不受支持的 jwt 发行者,因为配置列表为空..