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中,需要做以下事情以保护路由
需要Keycloak并表达会话:
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
}));
发起Keycloak:
var keycloak = new Keycloak({
store: memoryStore
});
将keycloak中间件包含在快速中间件中:
app.use(keycloak.middleware({
logout: '/logout',
admin: '/'
}));
使用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
答案 0 :(得分: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);
希望如果你仍然需要解决这个问题,这会有所帮助。
在调用Express
之前,也许Sails应该接受一个数组并展开它答案 1 :(得分: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);}
这将提供一个函数,该函数递归调用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的文档使用它们。我对执法者一无所知,所以我对此无能为力。