如何在 Node.js App/API 中从 Azure AD 发行令牌?
How to issue tokens from Azure AD in a Node.js App/API?
我正在构建一个带有快速后端的节点应用程序。其中一项要求是使用 Azure AD 进行身份验证。我已经安装了 passport-azure-ad
模块并将其设置如下:
import * as passportAD from "passport-azure-ad";
// ... <snip> ....
const tenantName = "<MY_TENANT_NAME>"";
const clientID = "<MY_CLIENT_ID>";
app.use(passport.initialize());
app.use(passport.session());
const bearerStrategy = new passportAD.BearerStrategy(
{
identityMetadata: `https://login.microsoftonline.com/${tenantName}.onmicrosoft.com/.well-known/openid-configuration`,
clientID
},
(token: any, done: any) => {
console.log(token);
return done(null, {}, token);
}
);
passport.use(bearerStrategy);
然后我给这样的路由添加了授权:
const myHandler = () => (req, res) => return res.json({});
app.get('/my/route',
passport.authenticate("oauth-bearer", { session: false }),
myHandler()
);
这是 return 预期的 401 状态,但是,我无法找到有关如何从 Azure AD 向客户端颁发令牌的文档。我想接受一个 POST 登录端点,在正文中包含用户名和密码,return 一个 Azure AD 令牌。这可能吗?
关于passport-azure-ad
模块,关于azure ad如何发布token,可以参考doc1 and doc2。
I'd like to accept a POST to a login endpoint with a username and
password in the body and return a Azure AD token. Is this possible?
是的,这是可能的。如果你想这样做,你可以参考here。
Azure AD 令牌的唯一颁发者是 Azure AD。你不应该不在你的客户中收集username/password,你不应该不在你的服务中接受他们。
您的客户端应用程序只需使用 MSAL(或 ADAL,或任何 OpenID Connect 客户端库)将用户发送到 Azure AD,让他们登录,并作为响应为您的 API.
例如,如果您的客户端是 JavaScript 单页应用程序,使用 MSAL for JavaScript 您可以执行以下操作:
var userAgentApplication = new Msal.UserAgentApplication(
'0813e1d1-ad72-46a9-8665-399bba48c201', // AppId of you client app
null, function (errorDes, token, error, tokenType, instance) {
// This callback only used loginRedirect OR acquireTokenRedirect.
}
);
var scopes = ["https://api.example.com/permission.scope"];
userAgentApplication.loginPopup(scopes).then(function (token) {
// Get the signed-in user
var user = userAgentApplication.getUser();
// Get an access token for the signed-in user
userAgentApplication.acquireTokenSilent(scopes).then(function (token) {
// Use the access token to call your API
$.ajax({
url: 'https://api.example.com/foo',
type: 'GET',
dataType: 'json',
headers: { 'Authorization': 'Bearer ' + token },
contentType: 'application/json; charset=utf-8',
success: function (result) {
// TODO: Do something cool with the API response.
},
error: function (error) {
// TODO: Do something smart if there's an error
}
});
}, function (error) {
// TODO: Silent token acquisition failed, retry with acquireTokenPopup()
});
}, function (error) {
// TODO: Deal with error.
});
(当然,你也可以在其他各种平台上这样做。)
您还可以进行以下操作。我最近用带有 nodejs 后端的 React 应用程序实现了一个
您可以在 https://github.com/AzureADQuickStarts/AppModelv2-WebAPI-nodejs/blob/master/node-server/config.js
找到 BearerStrategyOptions 的键值
允许仅供参考我使用了以下公共端点'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration for identityMetadata
const BearerStrategyOptions = {
identityMetadata,
clientID,
validateIssuer,
issuer,
passReqToCallback,
allowMultiAudiencesInToken,
audience
};
您可以在 https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-nodejs/blob/master/config.js
找到 OIDCStrategyOptions 的键值
const OIDCStrategyOptions = {
identityMetadata,
clientID,
responseType,
responseMode,
redirectUrl,
allowHttpForRedirectUrl,
clientSecret,
validateIssuer,
isB2C,
issuer,
passReqToCallback,
scope,
nonceLifetime,
nonceMaxAmount,
useCookieInsteadOfSession,
cookieEncryptionKeys,
clockSkew
};
身份验证:
passport.use(
new OIDCStrategy(OIDCStrategyOptions, function(
iss,
sub,
profile,
accessToken,
refreshToken,
done
) {
if (!profile.oid) {
return done(new Error("No oid found"), null);
}
// asynchronous verification, for effect...
process.nextTick(function() {
findByOid(profile.oid, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
// "Auto-registration"
users.push(profile);
// console.log("---------profile----------", profile)
return done(null, profile);
}
// console.log("-----------user---------", user)
return done(null, user);
});
});
})
);
授权:
passport.use(
new BearerStrategy(BearerStrategyOptions, function(token, done) {
console.log("verifying the user");
console.log(token, "was the token retreived");
findByOid(token.oid, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
// "Auto-registration"
console.log(
"User was added automatically as they were new. Their oid is: ",
token.oid
);
users.push(token);
owner = token.oid;
return done(null, token);
}
owner = token.oid;
return done(null, user, token);
});
})
);
并在 api
中使用以下代码授权路由
passport.authenticate('oauth-bearer', {session: false})
完成!希望这对希望使用 passport-azure-ad
的人有所帮助 :)
我正在构建一个带有快速后端的节点应用程序。其中一项要求是使用 Azure AD 进行身份验证。我已经安装了 passport-azure-ad
模块并将其设置如下:
import * as passportAD from "passport-azure-ad";
// ... <snip> ....
const tenantName = "<MY_TENANT_NAME>"";
const clientID = "<MY_CLIENT_ID>";
app.use(passport.initialize());
app.use(passport.session());
const bearerStrategy = new passportAD.BearerStrategy(
{
identityMetadata: `https://login.microsoftonline.com/${tenantName}.onmicrosoft.com/.well-known/openid-configuration`,
clientID
},
(token: any, done: any) => {
console.log(token);
return done(null, {}, token);
}
);
passport.use(bearerStrategy);
然后我给这样的路由添加了授权:
const myHandler = () => (req, res) => return res.json({});
app.get('/my/route',
passport.authenticate("oauth-bearer", { session: false }),
myHandler()
);
这是 return 预期的 401 状态,但是,我无法找到有关如何从 Azure AD 向客户端颁发令牌的文档。我想接受一个 POST 登录端点,在正文中包含用户名和密码,return 一个 Azure AD 令牌。这可能吗?
关于passport-azure-ad
模块,关于azure ad如何发布token,可以参考doc1 and doc2。
I'd like to accept a POST to a login endpoint with a username and password in the body and return a Azure AD token. Is this possible?
是的,这是可能的。如果你想这样做,你可以参考here。
Azure AD 令牌的唯一颁发者是 Azure AD。你不应该不在你的客户中收集username/password,你不应该不在你的服务中接受他们。
您的客户端应用程序只需使用 MSAL(或 ADAL,或任何 OpenID Connect 客户端库)将用户发送到 Azure AD,让他们登录,并作为响应为您的 API.
例如,如果您的客户端是 JavaScript 单页应用程序,使用 MSAL for JavaScript 您可以执行以下操作:
var userAgentApplication = new Msal.UserAgentApplication(
'0813e1d1-ad72-46a9-8665-399bba48c201', // AppId of you client app
null, function (errorDes, token, error, tokenType, instance) {
// This callback only used loginRedirect OR acquireTokenRedirect.
}
);
var scopes = ["https://api.example.com/permission.scope"];
userAgentApplication.loginPopup(scopes).then(function (token) {
// Get the signed-in user
var user = userAgentApplication.getUser();
// Get an access token for the signed-in user
userAgentApplication.acquireTokenSilent(scopes).then(function (token) {
// Use the access token to call your API
$.ajax({
url: 'https://api.example.com/foo',
type: 'GET',
dataType: 'json',
headers: { 'Authorization': 'Bearer ' + token },
contentType: 'application/json; charset=utf-8',
success: function (result) {
// TODO: Do something cool with the API response.
},
error: function (error) {
// TODO: Do something smart if there's an error
}
});
}, function (error) {
// TODO: Silent token acquisition failed, retry with acquireTokenPopup()
});
}, function (error) {
// TODO: Deal with error.
});
(当然,你也可以在其他各种平台上这样做。)
您还可以进行以下操作。我最近用带有 nodejs 后端的 React 应用程序实现了一个
您可以在 https://github.com/AzureADQuickStarts/AppModelv2-WebAPI-nodejs/blob/master/node-server/config.js
找到 BearerStrategyOptions 的键值允许仅供参考我使用了以下公共端点'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration for identityMetadata
const BearerStrategyOptions = {
identityMetadata,
clientID,
validateIssuer,
issuer,
passReqToCallback,
allowMultiAudiencesInToken,
audience
};
您可以在 https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-nodejs/blob/master/config.js
找到 OIDCStrategyOptions 的键值const OIDCStrategyOptions = {
identityMetadata,
clientID,
responseType,
responseMode,
redirectUrl,
allowHttpForRedirectUrl,
clientSecret,
validateIssuer,
isB2C,
issuer,
passReqToCallback,
scope,
nonceLifetime,
nonceMaxAmount,
useCookieInsteadOfSession,
cookieEncryptionKeys,
clockSkew
};
身份验证:
passport.use(
new OIDCStrategy(OIDCStrategyOptions, function(
iss,
sub,
profile,
accessToken,
refreshToken,
done
) {
if (!profile.oid) {
return done(new Error("No oid found"), null);
}
// asynchronous verification, for effect...
process.nextTick(function() {
findByOid(profile.oid, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
// "Auto-registration"
users.push(profile);
// console.log("---------profile----------", profile)
return done(null, profile);
}
// console.log("-----------user---------", user)
return done(null, user);
});
});
})
);
授权:
passport.use(
new BearerStrategy(BearerStrategyOptions, function(token, done) {
console.log("verifying the user");
console.log(token, "was the token retreived");
findByOid(token.oid, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
// "Auto-registration"
console.log(
"User was added automatically as they were new. Their oid is: ",
token.oid
);
users.push(token);
owner = token.oid;
return done(null, token);
}
owner = token.oid;
return done(null, user, token);
});
})
);
并在 api
中使用以下代码授权路由 passport.authenticate('oauth-bearer', {session: false})
完成!希望这对希望使用 passport-azure-ad