我在official keycloak example app的受保护的node.js应用中收到访问被拒绝的错误
受保护的应用程序已被docker化,并置于本身已被dockerized的应用程序网关后面。
应用程序网关是node.js Express应用程序,它使用http / https程序包并将传入流量路由到node.js安全应用程序。
因此,要访问应用程序URL,已将映射的URL添加到网关:
mappings:
- /:/
- /login:/login
- /logout:/logout
- /protected/resource:/protected/resource
Gateway不会进行ssl卸载。 Keycloak也被泊坞窗化,其 / auth 端点也映射到网关内部。
应用代码如下:
var Keycloak = require('keycloak-nodejs-connect');
var hogan = require('hogan-express');
var express = require('express');
var session = require('express-session');
var app = express();
var server = app.listen(3005, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
app.set('view engine', 'html');
app.set('views', require('path').join(__dirname, '/view'));
app.engine('html', hogan);
app.enable('trust proxy')
var memoryStore = new session.MemoryStore();
app.use(session({
secret: 'mySecret',
resave: false,
saveUninitialized: true,
store: memoryStore
}));
app.get('/', function (req, res) {
res.render('index');
});
var memoryStore = new session.MemoryStore();
app.use(session({
secret: 'mySecret',
resave: false,
saveUninitialized: true,
store: memoryStore
}));
// Additional configuration is read from keycloak.json file
// installed from the Keycloak web console.
var keycloak = new Keycloak({
store: memoryStore
});
app.use(keycloak.middleware({
logout: '/logout',
admin: '/',
protected: '/protected/resource'
}));
app.get('/login', keycloak.protect(), function (req, res) {
res.render('index', {
result: JSON.stringify(JSON.parse(req.session['keycloak-token']), null, 4),
event: '1. Authentication\n2. Login'
});
});
app.get('/protected/resource', keycloak.enforcer(['resource:view', 'resource:write'], {
resource_server_id: 'nodejs-apiserver'
}), function (req, res) {
res.render('index', {
result: JSON.stringify(JSON.parse(req.session['keycloak-token']), null, 4),
event: '1. Access granted to Default Resource\n'
});
});
keycloak.json 是:
{
"realm" : "nodejs-example",
"realm-public-key" : "[public_key]",
"auth-server-url" : "https://[https://[gateway_url]]/auth",
"ssl-required" : "none",
"resource" : "nodejs-connect",
"public-client" : true
}
在浏览器中访问 https://[gateway_url]/ 时,KeyCloak重定向到登录ui,在登录ui中输入用户名/密码,然后在浏览器中看到拒绝访问错误。 / p>
以下错误在应用程序日志中弹出:
无法获得授权码错误:{错误:自签名证书 在证书链中
因此,基本上,该应用无法交换访问令牌的授权代码。
我尝试过的事情:
1)如下所示,通过curl访问Keycloak令牌端点成功(返回访问/刷新令牌):
curl -k --key [keypath] --cert [certpath:passphrase] -d "grant_type=authorization_code&client_id=nodejs-connect&redirect_uri=https://[gw_url]/login?auth_callback=1&client_session_state=[client_state]&code=[authz_code]
-X POST 'https://[gw_url]/auth/realms/nodejs-example/protocol/openid-connect/token'
2)将“ auth-server-url ”更改为“ https ://:// [gateway_url]: keycloak.json 中的8080 / auth ”也有帮助。返回访问令牌。 8080是Keycloak docker容器的已发布端口。
因此,我想问题是应用程序中的node.js适配器在想要用访问令牌替换authz代码时不会向网关提供ssl证书。因此,我尝试将auth-server-url更改为相对/ auth。但是
无法获得授权代码错误:{错误:连接ECONNREFUSED 127.0.0.1:80
会在应用程序的日志中弹出。
如何正确配置keycloak node.js适配器以保护应用程序网关后面的服务?
答案 0 :(得分:1)
嘿,我也遇到了同样的错误,并通过在keycloak.json中输入LAN ip地址而不是主机名来解决。