我想知道是否可以使用express-jwt
NPM包作为中间件来验证Azure AD发布的JWT令牌。
我们有一个用express / node编写的Web API,并希望应用中间件模式来保护我们的端点并填充用户原则。
似乎:
server.use(jwt({
audience: '{UUID}',
issuer: 'https://sts.windows.net/{UUID}',
}).unless({path : ['/']}))
不起作用,因为它需要客户端密钥,但是从AD(很像隐式流程)中,令牌通过用户交互来检索,并且没有客户端密钥。
答案 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 });
});
参考文献: