[keycloak-user] redirect based authentication flow in secured by keycloak node.js app behind application gateway

Roman O warrior7089 at gmail.com
Tue Oct 9 07:09:02 EDT 2018


I'm getting access denied errors in secured node.js app which is an official
keycloak example app
<https://github.com/keycloak/keycloak-nodejs-connect/tree/master/example>

Secured app was dockerized and put behind application gateway which is
itself dockerized.

The application gateway is node.js express application which uses
http/https packages and routes incoming traffic to node.js secured app.

So, to access app url mapped urls were added to the gateway:

 mappings:
    - /:/
    - /login:/login
    - /logout:/logout
    - /protected/resource:/protected/resource

Gateway does ssl offloading. Keycloak was dockerized too and its
*/auth* endpoint
was mapped inside the gateway.

The app code is below:

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* is:

{
  "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}

When *https://[gateway_url]/ <https://[gateway_url]/>* is accessed in the
browser, KeyCloak redirects to login ui, user/password is entered in the
login ui and after that access denied error is seen in the browser.

Below error is popped in the app logs:

Could not obtain grant code error: { Error: self signed certificate in
certificate chain

So basically the app fails to exchange authorization code for access token.

*What i tried:*

1) Accessing Keycloak token endpoint with curl as follows succeeds
(Access/Refresh token is returned):

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]

2) changing "*auth-server-url*" to "*https**://[gateway_url]:8080/auth*" in
*keycloak.json* helped too. Access token is returned. 8080 is published
port of Keycloak docker container.

So, i guess the issue is that node.js adapter in the app doesn't present
ssl ceritificate to gateway when it wants to replace the authz code with
access token. So i tried to change auth-server-url to relative /auth.
However

Could not obtain grant code error: { Error: connect ECONNREFUSED
127.0.0.1:80

is popped inside the logs of the app.

How to configure keycloak node.js adapter correctly to secure services
behind the application gateway?


More information about the keycloak-user mailing list