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

3
我希望使用开源身份认证和访问管理系统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;

服务器是在一个名为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;

这是我的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' );
}

我希望使用keycloak.connect('...')来保护我的路由('/places/gps'),而路由'/places/street'则不需要任何保护。如何配置Keycloak中间件以实现此功能?

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

如何保护路由器:
router.route( '/gps' ).get( place.get_place_by_gps, keycloak.connect('user'));

如何访问每个受Keycloak保护的端点?是通过包含“Authorization: Bearer + $ {JWT}”的标头进行访问吗?例如:“curl -X GET localhost/gps -H'Authorization:Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJucnZ1ZS1tcTJ3a09DaEtXUldaa1lWTko3OUpma1VxTTR0ZUFocVZIMzBJIn0.eyJqdGkiOiJhMTc2NjU5YS1iY2JkLf....'” - Artanis Zeratul
1个回答

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

这是错误的。你必须将options传递进去。

    app.use(keycloak.middleware({
        logout: logoutUrl,
        admin: '/'
    }));

我应该如何保护我的路由: 路由器的路径应该是这样的:`router.route('/gps').get(place.get_place_by_gps,keycloak.connect('user'))`,类似上面的代码。
keycloak.middleware()

它本身不提供任何保护功能。它只是尝试从请求中获取grant数据,并将其放入特殊对象request.kauth.grant中。

此外,它还会执行一些其他操作,例如检查注销请求。

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

 app.get('/gps', keycloak.protect(), handler);

如果不想保护资源,只需不添加任何内容即可。

 app.get('/street', handler);

这个例子来自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'));

来源

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

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

此外,您还可以参考 keycloak-nodejs-example 中使用(资源、范围)的更复杂的保护方案。

注:本文涉及IT技术相关内容。

1
非常感谢,您提供了许多有用的信息和精彩的示例。我几乎要放弃并开始使用Webtokens实现普通身份验证了。 - Rolando Azevedo
@v.ladynev,关于每个受Keycloak保护的端点,需要使用包含“Authorization:Bearer + $ {JWT}”的头访问,对吗?例如:“curl -X GET http://localhost/gps -H'Authorization:Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia 2lkIiA6ICJucnZ1ZS1tcTJ3a09DaEtXUldaa1lWTko3OUpma1VxTTR0ZUFocVZIMzBJIn0.eyJqdGkiOiJhMTc2NjU5YS1iY2JkLf....'” - Artanis Zeratul
@ArtanisZeratul Keycloak不会保护端点免受攻击。它们由keycloak-connect库进行保护。 - v.ladynev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接