无法将Keycloak与Sails集成。能够将Keycloak与Express集成

问题描述 投票:1回答:2

Keycloak是一个用Java编写的开源认证和身份管理解决方案。它提供了一个nodejs适配器,使用它我可以成功地与express集成。这是有效的路线文件:

    'use strict';

module.exports = function(app) {
    var Keycloak = require('keycloak-connect');
    var session = require('express-session');


    var memoryStore = new session.MemoryStore();

    app.use(session({
          secret: 'mySecret',
          resave: false,
          saveUninitialized: true,
          store: memoryStore
    }));

    var keycloak = new Keycloak({
          store: memoryStore
    });
    app.use(keycloak.middleware({
          logout: '/logout',
          admin: '/'
    }));


    // var lRController = require('../controllers/LRController');
    //
    // app.route('/lrs').get(lRController.list_all_lrs).post(lRController.create_a_lr);


    var DeliveryOrderController = require('../controllers/DeliveryOrderController');
    app.route('/').get(keycloak.protect(), DeliveryOrderController.getAllDos)
    app.route('/api/dos').get(keycloak.protect(), DeliveryOrderController.getAllDos).post(DeliveryOrderController.createDo);
    app.route('/api/do').put(DeliveryOrderController.updateDo);
    app.route('/api/do/:doNumber').get(DeliveryOrderController.getDoByDoNumber);
    app.route('/api/do/location/:locationId').get(DeliveryOrderController.getDoByLocation);
    app.route('/api/do/branch/:branchId').get(DeliveryOrderController.getDoByBranch);
    app.route('/api/do').delete(DeliveryOrderController.deleteDo);


    var TransportDeliveryOrderController = require('../controllers/TransportDeliveryOrderController');

    app.route('/api/tdos').get(TransportDeliveryOrderController.getAllTdos).post(TransportDeliveryOrderController.createTdo);
    app.route('/api/tdo').put(TransportDeliveryOrderController.updateTdo);
    app.route('/api/tdo/:tdoNumber').get(TransportDeliveryOrderController.getTdoByTdoNumber);
    app.route('/api/tdo/status/:status').get(TransportDeliveryOrderController.getTdoByStatus);
    app.route('/api/tdo/status/:status/do/:doNumber').get(TransportDeliveryOrderController.getTdoByStatusAndDo);

};

正如您在交货订单路线中所看到的,我有两条路线(同一路线的副本)受keycloak.protect()保护。我试图在帆中做同样的事情。这样做我有以下问题。

一个。要将keycloak集成到express中,需要执行以下操作来保护路由

  1. 需要Keycloak和快递会话: var Keycloak = require('keycloak-connect'); var session = require('express-session');
  2. 定义用于存储会话的内存存储: var memoryStore = new session.MemoryStore();
  3. 将会话作为中间件包含在express中 app.use(session({ secret: 'mySecret', resave: false, saveUninitialized: true, store: memoryStore }));
  4. 发起Keycloak: var keycloak = new Keycloak({ store: memoryStore });
  5. 将keycloak中间件包含到express中间件中: app.use(keycloak.middleware({ logout: '/logout', admin: '/' }));
  6. 使用keycloak.protect()保护路线 app.route('/api/dos').get(keycloak.protect(),DeliveryOrderController.getAllDos).post(DeliveryOrderController.createDo);

我需要在帆中建立类似的步骤。我怎样在帆中做这些事情?

我假设http.js是我添加中间件的地方。如果我这样做,如何访问routes.js中的keycloak来使用keycloak.protect()。

例如,我可以通过以下方式添加保护功能:

'/foo': [
 keycloak.protect(),
  { controller: 'user', action: 'find' }
]

这是keycloak的nodejs适配器 - https://github.com/keycloak/keycloak-nodejs-connect

node.js sails.js keycloak sails-mongo
2个回答
2
投票

我终于找到了答案。问题是keycloak.middleware()返回一个函数列表,app.use()对此感到满意。 Sails获取http.middleware列表并添加到它并在结果列表中调用app.use。如果你只包含keycloak.middleware(),你就有一个包含一系列函数的函数列表。 Express忽略该数组,因为它不是一个函数。

您需要将列表扩展为单独的函数。在http顶部创建一个keycloak对象并初始化它。然后把它放在config / http.js文件的底部:

function expandList() {
    var newOrder = [];
    for (let i in module.exports.http.middleware.order)
    {
        var label = module.exports.http.middleware.order[i];
        var functor = module.exports.http.middleware[label];
        if (functor && functor.constructor === Array) {
            for (let j in functor) {
                let newlabel = label + "." + j;
                newOrder.push(newlabel);
                module.exports.http.middleware[newlabel] = functor[j];
            }
        } else {
            newOrder.push(label);
        }
    };
    module.exports.http.middleware.order = newOrder;
    return "";
}
var result = init();

在http.middleware对象中你需要使用:keycloakMiddleware:keycloak.middleware(),并将它添加到订单数组。

还要添加一个呼叫保护策略,包括:

var kc = sails.config.http.keycloak.protect();
return kc(req, resp, next);

希望如果你仍然需要解决这个问题,这会有所帮助

也许Sails应该接受一个数组并在调用Express之前扩展它


1
投票

上面的答案不适用于Sails 1.0。它现在要求中间件是一个函数,而不是一个数组,keycloak从keycloak.middleware返回一个数组。这似乎有用:创建服务:KeycloakService

var session = require('express-session');
var Keycloak = require('keycloak-connect');

var memoryStore = new session.MemoryStore();
var KeycloakConfig = {
  "realm": "somerealm,
  "auth-server-url" : "https://server.com/auth",
  "resource" : "someresource,
};

module.exports = {
		config: KeycloakConfig,
		setConfig: function (config) {
			return new Keycloak({ store: memoryStore }, config);
		}
}

现在在http.js中将以下内容放在顶部

var KeycloakService = require('../api/services/KeycloakService');
var masterKeycloak = setupKeycloak();
var kcMiddleware = masterKeycloak.middleware();

function setupKeycloak() {
	if (KeycloakService.keycloak == null) {
		var config = Object.assign({}, KeycloakService.config);
		config.bearerOnly = true;
		KeycloakService.keycloak = KeycloakService.setConfig(config);
	}
	return KeycloakService.keycloak;
}

function recurseCallFunction(arr, i, req, res, next) {
  if (arr.length > i) {
    arr[i](req, res, () => recurseCallFunction(arr, i+1, req, res, next));
  } else {
    next();
  }
}

然后在middleware.order数组中包含“keycloakMiddleware”和下面的order数组使用

'keycloakMiddleware': function (req, res, next) {recurseCallFunction(kcMiddleware, 0, req, res, next);}
You will also need to define sails.config.http.keycloak: masterKeycloak

这将提供一个递归调用Keycloak中的middles函数的函数。您需要定义一个策略。该政策可以做到:

  var keycloak = sails.config.http.keycloak;
  if (!req.hostname) {
    req.hostname = req.host;
  }
  var authWithKeycloak = keycloak.protect();
  if (authWithKeycloak) {
	authWithKeycloak(req, res, next);
  } else {
	sails.log.warn('Keycloak authentication could not obtain a protection checker. Contact Developers');
  }

这项技术应该有助于Keycloak Policy Enforcer。您可以添加到配置中以启用它们,并根据keycloak.protect的文档使用它们。我对执法者一无所知,所以我对此无能为力。

© www.soinside.com 2019 - 2024. All rights reserved.