使用express-jwt作为中间件来验证Azure AD发布的令牌

时间:2016-11-15 07:49:49

标签: node.js authentication express openid-connect

我想知道是否可以使用express-jwt NPM包作为中间件来验证Azure AD发布的JWT令牌。

我们有一个用express / node编写的Web API,并希望应用中间件模式来保护我们的端点并填充用户原则。

似乎:

server.use(jwt({
    audience: '{UUID}',
    issuer: 'https://sts.windows.net/{UUID}',
}).unless({path : ['/']}))

不起作用,因为它需要客户端密钥,但是从AD(很像隐式流程)中,令牌通过用户交互来检索,并且没有客户端密钥。

2 个答案:

答案 0 :(得分:5)

您可以使用“azure-ad-jwt”。它相当直接,不需要注入中间件。您可以将它作为中间步骤注入您自己的“中间件”功能中。

 private verifyToken(req: any, res: any) {
        var audience = "xxxxxxxxx";
        var tenantId = "xxxxxxxxx";

        var authorization = req.headers['authorization'];
        return Rx.Observable.create((observer) => {
            if (authorization) {
                var bearer = authorization.split(" ");
                var jwtToken = bearer[1];
                if (jwtToken) {
                    aad.verify(jwtToken, { audience: audience, tenantId: tenantId }, function (err, result) {
                        if (result) {
                            observer.next(true);
                        } else {
                            res.status(401).send('That is not a valid token!');
                        }
                    })
                } else {
                    res.status(401).send('No token in header.');
                }
            } else {
                res.status(401).send('Missing authorization attribute in header.');
            }
        });
    }

答案 1 :(得分:0)

express-jwt支持multi-tenancy,与天蓝色广告完美搭配。 https://github.com/auth0/express-jwt#multi-tenancy

import _ from 'lodash';
import jwt from 'express-jwt';

const ISS = 'https://sts.windows.net/********-****-****-****-************/';
const KEYS = {}; // response.body from https://login.microsoftonline.com/common/discovery/keys
// create another task to refresh KEYS every 24 hours.

app.use('/protected', jwt({
  secret: (req, header, payload, done) => {
    const { kid } = header;
    const { iss } = payload;

    if (iss !== ISS) { // issuer filter
      return done(new Error('invalid token issuer'));
    }

    const key = _.find(KEYS, { kid });
    if (key) {
      const pem = _.get(key, 'x5c[0]');

      if (pem) {
        return done(null, `-----BEGIN CERTIFICATE-----\n${pem}\n-----END CERTIFICATE-----`);
      }
      return done(new Error('not PEM found'));
    }
    return done(new Error('invalid kid'));
  },
}), (req, res) => {
  res.json({ msg: 'if you can see it, you have a valid access_token.' });
});

app.use((err, req, res, next) => { // error handler
  res.status(401).json({ msg: err.message });
});

参考文献: