Azure Node Web 应用 Entra ID 登录页面重定向问题

问题描述 投票:0回答:1

我在 Azure 上部署了一个使用 Microsoft 身份验证的简单登录和注销节点应用程序。我希望使用 Entra ID 登录后,重定向页面可以返回带有用户信息的主页。但登录后,页面仍然没有显示用户信息。该应用程序在本地运行良好,但在 Azure 中运行不佳。我想知道为什么。

登录前首页:欢迎您,请登录。

登录后正确首页:用户名、邮箱。

登录后首页错误:欢迎您,请登录。

一些代码:

const express = require("express");
const ejs = require("ejs");
const msal = require("@azure/msal-node");
const jwt = require("jsonwebtoken");
const session = require("express-session");
require("dotenv").config();

const app = express();
app.set("view engine", "ejs");

app.use(
  session({
    secret: process.env.SESSION_SECRET || "local_default_secret",
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true },
  })
);

const msalConfig = {
  auth: {
    clientId: process.env.AZURE_CLIENT_ID,
    authority: `https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}`,
    clientSecret: process.env.AZURE_CLIENT_SECRET,
  },
  system: {
    loggerOptions: {
      loggerCallback(loglevel, message, containsPii) {
        console.log(message);
      },
      piiLoggingEnabled: false,
      logLevel: msal.LogLevel.Verbose,
    },
  },
};

const pca = new msal.ConfidentialClientApplication(msalConfig);

function getRedirectUri() {
  return process.env.PROD_REDIRECT_URI;
}

app.get("/", (req, res) => {
  res.render("index", {
    isAuthenticated: req.session.isAuthenticated,
    user: req.session.user || null,
  });
});

app.get("/login", async (req, res) => {
  try {
    const authCodeUrlParameters = {
      scopes: ["user.read"],
      redirectUri: getRedirectUri(),
    };
    const loginUrl = await pca.getAuthCodeUrl(authCodeUrlParameters);
    res.redirect(loginUrl);
  } catch (error) {
    console.error(error);
    res.status(500).send("Error building auth code URL");
  }
});

app.get("/redirect", async (req, res) => {
  const tokenRequest = {
    code: req.query.code,
    scopes: ["user.read"],
    redirectUri: getRedirectUri(),
  };

  try {
    const response = await pca.acquireTokenByCode(tokenRequest);
    req.session.isAuthenticated = true;
    req.session.user = jwt.decode(response.accessToken);
    console.log("I am here!");
    res.redirect("/");
    console.log("I am still here!");
    console.log("Session here: ", req.session);
  } catch (error) {
    console.error(error);
    if (error.name === "ClientAuthError") {
      res.status(401).send("Authentication failed. Please try to login again.");
    } else {
      res.status(500).send("Error acquiring token");
    }
  }
});

app.get("/signout", (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      console.error(err);
      return res.status(500).send("Error during sign out.");
    }

    // Determine the post logout redirect URI based on the environment
    const postLogoutRedirectUri = process.env.PROD_URI;

    // Redirect to Azure AD logout URL
    const tenantId = process.env.AZURE_TENANT_ID;
    const logoutUri = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/logout?post_logout_redirect_uri=${postLogoutRedirectUri}`;
    res.redirect(logoutUri);
  });
});

const port = process.env.PORT;
app.listen(port, () => console.log(`Server running on port ${port}`));

在 Azure 日志中: enter image description here

从上面的屏幕截图中可以看到,用户可以通过身份验证,应用程序可以获取令牌和所有用户信息,并且页面应该重定向到包含用户信息的主页。但它永远不会以这种方式发生。

我希望弄清楚为什么登录后页面无法正确显示正确的信息。可能是什么原因?

azure authentication redirect
1个回答
0
投票

为了处理 Azure AD 身份验证并在成功登录后显示用户信息,我使用

passport
passport-azure-ad
库来处理身份验证过程。它手动管理会话和用户身份验证状态。 Passport-azure-ad 包让您可以在 Express 应用程序中轻松启动和运行 Azure AD 身份验证。

代码:

//app.js
    const  express  =  require('express'); 
    const  passport  =  require('passport');
    const  OIDCStrategy  =  require('passport-azure-ad').OIDCStrategy;
    const  app  =  express();
    // Configure session
    app.use(require('express-session')({ secret:  'your-secret-key', resave:  true, saveUninitialized:  true }));
    // Initialize passport
    app.use(passport.initialize());
    app.use(passport.session());
    // Ensure authenticated middleware
    function  ensureAuthenticated(req, res, next) {
    if (req.isAuthenticated()) {
    return  next();
    }
    res.redirect('/');
    }
    // Configure Azure AD authentication
    passport.use(new  OIDCStrategy({
    identityMetadata:  'https://login.microsoftonline.com/tenantId/v2.0/.well-known/openid-configuration',
    clientID:  'clientID',
    responseType:  'code',
    responseMode:  'query',
    redirectUrl:  'http://localhost:3000/auth/callback',
    allowHttpForRedirectUrl:  true,
    clientSecret:  'clientSecret',
    validateIssuer:  false,  
    passReqToCallback:  false,
    scope: ['openid', 'profile'],
    },
    (iss, sub, profile, accessToken, refreshToken, done) => {
    return  done(null, profile);
    }));
    passport.serializeUser((user, done) =>  done(null, user));
    passport.deserializeUser((obj, done) =>  done(null, obj));
   
    // Routes
    app.get('/', (req, res) => {
    if (req.isAuthenticated()) {
    res.send(`Welcome, ${req.user.displayName}! <a href="/logout">Logout</a>`);
    } else {
    res.send('Home Page <a href="/login">Login</a>'); 
    }
    });
    app.get('/login', passport.authenticate('azuread-openidconnect')); 
    app.get('/auth/callback',
    passport.authenticate('azuread-openidconnect', { failureRedirect:  '/' }),
    (req, res) => {
    res.redirect('/home');
    });
    app.get('/home', ensureAuthenticated, (req, res) => {
    
    res.send(`Welcome, ${req.user.displayName}! <a href="/logout">Logout</a>`);
    
    });
    app.get('/logout', (req, res) => {
    req.logout();
    res.redirect('/');
    });
    // Start server
    const  PORT  =  process.env.PORT  ||  3000;
    app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
    });

输出

本地

enter image description here

部署到应用服务

enter image description here

请参考下面的MSDoc

在 Azure 中部署 Node.js Web 应用程序

使用 Express 构建和部署 Node.js Web 应用程序

© www.soinside.com 2019 - 2024. All rights reserved.