Как выпускать токены из Azure AD в приложении / API Node.js?

Я создаю приложение узла с экспресс-сервером. Одно из требований - использовать 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.info(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()
);

Это возвращает статус 401, как и ожидалось, однако мне не удалось найти документацию о том, как выдать токен клиенту из Azure AD. Я хотел бы принять POST для конечной точки входа с именем пользователя и паролем в теле и вернуть токен Azure AD. Это возможно?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
3 104
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Для модуля passport-azure-ad о том, как Azure Ad выдает токен, вы можете обратиться к doc1 и 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?

Да, это возможно. Если вы хотите сделать так, вы можете обратиться к здесь.

Ответ принят как подходящий

Единственным эмитентом токена Azure AD является Azure AD. Вы должны нет собирать имя пользователя / пароль в своих клиентах, и вы должны нет принимать их в своей службе.

Вашим клиентским приложениям просто необходимо использовать MSAL (или ADAL, или любую клиентскую библиотеку OpenID Connect), чтобы отправить пользователя в Azure AD, чтобы он вошел в систему и в ответ получил токен доступа для вашего API.

Например, если вашим клиентом было одностраничное приложение 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.
});

(Конечно, вы можете сделать это для различных других платформ.)

Спасибо, это действительно полезно. Вы знаете, можно ли стилизовать loginPopup?

Eric Barbour 12.10.2018 15:56

Не совсем. Вы можете добавить логотип для своего приложения, но стиль будет тем же стилем, который был определен организацией для пользователя, который входит в систему (и есть лишь некоторые из них, которые можно стилизовать на самом деле).

Philippe Signoret 12.10.2018 15:59

Вы также можете сделать следующее. Я недавно реализовал один с моим приложением реакции с бэкэндом nodejs

Вы можете найти ключевые значения для BearerStrategyOptions на https://github.com/AzureADQuickStarts/AppModelv2-WebAPI-nodejs/blob/master/node-server/config.js

Разрешите FYI Я использовал следующую общую конечную точку https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration для identityMetadata

const BearerStrategyOptions = {
  identityMetadata,
  clientID,
  validateIssuer,
  issuer,
  passReqToCallback,
  allowMultiAudiencesInToken,
  audience
};

Вы можете найти ключевые значения для OIDCStrategyOptions в https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-nodejs/blob/master/config.js

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.info("---------profile----------", profile)
            return done(null, profile);
          }
          // console.info("-----------user---------", user)
          return done(null, user);
        });
      });
    })
  );

Для авторизации:

passport.use(
    new BearerStrategy(BearerStrategyOptions, function(token, done) {
      console.info("verifying the user");
      console.info(token, "was the token retreived");
      findByOid(token.oid, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          // "Auto-registration"
          console.info(
            "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

Другие вопросы по теме