使用 keycloak.protect() 和 express.Router()

Rol*_*edo 3 node.js keycloak

我想使用 Keycloak 来保护我的路线,Keycloak 是一种开源身份和访问管理。我试图遵循他们的文档,但我无法使其正常工作。

这是我的 app.js 文件:

const express = require( 'express' );
const routePlaces = require( './routes/placesRoutes' );

const Keycloak = require( 'keycloak-connect' );
const session = require( 'express-session' );
const memoryStrore = new session.MemoryStore();

let kcConfig = {
    clientId =      'parking-app',
    bearerOnly:     true,
    serverUrl:      'localhost:8080/auth',
    realm:          'FlexParking',
    reamlPublicKey: 'MIIBIjANBg…'
}

var keycloak = new KeyCloak( {store: memoryStore}, kcConfig );

app.use( keycloak.middleware({
    //  here I think I have to place my routes
}));

app.use( '/places, routePlaces );
module.exports = app;
Run Code Online (Sandbox Code Playgroud)

服务器是在一个server.js文件中创建的,在尝试使用 Keycloak 之前,所有端点都运行良好。

这是我的routePlaces.js文件:

'use strict';
const express = require( 'express' );
const place = require( '../controllers/placesController' );

router.route( '/gps' ).get( place.get_place_by_gps );
router.route( '/street' ).get( place.get_place_by_street );

module.exports = router;
Run Code Online (Sandbox Code Playgroud)

这是我的placesController.js

'use strict';

exports.get_place_by_gps = ( req, res, next ) => {
    res.send( ' GET places by the GPS position' );
}

exports.get_place_by_street = ( req, res, next ) => {
    res.send( ' GET places by the street name' );
}
Run Code Online (Sandbox Code Playgroud)

我希望我的路线 ('/places/gps') 受到保护keycloak.connect('...'),而路线 '/places/street' 在没有任何保护的情况下使用。如何配置 Keycloak 中间件来做到这一点?

app.use( keycloak.middleware({
    //  here i think i have to place my routes
}));
Run Code Online (Sandbox Code Playgroud)

如何像这样保护路由:

const express = require( 'express' );
const routePlaces = require( './routes/placesRoutes' );

const Keycloak = require( 'keycloak-connect' );
const session = require( 'express-session' );
const memoryStrore = new session.MemoryStore();

let kcConfig = {
    clientId =      'parking-app',
    bearerOnly:     true,
    serverUrl:      'localhost:8080/auth',
    realm:          'FlexParking',
    reamlPublicKey: 'MIIBIjANBg…'
}

var keycloak = new KeyCloak( {store: memoryStore}, kcConfig );

app.use( keycloak.middleware({
    //  here I think I have to place my routes
}));

app.use( '/places, routePlaces );
module.exports = app;
Run Code Online (Sandbox Code Playgroud)

v.l*_*nev 5

> app.use(keycloak.middleware({
> 
> //  here i think i have to place my routes
> 
> }));
Run Code Online (Sandbox Code Playgroud)

这是不正确的。你必须通过options那里。

    app.use(keycloak.middleware({
        logout: logoutUrl,
        admin: '/'
    }));
Run Code Online (Sandbox Code Playgroud)

如何成为我想要保护的路线:

router.route('/gps').get(place.get_place_by_gps,keycloak.connect('user'); 上面的东西?

keycloak.middleware()
Run Code Online (Sandbox Code Playgroud)

本身不做任何保护。它只是尝试grant从请求中获取数据并将其放入特殊对象中request.kauth.grant。它还做一些额外的事情,比如检查注销请求。

要保护您需要添加的资源 keycloak.protect()

 app.get('/gps', keycloak.protect(), handler);
Run Code Online (Sandbox Code Playgroud)

不保护资源只是不添加任何东西

 app.get('/street', handler);
Run Code Online (Sandbox Code Playgroud)

这是来自keycloak-nodejs-example 的一个更复杂的示例,它使用自定义中间件

middleware(logoutUrl) {
        // Return the Keycloak middleware.
        //
        // Specifies that the user-accessible application URL to
        // logout should be mounted at /logout
        //
        // Specifies that Keycloak console callbacks should target the
        // root URL.  Various permutations, such as /k_logout will ultimately
        // be appended to the admin URL.
        let result = this.keyCloak.middleware({
            logout: logoutUrl,
            admin: '/'
        });
        result.push(this.createSecurityMiddleware());
        return result;
    }


    createSecurityMiddleware() {
        return (req, res, next) => {
            if (this.permissions.isNotProtectedUrl(req)) {
                return next();
            }

            const permission = this.permissions.findPermission(req);
            if (!permission) {
                console.log('Can not find a permission for: %s %s', req.method, req.originalUrl);
                return this.keyCloak.accessDenied(req, res);
            }

            this.protectAndCheckPermission(req, res, next, permission.resource, permission.scope);
        };
    }


app.use(keyCloak.middleware('/logout'));
Run Code Online (Sandbox Code Playgroud)

来源

https://github.com/v-ladyev/keycloak-nodejs-example/blob/master/lib/keyCloakService.js#L69

https://github.com/v-ladyev/keycloak-nodejs-example/blob/master/app.js#L60

您也可以参考更复杂的保护模式,在keycloak-nodejs-example 中使用 (resource, scope)