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

9rbhqvlz  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(123)

我在Azure上部署了一个简单的使用Microsoft身份验证的登录和注销Node应用程序。我希望在使用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
从上面的截图中可以看到,用户可以通过身份验证,应用程序可以获得令牌和所有用户信息,页面应该重定向到带有用户信息的主页。但它从来没有以这种方式发生。
我希望弄清楚为什么登录后,页面不能正确显示正确的信息。可能是什么原因?

lh80um4z

lh80um4z1#

为了处理Azure AD身份验证并在成功登录后显示用户信息,我使用passportpassport-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}`);
    });

字符串

输出
本地

x1c 0d1x的数据

部署到App Service



请参考下面的MSDoc
Deploy a Node.js web app in Azure
Build and deploy a Node.js web application using Express

相关问题