使用 nginx 反向代理后面的 keycloak 保护 nodejs 中的路由
Posted
技术标签:
【中文标题】使用 nginx 反向代理后面的 keycloak 保护 nodejs 中的路由【英文标题】:protecting route in nodejs with keycloak behind nginx reverse proxy 【发布时间】:2019-11-26 12:08:38 【问题描述】:我启动了一个 keycloak 容器:
docker run --name keycloak -p 8080:8080 -e PROXY_ADDRESS_FORWARDING=true -d jboss/keycloak
配置了一个nginx反向代理:
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
server
listen 80;
listen [::]:80;
server_name 192.168.32.132;
return 301 https://$server_name$request_uri;
server
listen 443 ssl;
listen [::]:443 ssl;
server_name 192.168.32.132;
ssl_certificate /etc/ssl/private/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location /login
proxy_pass http://127.0.0.1:9080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location /auth
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location /app
rewrite ^/app(.*)$ $1 last;
proxy_pass http://localhost:7080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
然后我启动了一个 nodeJS 服务器,在用户可以访问应用程序之前,它需要一些自定义逻辑:
// Setup Axios HTTP Request client
AXIOS.defaults.baseURL = CONF.URL;
AXIOS.defaults.headers.common['apikey'] = CONF.apiKey;
// Setup keycloak to use the session memoryStore
var memoryStore = new SESSION.MemoryStore();
var keycloak = new KEYCLOAK( store: memoryStore );
// Set up a server instance and create a session middleware
const APP = EXPRESS();
APP.use(SESSION(
secret: CRYPTO.randomBytes(512).toString('hex'),
resave: false,
saveUninitialized: true,
store: memoryStore
));
// Default route handler
APP.get('/login', keycloak.protect(), function(req, res)
console.log('%s accessing protected route', req.get('X-Forwarded-For'));
let sessionID = '';
let tokenID = '';
// Dispatch requests to APP's REST Endpoints
AXIOS(
method:'POST',
url: 'session',
headers: 'Accept': 'application/json'
)
.then(response =>
if (response.status == 201)
sessionID = response.data['sessionId'];
console.log('Received session %s', sessionID);
return AXIOS(
method:'POST',
url: 'session/' + sessionID + '/token',
headers: 'Accept': 'application/json',
);
else throw new ServerError(response);
)
.then(response =>
if (response.status == 201)
tokenID = response.data['tokenId'];
console.log('Received token %s', tokenID);
res.redirect('/app/html/createCustomer?' + QUERYSTRING.encode('tokenId': tokenID));
)
.catch( error => console.log('Error', error.message);
);
);
APP.use(keycloak.middleware( logout: '/logout'));
// Start servers
HTTP.createServer(APP).listen(CONF.serverPort, CONF.serverInterface, () =>
console.log('Server listening on %s:%d', CONF.serverInterface,
CONF.serverPort));
CONF.serverPort=9080
和 CONF.serverInterface=127.0.0.1
的位置。
keycloak 服务器管理控制台中的 keycloak.json 读取
"realm": "app-realm",
"auth-server-url": "https://192.168.32.132/auth",
"ssl-required": "external",
"resource": "app-client",
"public-client": true,
"confidential-port": 0
在 keycloak 管理控制台上,我添加了一个用户。客户端的重定向 URL 设置为通配符。
当我在路由 /login 访问 VM 的 IP 192.168.32.132 时,我被重定向到 keycloak 登录页面,该页面告诉我更改用户的初始密码。
无论我尝试什么,每次进一步的登录尝试都会导致:ERROR_TOO_MANY_REDIRECTS。
【问题讨论】:
【参考方案1】:当您尝试访问 /auth
路径下的 keycloak 时,它会将您重定向到
要解决这个问题,请在您的 ngnix 配置中 /auth
和 proxy_pass 之后添加 /
:
location /auth/
proxy_pass http://localhost:8080/;
...
【讨论】:
以上是关于使用 nginx 反向代理后面的 keycloak 保护 nodejs 中的路由的主要内容,如果未能解决你的问题,请参考以下文章
在反向代理后面使用 Keycloak:无法打开管理员登录页面,因为内容混合
keycloak 无效参数:redirect_uri 在反向代理后面