使用 Azure AD、ReactJS 和 NodeJS 验证用户并使用 Graph API

     2023-03-08     58

关键词:

【中文标题】使用 Azure AD、ReactJS 和 NodeJS 验证用户并使用 Graph API【英文标题】:Authenticate Users and use Graph API using Azure AD, ReactJS and NodeJS 【发布时间】:2017-04-11 16:03:15 【问题描述】:

我有一个使用 NodeJS + ReactJS 创建的项目应用程序,我想要的只是使用 Azure AD 对用户进行身份验证,并使用 Azure 的 Graph API 获取他的数据,如姓名、组、图片、职业等。

我已经在 Azure 门户上正确配置了 Azure AD 和应用程序。包括权限委派和所有这些人员。

我试图了解如何做到这一点的最佳方法,但没有成功。我一直在尝试在 google、***、Microsoft 文档,甚至项目示例上找到。

一些示例已经奏效,但我无法理解其中任何一个示例并将其放入我的项目中以用作生产应用程序。

我已经用这个来验证用户,但是返回的AccessToken对于调用Graph API是无效的:

passport.use(new OIDCStrategy(
    redirectUrl: config.creds.returnURL,
    realm: config.creds.realm,
    clientID: config.creds.clientID,
    clientSecret: config.creds.clientSecret,
    oidcIssuer: config.creds.issuer,
    identityMetadata: config.creds.identityMetadata,
    skipUserProfile: config.creds.skipUserProfile,
    responseType: config.creds.responseType,
    responseMode: config.creds.responseMode,
    allowHttpForRedirectUrl: config.creds.allowHttpForRedirectUrl
  ,
  function(iss, sub, profile, accessToken, refreshToken, done) 
    console.log(accessToken);
    profile = profile._json;
    if (!profile.email) 
      return done(new Error("No email found"), null);
    
    // asynchronous verification, for effect...
    process.nextTick(function () 
      findByEmail(profile.email, function(err, user) 
        if (err) 
          return done(err);
        
        if (!user) 
          // "Auto-registration"
          users.push(profile);
          return done(null, profile);
        
        return done(null, user);
      );
    );
  
));

这个给了我正确的 AccessToken 来使用 Graph API,但我不明白如何使用它而不是 Passport:

function createAuthorizationUrl(state) 
  var authorizationUrl = templateAuthzUrl.replace('<client_id>', sampleParameters.clientId);
  authorizationUrl = authorizationUrl.replace('<redirect_uri>',redirectUri);
  authorizationUrl = authorizationUrl.replace('<state>', state);
  authorizationUrl = authorizationUrl.replace('<resource>', resource);
  return authorizationUrl;


// Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD.
// There they will authenticate and give their consent to allow this app access to
// some resource they own.
app.get('/auth', function(req, res) 
  crypto.randomBytes(48, function(ex, buf) 
    var token = buf.toString('base64').replace(/\//g,'_').replace(/\+/g,'-');

    res.cookie('authstate', token);
    var authorizationUrl = createAuthorizationUrl(token);

    res.redirect(authorizationUrl);
  );
);

// After consent is granted AAD redirects here.  The ADAL library is invoked via the
// AuthenticationContext and retrieves an access token that can be used to access the
// user owned resource.
app.get('/getAToken', function(req, res) 
  if (req.cookies.authstate !== req.query.state) 
    res.send('error: state does not match');
  
  var authenticationContext = new AuthenticationContext(authorityUrl);
  authenticationContext.acquireTokenWithAuthorizationCode(req.query.code, redirectUri, resource, sampleParameters.clientId, sampleParameters.clientSecret, function(err, response) 
    var message = '';
    if (err) 
      message = 'error: ' + err.message + '\n';
    
    message += 'response: ' + JSON.stringify(response);

    if (err) 
      res.send(message);
      return;
    

    // Later, if the access token is expired it can be refreshed.
    authenticationContext.acquireTokenWithRefreshToken(response.refreshToken, sampleParameters.clientId, sampleParameters.clientSecret, resource, function(refreshErr, refreshResponse) 
      if (refreshErr) 
        message += 'refreshError: ' + refreshErr.message + '\n';
      
      message += 'refreshResponse: ' + JSON.stringify(refreshResponse);

      res.send(message); 
    ); 
  );
);

如果有人可以帮助我提供一些真实的应用示例、视频或其他内容,那就太好了。我正在失去理智去弄清楚。

谢谢!

【问题讨论】:

【参考方案1】:

护照的OIDCStrategy 跟随Authorize access to web applications using OpenID Connect and Azure Active Directory 对用户进行身份验证和授权。而如果需要资源的访问权限,还需要完成Use the authorization code to request an access token的步骤。

我根据openid connection sample添加了一些代码sn-ps:

返回路由函数将使用code获取访问令牌并保存到用户视觉对象中。

app.post('/auth/openid/return',
  passport.authenticate('azuread-openidconnect',  failureRedirect: '/login' ),
  function (req, res) 
    let option = 
      method:'POST',
      uri:'https://login.microsoftonline.com/<tenant_id>/oauth2/token',
      headers:
        'Content-Type':'application/x-www-form-urlencoded'
      ,
      form:
        grant_type:'authorization_code',
        client_id:'<client_id>',
        resource:'https://graph.windows.net',
        client_secret:'<secret_key>',
        code:req.body.code,
        redirect_uri:'http://localhost:3000/auth/openid/return'
      
    
    console.log(option);
    request(option,function(err,res,body)
      req.user.access_token = JSON.parse(body).access_token;
    )

    // log.info('We received a return from AzureAD.');
    res.redirect('/');
  );

路由'/me'是为了采样使用访问令牌来要求资源。

app.get('/me',ensureAuthenticated ,function(req,response)
  request.get("https://graph.windows.net/<tenant_id>/me?api-version=1.5", 
    'headers': 
      'Authorization': "Bearer " + req.user.access_token,
      'Content-Type': 'application/json'
    
  , function(err, res, body)
    if(err)
      console.log("err: " + err);
    
    else
      console.log("res: " + res);
      response.send(res);
    
  );
);

如有任何疑问,请随时告诉我。

【讨论】:

嗨,加里!感谢您的回复...在看到您的答案之前,我使用 adal-node 而不是 Passport 使用此方法得到了结果:authenticationContext.acquireTokenWithAuthorizationCode() 但是现在,我在 Azure 上配置了另一个 WebAPI,我仍然有问题要调用此 API 的方法。我更改了 adal-node 方法的资源参数,并获得了一个有效的令牌来调用我的 WebAPI,但现在图表无法使用此令牌。 我的问题是:我是否需要获得 2 个不同的令牌才能使用我的 WebAPI 和 Graph API?如果我使用“acquireTokenWithAuthorizationCode”对用户进行身份验证并调用 Graph 并使用“acquireTokenWithClientCredentials”来要求使用令牌调用 WebAPI 是否可以? 在这些示例github.com/AzureAD/… 中为不同资源更改resource 参数。例如。使用resource = "https://graph.windows.net" 获取 Azure AD 图形资源的访问令牌。 完美!但是,这是一个好习惯吗?比如:使用 adal 对用户进行身份验证,然后创建一种方法来获取不同资源的 accessTokens?我创建了一个方法,它接收资源作为参数并调用 adal 方法以从 azure 获取令牌,现在它工作得很好。但我真的不知道这是否是一个好习惯。你怎么看? 出于安全考虑,它是由 OAuth 2.0 设计的。

ReactJS 与 azure SAML SSO 的集成

】ReactJS与azureSAMLSSO的集成【英文标题】:ReactJSintegrationwithazureSAMLSSO【发布时间】:2022-01-1115:53:52【问题描述】:寻求对AzureSAMLSSO与ReactJS和NodeJS应用程序(具有自定义域名的非库应用程序)集成的支持。这里有更多细节,我有使... 查看详情

使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户

...hJWTtoken【发布时间】:2017-12-0114:57:21【问题描述】:我在ReactJS中有一个.netcorewebapi和SPA客户端。我想允许用户使用在AzureAD中注册的电子邮件从客户端登录,并使用JWT令牌保护 查看详情

使用 Passport 和 passport-azure-ad 时没有刷新令牌

】使用Passport和passport-azure-ad时没有刷新令牌【英文标题】:NorefreshtokenwhenusingPassportandpassport-azure-ad【发布时间】:2017-11-1909:12:21【问题描述】:我正在尝试使用Passport连接到Office365。我得到了身份验证提示并返回了访问令牌。问... 查看详情

Azure AD 和核心身份角色混合

...发布时间】:2021-12-1111:55:39【问题描述】:是否可以同时使用AzureAD和核心身份角色?基本上,用户将使用AD登录应用程序,我已经这样做了。但是当他们使用该应用程序时,他们的角色将基于AspNetRoles和AspNetUsersRoles表。我在想我... 查看详情

使用 KeyVault 和 Azure PowerShell 证书身份验证创建 Azure AD 应用程序

】使用KeyVault和AzurePowerShell证书身份验证创建AzureAD应用程序【英文标题】:CreateanAzureADapplicationwithKeyVault&AzurePowerShellCertificateauthentication【发布时间】:2017-06-1802:21:28【问题描述】:我尝试使用AzurePowerShell证书身份验证在AzureAD... 查看详情

使用 oAuth 和 SAML 代表 Azure AD

】使用oAuth和SAML代表AzureAD【英文标题】:AzureADOn-Behalf-OfwithoAuth&SAML【发布时间】:2018-06-0304:12:05【问题描述】:我们使用AzureADOn-Behalf-Offlow通过单个API网关将用户连接到多个服务。现在我们想添加另一个服务(Nextcloud,通过LD... 查看详情

使用 Azure AD 授予用户权限

】使用AzureAD授予用户权限【英文标题】:GiveuserpermessionwithAzureAD【发布时间】:2022-01-1911:36:17【问题描述】:我已经在azureapp服务上部署了一个应用程序,它使用azureAD进行身份验证和授权。不幸的是,开发它的开发者已经不在了... 查看详情

使用 Azure AD 和本地帐户保护 API

】使用AzureAD和本地帐户保护API【英文标题】:SecuringAPIwithAzureADandlocalaccounts【发布时间】:2020-08-1907:34:04【问题描述】:我想保护我的API,以便只有在AzureAD中进行身份验证并在我的应用程序中拥有本地帐户的用户才能调用它。... 查看详情

使用 AWS cognito 联合身份设置 Azure AD 和 GSuite

】使用AWScognito联合身份设置AzureAD和GSuite【英文标题】:SettingupAzureADandGSuitewithAWScognitofederatedidentities【发布时间】:2018-01-2403:38:40【问题描述】:如何使用AWScognito联合身份为azureAD和GSuite启用SSO?我曾尝试使用SAML,但无法弄清楚... 查看详情

401- 使用 REST API Dynamics CRM 和 Azure AD 进行未经授权的身份验证

】401-使用RESTAPIDynamicsCRM和AzureAD进行未经授权的身份验证【英文标题】:401-UnauthorizedauthenticationusingRESTAPIDynamicsCRMwithAzureAD【发布时间】:2016-09-0923:44:52【问题描述】:我正在尝试使用AzureADoAuth2身份验证访问DynamicsCRMOnlineRESTAPI。... 查看详情

如何在 ASP.NET Core 3 上同时使用 Azure AD 身份验证和身份?

】如何在ASP.NETCore3上同时使用AzureAD身份验证和身份?【英文标题】:HowtousebothAzureADauthenticationandIdentityonASP.NETCore3?【发布时间】:2020-05-2814:49:45【问题描述】:Web应用程序应允许拥有AD帐户的内部员工使用AzureAD身份验证在应用程... 查看详情

Azure Front Door、应用服务访问限制和 AD 身份验证

...时间】:2021-07-0113:23:32【问题描述】:`大家好,我正在使用AzureFrontDoor,这是一个通过AzureAD进行身份验证的应用服务/Web应用。我似乎遇到了一些问题。我有一个自定义域映射-将使用示例进行演示。 查看详情

Redhat BRMS 和 Azure AD 集成

...务中心)与azureAD集成以进行身份​​验证?目前,我们使用LDAP。【问题讨论】:你看过这个MS文件吗?docs.microsoft.com/en-us/dynamics365/business-central/d 查看详情

asp.net core 自定义不记名令牌和 Azure Ad 令牌授权

...述】:我会尽力解释我的问题。目前我正在处理用户可以使用本地db用户登录并可以使用AzureAD登录的要求,使用本地db用户我正在使用以下代码创建自定义令牌。publicstaticstring 查看详情

如何使用身份服务器 3 和 microsoft 团队应用程序使用 Azure AD 令牌进行身份验证

】如何使用身份服务器3和microsoft团队应用程序使用AzureAD令牌进行身份验证【英文标题】:HowtoauthenticateusingAzureADtokenusingidentityserver3andmicrosoftteamsapp【发布时间】:2021-05-0612:39:14【问题描述】:我们使用自定义idp(身份服务器3)... 查看详情

使用 Azure Active Directory 或 ADFS 或 AD 的 SSO

】使用AzureActiveDirectory或ADFS或AD的SSO【英文标题】:SSOWithAzureActiveDirectoryorADFSorAD【发布时间】:2021-12-1808:34:32【问题描述】:MicrosoftSSO身份验证新手。具有元数据、公共证书和登录url以及AzureAD标识符和entityid。当我浏览这个SAML2.... 查看详情

允许用户通过 Azure AD 用户名和密码登录

...控制器中,我硬编码了用户名和密码。现在我想允许用户使用他/她的AzureAD用户名和密码登录。publicIActionResultLogin([FromBody]LoginModeluser)if(user==null) 查看详情

Azure AD B2C:注销社交帐户(使用 OIDC 的 Azure AD)

】AzureADB2C:注销社交帐户(使用OIDC的AzureAD)【英文标题】:AzureADB2C:Logoutofsocialaccount(AzureADusingOIDC)【发布时间】:2021-09-1822:27:57【问题描述】:我有一个使用B2C的应用程序让用户使用本地帐户或AzureAD帐户登录。在注销期间,本... 查看详情