首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Node.js应用程序/API中从Azure AD发出令牌?

如何在Node.js应用程序/API中从Azure AD发出令牌?
EN

Stack Overflow用户
提问于 2018-10-11 18:43:26
回答 3查看 3.9K关注 0票数 0

我正在构建一个具有快速后端的节点应用程序。其中一个要求是使用Azure AD进行身份验证。我已经安装了passport-azure-ad模块,并将其设置为:

代码语言:javascript
复制
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);

然后,我给这样一条路线增加了授权:

代码语言:javascript
复制
const myHandler = () => (req, res) => return res.json({});
app.get('/my/route',
        passport.authenticate("oauth-bearer", { session: false }),
        myHandler()
);

这是返回401状态的预期,但是,我还没有找到有关如何从Azure AD向客户端发出令牌的文档。我希望接受一个带有用户名和密码的登录端点的帖子,并返回Azure AD令牌。这个是可能的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-12 11:04:08

Azure广告令牌的唯一发行者是Azure AD。您不应该在客户端中收集用户名/密码,也不应该在服务中接受它们。

您的客户端应用程序只需使用MSAL (或ADAL,或任何OpenID连接客户端库)将用户发送到Azure,让它们登录,并相应地为您的API获取一个访问令牌。

例如,如果您的客户端是一个JavaScript单页应用程序,那么您可以使用用于JavaScript的MSAL执行以下操作:

代码语言: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.
});

(当然,您可以在其他各种平台上这样做。)

票数 0
EN

Stack Overflow用户

发布于 2019-11-08 07:06:45

您还可以执行以下操作。最近,我用nodejs后端使用我的react应用程序实现了一个

您可以在BearerStrategyOptions上找到https://github.com/AzureADQuickStarts/AppModelv2-WebAPI-nodejs/blob/master/node-server/config.js的键值。

我对identityMetadata使用了以下常用端点的https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

代码语言:javascript
复制
const BearerStrategyOptions = {
  identityMetadata,
  clientID,
  validateIssuer,
  issuer,
  passReqToCallback,
  allowMultiAudiencesInToken,
  audience
};

您可以在OIDCStrategyOptions上找到https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-nodejs/blob/master/config.js的键值。

代码语言:javascript
复制
const OIDCStrategyOptions = {
  identityMetadata,
  clientID,
  responseType,
  responseMode,
  redirectUrl,
  allowHttpForRedirectUrl,
  clientSecret,
  validateIssuer,
  isB2C,
  issuer,
  passReqToCallback,
  scope,
  nonceLifetime,
  nonceMaxAmount,
  useCookieInsteadOfSession,
  cookieEncryptionKeys,
  clockSkew
};

用于身份验证:

代码语言:javascript
复制
 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);
        });
      });
    })
  );

授权:

代码语言:javascript
复制
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中使用以下代码

代码语言:javascript
复制
 passport.authenticate('oauth-bearer', {session: false})

完成了!希望这对想要使用passport-azure-ad的人有帮助

票数 6
EN

Stack Overflow用户

发布于 2018-10-12 07:36:37

对于passport-azure-ad模块,关于azure广告如何发布令牌,您可以参考doc1doc2

我希望接受一个带有用户名和密码的登录端点的帖子,并返回Azure AD令牌。这个是可能的吗?

是的,这是可能的。如果您想这样做,可以参考这里

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52766958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档