【问题标题】:Nodejs with LDAP. How to authorize user in multiple groups having same privileges带有 LDAP 的 Nodejs。如何授权具有相同权限的多个组中的用户
【发布时间】:2018-03-08 18:00:12
【问题描述】:

我在我的网页中使用 LDAP 身份验证将登录的用户链接到他在 Active Directory 中拥有的正确组。我想在用户发出请求时使用这些组来执行授权并且已经成功,直到我注意到当用户是多个组的一部分时,这些组对我正在运行的同一资源具有“错误:可以”的权限t 在发送后设置标题。"。

该错误是由中间件调用检查组是否应有权访问资源的函数引起的。因为当多个组具有相同的权限时会多次调用它,所以最终会多次调用 next()。

我应该如何进行更改以使多个组中的用户能够访问相同的资源?我应该能够以某种方式返回一个阻止对授权函数的任何进一步调用的值,但是我必须在中间件而不是函数中创建响应。

所有这一切都可能是由于我对中间件的工作原理缺乏了解造成的,所以如果我的实现中有一些逻辑错误,我很乐意得到一些反馈。

这里是负责授权的中间件:

app.use(function(reg, res, next){
        var checkSpesificGroup = false;
        var bearerToken;
        console.log(reg.body);
        var bearerHeader = reg.headers.authorization;
        var forbidden=true
        for(käyttäjänOikeus in käyttäjänOikeudet){
                if(käyttäjänOikeudet[käyttäjänOikeus].indexOf(reg.url) > -1){
                        forbidden = false;
                        checkYourPrivilege(käyttäjänOikeus, bearerHeader, res, reg, next);
                }
        }


        if(public.indexOf(reg.url) > -1){
                console.log('public')
                forbidden = false;
                bearerToken = decodeToken(bearerHeader);
                if(bearerToken !== false){
                        decoded = verifyToken(bearerToken);
                        if(decoded !== false){
                                if (checkIfExpired(decoded.expires)){
                                        console.log('checkifexpired success');
                                        res.setHeader('Tokenexpired',false);
                                        next();
                                }else{
                                        console.log('checkifexpired failed');
                                        res.setHeader('Tokenexpired',true);
                                        next();
                                }
                        }else{
                                console.log('decoding failed');
                                res.setHeader('Tokenexpired',false);
                                next();
                        }
                }else{
                        console.log('no bearer token');
                        res.setHeader('Tokenexpired',false);
                        next();
                }
        }
        if(forbidden){
                console.log('forbidden')
                return res.status(403).send({
                        success: false,
                        message: "Forbidden"
                });
        }
});

这是中间件调用的函数,用于对非公开资源执行授权:

function checkYourPrivilege(checkSpesificGroup, bearerHeader, res, reg, next){
        bearerToken = decodeToken(bearerHeader);
        if (bearerToken !== false) {
                decoded = verifyToken(bearerToken)
                if (decoded !== false){
                        if (checkIfExpired(decoded.expires)){
                                if(checkSpesificGroup){
                                        if(decoded.oikeudet[checkSpesificGroup] == true){
                                                console.log("Tokenisi vanhentuu" + Math.abs(decoded.expires - Math.floor(Date.now())/100$
                                                reg.decoded = decoded;
                                                res.setHeader('Tokenexpired',false);
                                                next()
                                        }else{
                                                return;
                                        }
                                }else{
                                        console.log("Tokenisi vanhentuu" + Math.abs(decoded.expires - Math.floor(Date.now())/1000) + "pä$
                                        reg.decoded = decoded;
                                        res.setHeader('Tokenexpired',false);
                                        next();
                                }
                        }else{
                                console.log("Token Expired");
                                return res.status(403).send({
                                          success: false,
                                          tokenstatus: "expired",
                                          message: "Token expired"
                                });
                        }
                }else{
                        return res.status(403).send({ success:false, message: 'Invalid token'});
                }
        } else {
                console.log('ei tokenia');
                return res.status(403).send({
                        success: false,
                        message: 'No token provided.'
                });
        }
};

这里是包含组信息的数组和包含公共资源的列表:

var käyttäjänOikeudet =({
"JasentietoSecurity":[],
"JasenSurvivalkit": ['/haut.html','/haku'],
"JasenKV": ['/haut.html','/haku'],
"JasenJasenpalvelu": ['/haut.html','/haku'],
"JasenAsukastoimisto": ['/haut.html','/haku'],
"JasenMaksutiedot":['/varaushaku'],
"JasenSystem": ['/haut.html','/haku','/pk.html','/update','/loki.html', '/raportointi.html','/maksuhaku','/tulosraportti.html']
});

var public = ['/','/login.html','/core.js','/authenticate','/koti.html', '/styles.css','/favicon.ico']

【问题讨论】:

    标签: node.js ldap authorization middleware


    【解决方案1】:

    我设法通过将授权函数从 for 循环中取出并在循环完成后仅调用一次来实现此功能。

    我还需要从授权函数中返回一个值,而不是在里面调用 next()。

    这是我对中间件所做的更改:

        var tarkistuslista = []; //Created a list to contain the groups the user is in
        for(käyttäjänOikeus in käyttäjänOikeudet){
                if(käyttäjänOikeudet[käyttäjänOikeus].indexOf(reg.url) > -1){
                        tarkistuslista.push(käyttäjänOikeus); //Instead of calling the authorization function, this part pushes the group in the list instead
                }
        }
        //Added the following if statement
        if (tarkistuslista.length > 0){
                privilege = checkYourPrivilege(tarkistuslista, bearerHeader)
                if(privilege == true){
                        next();
                }else{
                        return res.status(403).send(privilege);
                }
        }
    

    我还需要对授权功能做一些改动:

    function checkYourPrivilege(tarkistuslista, bearerHeader){
            bearerToken = decodeToken(bearerHeader);
            if (bearerToken !== false) {
                    decoded = verifyToken(bearerToken)
                    if (decoded !== false){
                            if (checkIfExpired(decoded.expires)){
                                    n = 1;
                                    privilege = false;
                                    for(i in tarkistuslista){
                                            if(decoded.ryhmäoikeudet[tarkistuslista[i]]){
                                                    privilege = true
                                                    console.log("Tokenisi vanhentuu" + Math.abs(decoded.expires - Mat$
                                                    return true;
                                                    break;
                                            }else{
                                                    if(n == tarkistuslista.length && privilege == false){
                                                            response = ({
                                                              success: false,
                                                              message: "Forbidden"
                                                            });
                                                            return response;
                                                    }
                                                    n +=1;
                                            }
                                    };
                            }else{
                                    console.log("Token Expired");
                                    response = ({
                                              success: false,
                                              tokenstatus: "expired",
                                              message: "Token expired"
                                    });
                                    return response;
                            }
                    }else{
                            response = ({ success:false, message: 'Invalid token'});
                            return response;
                    }
            } else {
                    response = ({
                            success: false,
                            message: 'No token provided.'
                    });
                    return response;
            }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2018-08-06
      • 2019-05-03
      • 1970-01-01
      相关资源
      最近更新 更多