从两个不同的 URL 验证 Keycloak 令牌 [英] Verify Keycloak token from two different URLs
问题描述
我有一个基于 Docker compose
的系统,带有后端和前端组件.后端使用 Python Flask
编写并在多个 docker 容器中运行,前端使用 TypeScript
和 Angular
编写.前端通过 Restful API 与后端通信.代理是使用 Nginx
创建的.但是Keycloak
令牌验证在前端和后端之间不起作用.
我的KeyCloak
(和MySQL
)部分docker-compose.yml
文件:
mysql:图像:mysql:5.7.31端口:- 9988:3306卷:- keycloak_data:/var/lib/mysql环境:MYSQL_ROOT_PASSWORD:rootMYSQL_DATABASE:钥匙斗篷MYSQL_USER:钥匙斗篷MYSQL_PASSWORD:密码网络:- auth_net钥匙斗篷:图片:jboss/keycloak:13.0.1环境:DB_VENDOR:MYSQLDB_ADDR: mysqlDB_DATABASE:密钥斗篷DB_USER:钥匙斗篷DB_PASSWORD:密码KEYCLOAK_USER:管理员KEYCLOAK_PASSWORD:管理员PROXY_ADDRESS_FORWARDING:真";端口:- 8080:8080- 8443:8443取决于:- mysql网络:- auth_net
相关Nginx
配置部分:
location/api/auth/verify {内部的;proxy_method POST;proxy_intercept_errors on;proxy_pass http://keycloak:8080/auth/realms/master/protocol/openid-connect/userinfo;error_page 400 =401/401.html;}
我对每个端点使用上述 /api/auth/verify
URL 作为验证.例如:
位置/api/users {auth_request/api/auth/verify;重写 ^/api/(.*)/$1 中断;proxy_pass http://users:6000;proxy_pass_request_headers 开启;proxy_set_header 主机 $host;proxy_set_header X-Real-IP $remote_addr;}
我的 Keycloak
TypeScript
/Angular
配置:
export const environment = {生产:假,密钥斗篷配置:{url: 'http://localhost:8080/auth/',领域:'主人',客户 ID:'前端'}};
app-init.ts
:
import { KeycloakService, KeycloakOptions } from 'keycloak-angular';从'src/environments/environment'导入{环境};导出函数初始值设定项(keycloak:KeycloakService):()=>承诺<任何>{const 选项:KeycloakOptions = {配置:environment.keycloakConfig};return(): PromiseKeycloak
中frontend
客户端的配置:
我的问题:
Nginx
使用 http://keycloak:8080
URL,它是 docker 系统内部的网络(Nginx
没有查看 Docker
中的 localhost
).- 前端 (
TS
/Angular
) 使用从外部可见的 http://localhost:8080
URL(从用户的浏览器)(理论上前端不会从用户的浏览器看到 keycloak
网络) - 当我从调用我的 API 的前端发送请求(想要根据上述
Nginx
示例验证令牌)时,我收到 Invalid Token
错误 - 根据我的调查,我收到此错误是因为我在
http://localhost:8080
URL 上获得了令牌,并且我想在 http://keycloak 上验证它:8080
网址.
我使用过的网址汇总:
- API 的 URL:
http://localhost
- Docker 中的 Keycloak URL:
http://keycloak:8080
- 前端的Keycloak:
http://localhost:8080
- Fornt-end 的 URL :
http://localhost:4200
我的问题:
- 如何解决上述问题?我对想法非常开放.
1.
如果我尝试将前端 URL 设置为 http://localhost:8080
和 http://localhost:4200
但我得到以下两种情况下的问题:
解决方案 我刚刚找到了解决方案!
Frontend URL
参数在 Keycloak
常规配置中是一个相当误导的参数.我的前端在 http://localhost:4200
URL 上,但正如我在问题中提到的,URL 不能作为 Keycloak 中的前端 URL 参数(我已经测试了很多次).
正如您在 keycloak-angular
模块配置中的问题中所见,Keycloak
URL 设置为 url: 'http://localhost:8080/auth/'
.如果我将该 URL 设置为 Keycloak
常规配置中的 Frontend URL
参数(或作为 docker-compose.yml
文件中的输入参数)我的系统很有魅力.
注意:
- 基本 URL (
http://localhost:8080
) 是不够的,所以还需要 /auth
后缀(有效的完整 URL:http://localhost:8080/auth/
).
I have a Docker compose
based system with back-end and front-end components. The back-end is written in Python Flask
and run in several docker containers and front-end is written in TypeScript
with Angular
. The front-end communicates with back-end via Restful APIs. The proxy is created with Nginx
. But the Keycloak
Token verification doesn't work between front-end and back-end.
My KeyCloak
(and MySQL
) section of docker-compose.yml
file:
mysql:
image: mysql:5.7.31
ports:
- 9988:3306
volumes:
- keycloak_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak
MYSQL_PASSWORD: password
networks:
- auth_net
keycloak:
image: jboss/keycloak:13.0.1
environment:
DB_VENDOR: MYSQL
DB_ADDR: mysql
DB_DATABASE: keycloak
DB_USER: keycloak
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
PROXY_ADDRESS_FORWARDING: "true"
ports:
- 8080:8080
- 8443:8443
depends_on:
- mysql
networks:
- auth_net
Related Nginx
config part:
location /api/auth/verify {
internal;
proxy_method POST;
proxy_intercept_errors on;
proxy_pass http://keycloak:8080/auth/realms/master/protocol/openid-connect/userinfo;
error_page 400 =401 /401.html;
}
I use the above /api/auth/verify
URL for every endpoints as verification. Eg.:
location /api/users {
auth_request /api/auth/verify;
rewrite ^/api/(.*) /$1 break;
proxy_pass http://users:6000;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
My Keycloak
config for TypeScript
/Angular
:
export const environment = {
production: false,
keycloakConfig: {
url: 'http://localhost:8080/auth/',
realm: 'master',
clientId: 'frontend'
}
};
app-init.ts
:
import { KeycloakService, KeycloakOptions } from 'keycloak-angular';
import { environment } from 'src/environments/environment';
export function initializer(keycloak: KeycloakService): () => Promise<any> {
const options: KeycloakOptions = {
config: environment.keycloakConfig
};
return (): Promise<any> => keycloak.init(options);
}
My app.module.ts
file contains the following section:
providers: [
KeycloakService,
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
]
The getting error:
Config of frontend
client in Keycloak
:
My problem in points:
- The
Nginx
uses the http://keycloak:8080
URL which is the network inside the docker system (The Nginx
doesn't see the localhost
from Docker
).
- The front-end (
TS
/Angular
) uses the http://localhost:8080
URL which is visible from outside (from the users' browser) (In theory the front-end doesn't see the keycloak
network from user's browser)
- When I send a request from front-end which calls my API (which want to verify the token based on above
Nginx
example), I get Invalid Token
error
- Based on my investigation I get this error because I get the token on
http://localhost:8080
URL and I want to verify it on http://keycloak:8080
URL.
Summarize of my used URLs:
- API's URL:
http://localhost
- Keycloak URL inside Docker:
http://keycloak:8080
- Keycloak on front-end side:
http://localhost:8080
- Fornt-end's URL :
http://localhost:4200
My question:
- How can I solve the above problem? I am very open for ideas.
1. EDIT:
If I have tried to set the front-end URL to http://localhost:8080
, and http://localhost:4200
but I got the below issue in both cases:
解决方案 I have just found the solution!
The Frontend URL
parameter is a quite misleading in the Keycloak
general configuration. My front-end is on http://localhost:4200
URL but as I mentioned in my question that URL wasn't working as front-end URL parameter in Keycloak (I have tested is many times).
As you can see in my question in the configuration of keycloak-angular
module the Keycloak
URL is set as url: 'http://localhost:8080/auth/'
. If I set that URL as Frontend URL
parameter in the Keycloak
general configuration (or as input parameter in docker-compose.yml
file) my system works as charm.
Note:
- The base URL (
http://localhost:8080
) is not enough so the /auth
suffix is also needed (The full URL which is working: http://localhost:8080/auth/
).
这篇关于从两个不同的 URL 验证 Keycloak 令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!