退出 Azure Passport 身份验证 (Node.js)

3

我有一个Node.js应用程序,其中我们使用了Azure登录和Passport身份验证。

我已经成功使用Azure登录,并且应用程序正在正常工作。

但是,当我注销并将URL给定到页面时,它会检查身份验证并自动转到该页面,而不询问登录。

一旦我登录,我的URL包含以下查询字符串:

1. session_state 2. code 3. state 4. token

登录代码:

app.get('/login', passport.authenticate('azuread-openidconnect', { failureRedirect: '/' }), function (req, res) {
res.sendFile(path.join(__dirname+'/index.html'));

注销代码:

});

app.get('/logout', function (req, res) {
    req.session.destroy();
    req.logout();
    res.redirect('/');
});

当我注销后,页面会重定向到我的主页。然后当我在URL中输入“/login”时,它会直接跳转到登录页面而不是让我进行登录。
请帮忙解决这个问题...
4个回答

3
这个问题是由OAuth 2.0的授权码授权流引起的。类似于Azure AD OAuth 2.0服务上没有任何会话的情况。这不是passportjsexpressjs的问题。
我们可以进行以下简单的测试,在浏览器中访问认证端点:https://login.microsoftonline.com/common/oauth2/authorize?response_type=id_token%20code&client_id=<client_id>&redirect_uri=<redirect_uri>&response_mode=query&scope=openid 您需要先填写电子邮件和密码,完成登录流程后,第二次访问端点时,您将不再需要填写电子邮件或密码。
我们可以在授权端点中设置url参数promptlogin,以强制用户每次重新进行身份验证。
您可以参考https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx#code-snippet-3获取详细信息。
但在Azure Passport OIDC策略中,我们应该修改源代码以添加参数到端点中。
安装passport-azure-ad模块后,打开文件/node_modules/passport-azure-ad/lib/passport-azure-ad/oidcstrategy.js,在第545行(左右)处,您可以找到以下代码片段:
      var params = {};
      if (self.authorizationParams) { params = self.authorizationParams(options); }
      params['response_type'] = config.responseType;
      log.info('We are sending the response_type: ', params['response_type']);
      params['client_id'] = config.clientID;
      params['redirect_uri'] = callbackURL;
      ...

我们可以在代码片段后添加句子params ['prompt'] ='login';来添加支持。
如果还有任何疑问,请随时让我知道。
编辑

是否有办法只在注销时提示登录...

我不确定你的意思是什么,你想在访问登录路由时检查用户是否已经验证过,如果是,则不提示登录流程吗?
如果是这样,您可以自定义一个中间件来检查身份验证。例如:
function checkAuthenticatedOnLogin(req,res,next){
  if (!req.isAuthenticated()) { 
    return next(); 
  }else{
    res.send('do not need login');
  }
}

app.get('/login',checkAuthenticatedOnLogin,
  passport.authenticate('azuread-openidconnect',{ failureRedirect: '/login' }),
  function(req, res) {
    log.info('Login was called in the Sample');
    res.redirect('/');
});

谢谢。现在每次都会提示登录...有没有办法只在我注销时提示登录...目前它在我登录并再次进入登录页面时提示登录...它必须重定向到其他页面... - user3211705
1
已更新,请确认是否符合您的要求。 - Gary Liu

1

1) 我曾经遇到过同样的问题,正如passport-azure所记录的那样,我执行了以下函数以注销:

 logout: function(req, res) {
    req.logout();
    res.redirect('/');
  }

但是Azure登录会话保持活动状态,因此当我重新进入我的网站时,身份验证请求将自动有效,不会显示登录页面。
我尝试了@Gary Liu - MSFT的建议来配置prompt:login选项,但正如@user3211705所评论的那样,这会使登录页面重新出现(即使我没有注销并且我有一个portal.azure.com标签打开),例如当我重新启动我的服务器时(注意:这并不是错误,但当我们正在开发时,经常重启服务器,这很烦人,需要一直登录)。
2)我的解决方案的一部分来自于这个post,它建议调用此url以注销Azure AD中的用户:
https://login.microsoftonline.com/<tennantid>/oauth2/logout

但仅仅这样做并不能适用于所有情况。
如果我在浏览器中打开多个窗口/标签页,通过调用此URL会使用户在Azure AD中无效,但我可以继续在其他标签页使用我的网站(似乎该标签页会话中的用户仍然保持活动状态)。
这类似于将我的网站放在一个标签页中,在另一个标签页中打开portal.azure.com,并在portal.azure.com中注销,这将使我的用户在Azure AD中失效。
因此,我的最终解决方案是两者的混合。
 logout: function(req, res) {
    req.logout();
    res.redirect('https://login.microsoftonline.com/<tennantid>/oauth2/logout');
  }

这将在请求中注销我的用户,并在Azure AD中调用注销认证。
仍然可以在注销URL参数?post_logout_redirect_uri=中添加重定向URI。
/oauth2/logout?post_logout_redirect_uri=<your website>

注意:在 Azure 应用程序配置中,<your website> 必须列在已批准的回复 URL 列表中。 - John Stephenson

1

退出应用程序并不意味着用户已从Azure注销。当用户退出应用程序时,您只需销毁应用程序对该用户的会话。当他们再次登录时,它将重定向到Azure(他们仍然登录,并且您的应用程序仍具有权限),然后立即使用该用户的令牌重定向回您的应用程序。您需要让用户注销Azure才能再次提示他们输入凭据。


1
好的,Azure 也可以注销吗?有没有相关的参考资料或教程? - user3211705

0

Azure xplat的代码,它们似乎没有调用显式的注销函数,而是简单地删除所有相关的客户端令牌。

如果没有本地令牌,您就无法登录!


我尝试清除本地存储,如id_token、session_state、state和code...但仍然无法注销...在Azure中是否有其他手动清除的方法? - user3211705

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接