使用 express-jwt 作为中间件来验证 Azure AD 颁发的令牌
Use express-jwt as middleware to verify Azure AD issued tokens
我想知道是否可以使用 express-jwt
NPM 包作为中间件来验证 Azure AD 颁发的 JWT 令牌。
我们有一个用 express/node 编写的网络 API 并且想应用中间件模式来保护我们的端点并填充用户原则。
好像是:
server.use(jwt({
audience: '{UUID}',
issuer: 'https://sts.windows.net/{UUID}',
}).unless({path : ['/']}))
不起作用,因为它需要客户端密码,但从 AD(很像在隐式流中)令牌是通过用户交互检索的,没有客户端密码。
您可以使用 "azure-ad-jwt"。它相当简单,不需要注入中间件。当然,您可以将其作为中间步骤注入到您自己的 "middleware" 函数中。
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.');
}
});
}
express-jwt
支持 multi-tenancy
,与 azure ad 完美搭配。 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 });
});
参考文献:
我想知道是否可以使用 express-jwt
NPM 包作为中间件来验证 Azure AD 颁发的 JWT 令牌。
我们有一个用 express/node 编写的网络 API 并且想应用中间件模式来保护我们的端点并填充用户原则。
好像是:
server.use(jwt({
audience: '{UUID}',
issuer: 'https://sts.windows.net/{UUID}',
}).unless({path : ['/']}))
不起作用,因为它需要客户端密码,但从 AD(很像在隐式流中)令牌是通过用户交互检索的,没有客户端密码。
您可以使用 "azure-ad-jwt"。它相当简单,不需要注入中间件。当然,您可以将其作为中间步骤注入到您自己的 "middleware" 函数中。
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.');
}
});
}
express-jwt
支持 multi-tenancy
,与 azure ad 完美搭配。 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 });
});
参考文献: