the*_*pan 8 oauth-2.0 docker keycloak
我正处于构建网络应用程序的早期阶段。我打算使用 Keycloak 作为身份提供者来保护后端。在我的本地计算机上,我将 Keycloak 和后端都作为 docker 容器运行,但在不同的网络上,因为最终在生产中,我希望运行 Keycloak 的身份验证服务器与后端分别运行,例如account.example.com和api.example.com分别
在本地,我的 Keycloak 容器可以通过基本 URL 访问http://localhost:8080/auth,后端通过http://test.localhost:8000/
我在 Keycloak 领域创建了一个客户端,其访问类型是机密的。我正在使用授权代码授予类型生成令牌。
因此,后端的每个 REST API 端点都会验证传递到授权标头的令牌,然后在处理请求之前调用 Keycloak 服务器来验证令牌。
我目前遇到的问题是令牌验证失败并响应
{"error":"invalid_token","error_description":"Token verification failed"}'
Run Code Online (Sandbox Code Playgroud)
经过调查,显然,这是因为我从后端 API 容器调用 Keycloak 服务器。如果我在后端 docker 容器内使用curl 生成令牌,则我收到的令牌可以正常验证,但在容器外部生成的令牌则不能。
我用作python-keycloakKeycloak REST API 的包装器
from keycloak import KeycloakOpenID
self._keycloak = KeycloakOpenID(
server_url='http://host.docker.internal:8080/auth/',
realm_name='myrealm',
client_id='myclient',
client_secret_key='mysecret,
)
if "HTTP_AUTHORIZATION" not in request.META:
return JsonResponse(
{"detail": NotAuthenticated.default_detail},
status=NotAuthenticated.status_code,
)
auth_header = request.META.get("HTTP_AUTHORIZATION").split()
token = auth_header[1] if len(auth_header) == 2 else auth_header[0]
try:
self.keycloak.userinfo(token)
except KeycloakInvalidTokenError as e:
# print(e)
return JsonResponse(
{"detail": AuthenticationFailed.default_detail},
status=AuthenticationFailed.status_code,
)
Run Code Online (Sandbox Code Playgroud)
如何解决此问题并在本地计算机上进行令牌验证
sve*_*ben 13
您的令牌无效,因为iss令牌中的颁发者 ( ) 与您的后端服务期望的颁发者不匹配。
您的后端(或后端中的适配器/框架)将使用 OIDC 发现协议来确定预期的发行者。为此,它将调用https://keycloak-container-name/auth/realms/<your-realm>/.well-known/openid-configuration. 这将返回如下元数据:
{
"issuer":"https://keycloak-container-name/auth/realms/<your-realm>",
...
}
Run Code Online (Sandbox Code Playgroud)
keycloak-container-nameKeycloak将根据请求确定发行者的主机部分(在本例中)。因此,如果您的后端从 docker 网络内查询发现端点keycloak-container-name,则主机部分将为your-container-name. 您的后端将期望发行人处于https://keycloak-container-name/auth/realms/<your-realm>这种情况。
现在,如果您想从前端查询令牌,您的前端会将请求发送到http://localhost:8080/auth/.... 由于发行者将根据请求确定,因此该令牌中的发行者将是https://localhost:8080/auth/realms/<your-realm>这种情况。这与预期的发行者不匹配https://keycloak-container-name/auth/realms/<your-realm>,因此令牌将被视为无效而被拒绝。
您还可以通过调用 OIDC 发现端点来验证这一点http://localhost:8080/auth/realms/<your-realm>/.well-known/openid-configuration。您将得到如下响应:
{
"issuer":"http://localhost:8080/auth/realms/<your-realm>",
...
}
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您可以将Frontend URL您的领域设置为http://localhost:8080/auth。通过此设置,发行人将不再在请求中确定,而是被修复http://localhost:8080/auth/realms/<your-realm>。您可以通过向 发出请求,从后端容器中检查这一点https://keycloak-container-name/auth/realms/<your-realm>/.well-known/openid-configuration。现在将返回如下元数据:
{
"issuer":"http://localhost:8080/auth/realms/<your-realm>",
...
}
Run Code Online (Sandbox Code Playgroud)
如果您不想为每个领域单独配置此选项,则可以在服务器范围内配置默认主机名提供程序。
| 归档时间: |
|
| 查看次数: |
10316 次 |
| 最近记录: |