使用 Keycloak 授权在 Docker 容器内调用 Quarkus 应用程序时出现 401 Unauthorized
我有一个在 localhost:4200 (角度应用程序)上运行的客户端应用程序,它从 Quarkus 应用程序( localhost:8082 )获取资源。授权是使用Keycloak
完成的。
如果我同时启动 Angular 和 Angular,授权就可以正常工作。我的本地主机上的 Quarkus 应用程序:
但是,如果我使用 Quarkus 应用程序构建 Docker 映像并在 Docker 容器内运行它,则它不起作用。 Angular 应用程序仍然在我的本地主机上运行,而不是在容器内运行:
我的 Quarkus application.properties:
quarkus.http.port=8082
quarkus.oidc.auth-server-url=http://${KEYCLOAK_HOST:localhost}:${KEYCLOAK_PORT:8081}/auth/realms/the-realm
quarkus.oidc.client-id=the-api
quarkus.oidc.credentials.secret=secret
quarkus.oidc.authentication.scopes=profile
quarkus.http.cors.origins=http://localhost:4200
quarkus.http.cors.methods=GET,PUT,POST,PATCH,DELETE,OPTIONS
quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
quarkus.http.cors=true
发生这种情况是因为容器内的 localhost 不引用我机器的 localhost 吗?那么这个属性将不起作用: quarkus.http.cors.origins=http://localhost:4200 ?我尝试使用 quarkus.http.cors.origins=http://host.docker.internal:4200 ,但它不起作用。
作为初学者,任何建议都值得赞赏,谢谢!
I have a client app running on localhost:4200
(angular app) that gets resources from a Quarkus app( localhost:8082
). The authorization is done using Keycloak
.
The authorization works fine if I start both Angular & Quarkus apps on my localhost:
However, it does not work if I build a Docker image with my Quarkus app and run it inside a Docker container. Angular app still runs on my localhost, not inside a container:
My Quarkus application.properties:
quarkus.http.port=8082
quarkus.oidc.auth-server-url=http://${KEYCLOAK_HOST:localhost}:${KEYCLOAK_PORT:8081}/auth/realms/the-realm
quarkus.oidc.client-id=the-api
quarkus.oidc.credentials.secret=secret
quarkus.oidc.authentication.scopes=profile
quarkus.http.cors.origins=http://localhost:4200
quarkus.http.cors.methods=GET,PUT,POST,PATCH,DELETE,OPTIONS
quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
quarkus.http.cors=true
Does this happen because localhost inside a container does not refer to my machine's localhost ? So this property will have no effect: quarkus.http.cors.origins=http://localhost:4200
? I tried using quarkus.http.cors.origins=http://host.docker.internal:4200
but it did not work..
As a beginner, any advice is apreciated, thank you !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只是为了补充这一点。
我按照上面的建议做了,并阅读了有趣的“更多详细信息”链接,这确实帮助我理解了这个问题,但问题仍然存在。
我最终让它发挥作用,并想扩展上面接受的答案。
正如答案中提到的,需要在领域
Frontend URL
属性中输入正确的值。Frontend URL
表示“您的前端应用程序用于进行身份验证的 Keycloak 公共 url”。因此,就我而言,我在内部网络 (
flowt-net
) 上的容器中使用 Keycloak 20.0.2,以便我的 Quarkus 应用程序可以找到它。我有一个 Vue 3 应用程序来测试身份验证。这是一个开发测试上下文,因此不是有关密码、CORS 等的最佳实践。
Keycloak docker 运行:
网络按照
--net flowt-net
设置。我还有一个名为
keycloak
的 docker 卷来保存内置的 H2 数据库 (-v keycloak:/opt/keycloak/data/h2
)为了进行测试,我从来自 https://quarkus.io/guides/security-openid-connect 的示例应用程序
相关的Quarkus 应用
application.properties
:http://keycloak:8080/realms/quarkus
引用名为keycloak
的 keycloak 容器的 url(--name keycloak
)在内部docker网络上,端口8080
是KC内部端口。即按照-p 8543:8080
。Quarkus 应用程序 docker 构建:
我现在正在使用 JVM 映像测试 dockerization。
Vue 应用程序按如下方式进行身份验证,我将其设置为在 localhost:3123 而不是 localhost:8080 上运行,因此当我试图了解“动物园里的谁是谁”时,我不会对 KC 内部端口号感到困惑。
有关 vueKeycloak 和 vueAxios 的更多信息,请参阅 https://github.com/baloise/vue-keycloak 。
我的 Quarkus 应用程序的 Vue axios 端点是例如
http://localhost:10000/api/users/me
注意:对于构建的 Keycloak 的最新版本使用 Quarkus,身份验证 URL 为
http://localhost:8543/
不是http://localhost:8543/auth
。给定带有
-p 8543:8080
的 Keycloak 映像,您可以使用外部/公共端口,即本例中的8543
。因此,在 Quarkus 领域的 Keycloak 管理中,
Frontend URL
在我的情况下也需要是http://localhost:8543/
,而不是http:// /localhost:8543/auth
这是一些较旧的 SO 帖子所建议的。理论上这应该有效,但事实并非如此。我仍然收到 401 错误。
难题中缺少的部分是我需要删除现有的 Quarkus 应用程序及其所有层,然后从头开始重建。一旦我这样做了,它就神奇地起作用了,我在 Vue 应用程序中的 api 调用开始返回 200。耶!
我希望能为某人节省一些时间!
走好,
穆雷
Just to add to this.
I did as suggested above and read the interesting "more details" link which certainly helped me understand the issue, but the problem remained.
I eventually got it working and wanted to expand on the accepted answer above.
As mentioned in the answer, one needs to put the right value in the realm
Frontend URL
property.Frontend URL
means "the Keycloak public url that your front end app uses to authenticate with".So, in my case, I am using Keycloak 20.0.2 in a container on an internal network (
flowt-net
) so my Quarkus app could find it. I have a Vue 3 app to test the authentication.This is a development test context so is not best practice re passwords, CORS, etc.
The Keycloak docker run:
The network is set as per
--net flowt-net
.I also have a docker volume called
keycloak
to persist the built-in H2 database (-v keycloak:/opt/keycloak/data/h2
)For testing I started with the example app from https://quarkus.io/guides/security-openid-connect
The relevant Quarkus app
application.properties
:The
http://keycloak:8080/realms/quarkus
refers to the url of the keycloak container namedkeycloak
(--name keycloak
) on the internal docker network, and the port8080
is the KC internal port. ie as per-p 8543:8080
.The Quarkus app docker build:
I am testing the dockerisation by using the JVM image for now.
The Vue app authenticates as below and I set it to run on localhost:3123 instead of localhost:8080 so I didn't get confused with the KC internal port number when I was trying to understand "who is who in the zoo".
See https://github.com/baloise/vue-keycloak for more on vueKeycloak and vueAxios.
My Vue axios end point for the Quarkus app is eg
http://localhost:10000/api/users/me
Note: for the more recent versions of Keycloak which were built using Quarkus, the authentication url is
http://localhost:8543/
nothttp://localhost:8543/auth
.Given the Keycloak image with
-p 8543:8080
you use your external / public port ie8543
in this case.In Keycloak admin for the Quarkus realm, the
Frontend URL
therefore needs to also behttp://localhost:8543/
in my case, and nothttp://localhost:8543/auth
which some older SO posts suggest.Theoretically that should have worked, but it didn't. I was still getting 401 errors.
The missing piece in the puzzle was that I needed to remove my existing Quarkus app and all its layers and rebuild it from scratch. Once I did that, it magically worked and my api calls in the Vue app started returning 200. Yay!
I hope that save someone some hours!
Go well,
Murray
最后,这不是 CORS 问题,正如评论中提到的(谢谢@sventorben!),解决方案是进入 Keycloak 领域设置并添加
http://localhost:8081/auth
对于前端 URL
:更多详细信息:https://stackoverflow.com/a/70708121/16357334
In the end it wasn't a CORS problem, as mentioned in the comments (thank you @sventorben!), the solution was to go into Keycloak realm settings and add
http://localhost:8081/auth
forFrontend URL
:More details here: https://stackoverflow.com/a/70708121/16357334