我有一个由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));
我获得了访问令牌,因为没有解码/编码。
任何支持将不胜感激。谢谢!
答案 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;
...
}