通过OIDCStrategy和BearerStrategy使用护照通行证广告配置来保护Web应用和Web服务器

时间:2019-12-14 00:04:23

标签: javascript azure express azure-active-directory passport.js

我有一个由express.js服务器(Web应用程序服务器)提供的Web应用程序。 Web应用程序服务器通过passport.js和passport-azure-ad npm程序包处理用户登录。我为此使用了 OIDCStrategy

我还通过另一台服务器(其余后端)托管REST api。我想使用 BearerStrategy 通过password.js和Passport-azure-ad npm软件包保护此后端。为此,我想在Web应用程序服务器通行证配置中定义一个范围,以便Web应用程序服务器的access_token可以通过Cookie传递到我的Web应用程序,并从那里用于访问其余后端。

我的问题:在当前配置下,尝试使用access_token访问我的后端api时,我收到401访问被拒绝。 access_token invalid是错误消息:{"name":"AzureAD: Bearer Strategy", "msg":"authentication failed due to: error: invalid_token","v":0}

我认为我应该在登录时重定向到权限页面,但事实并非如此。所以我想我的访问令牌实际上是无效的。

Web应用服务器密码配置:

passport.use(
  new OIDCStrategy(
    {
      clientID: credsAzureAD.clientID,
      identityMetadata: credsAzureAD.identityMetadata, // here is use the web app tenant id
      clientSecret: credsAzureAD.clientSecret,
      callbackURL: credsAzureAD.returnURL,
      redirectUrl: credsAzureAD.returnURL,
      skipUserProfile: true,
      responseType: 'code',
      responseMode: 'query',
      scope: 'api://test/Write.Contributor',
      useCookieInsteadOfSession: false,
      passReqToCallback: false
    },
    (issuer, sub, profile, accessToken, refreshToken, done) => {
        user.accessToken = accessToken;
        return done(null, user);
    }
  )
);

我尝试使用范围,其中api://test是我的REST API应用程序ID uri,而/Write.Contributor是我在azure活动目录中定义的范围。

我的REST后端服务器护照配置:

const options = {
    identityMetadata: azureAD.identityMetadata, // here I use the backend server tenant id
    clientID: azureAD.clientID,
    issuer: azureAD.issuer, // here I use the backend server tenant id
    passReqToCallback: false,
};

const bearerStrategy = new BearerStrategy(options, function(token, done) {
    done(null, {}, token);
});

我已经通过应用程序注册在azure活动目录中创建了后端服务器,并在上面创建了命名作用域和应用程序ID。我还在其中将我的网络应用程序clientId列为授权的客户端应用程序。

我尝试拨打以下路线并收到401:

app.get(
    '/testtest',
    cors(),
    passport.authenticate('oauth-bearer', { session: false }),
    function(req, res) {
        var claims = req.authInfo;
        console.log('User info: ', req.user);
        console.log('Validated claims: ', claims);
        res.status(200).json({ name: claims['name'] });
    }
);

这是我在vue网络应用程序中的休息电话:

    let headers = {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${this.user.accessToken}`,
      'cache-control': 'no-cache'
    };
    const apiClient = axios.create({
      baseURL,
      headers
    });
    apiClient.get('/testtest').then( resp => console.log( resp));

我获得了访问令牌,因为没有解码/编码。

任何支持将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

正如@Jim Xu在评论中建议的那样,通过Azure门户将REST api的应用程序范围添加到客户端应用程序有助于解决此问题。但是我也使用了错误的令牌。

我现在不再使用验证功能参数列表中的accessToken,而是使用验证功能参数列表中的param

(iss, sub, profile, access_token, refresh_token, params, done) => {
     // access_token did not work
     // id_token can be used as an accessToken
     user.accessToken = params.id_token;
     ...
}