Search code examples
node.jspassport.jsadalpassport-azure-ad

Trouble using passport-azure-ad OIDCStrategy with Passportjs


I'm trying to use passport-azure-ad to authenticate a user. The app displays the common login screen but when I hit Sign in, the browser window goes blank and shows a spinner indicating its working. My server, meanwhile, is receiving a continuous stream of POST requests to my callback endpoint.

During this time, none of my passport functions (verification, serializeUser and deserializeUser) are ever called.

here is my strategy definition:

    passport.use("azure", new azureStrategy({
    identityMetadata: 'https://login.microsoftonline.com/common/.well-known/openid-configuration',
    clientID: "*************************",
    responseType: 'code id_token',
    issuer: "https://sts.windows.net/********************/",
    responseMode: 'form_post',
    redirectUrl: "http://localhost:5055/auth/azure/callback",
    allowHttpForRedirectUrl: true,
    clientSecret: "**********************************"
}, function(iss, sub, profile, accessToken, refreshToken, done) {
    console.log("ID TOken: ", profile.oid); //Never gets called
    console.log("User" ,profile) //Never gets called
    done(null, profile);
}));

passport.serializeUser(function(user, done){
    console.log("serialize: ", user)  //Never gets called
    done(null, user);
})

passport.deserializeUser((user, done) => {
    console.log("deserialize: ", user)  //never gets called
    done(null, user);
})   

And here are my route definitions:

app.get("/auth/azure", passport.authenticate('azure', {failureRedirect: '/'}))

app.post("/auth/azure/callback",
  (req, res, next) => {
    console.log("POST Callback Received!");
    next();
  },
  passport.authenticate("azure", {
    failureRedirect: "/error.html"
  }),
  (req, res) => {
    console.log("Recieved POST callback")
    res.redirect("/user")
  })

A few things to mention:

  1. I'm developing the app for my organization so it should only authenticate users in our AD.
  2. I initially tried using the https://login.microsoft.com/<tenant>... version of the identityMetadata but I received an error about the Application not being supported for the API version -- using common seems to have resolved that issue.
  3. As I mentioned above, the console.log() code in the serializeUser, deserializeUser, and the verification callback never gets called.

The console window on my nodejs server simply shows this:

Request at:  1477083649230 GET / {}          
Request at:  1477083649235 GET /login.html {}
Request at:  1477084498737 GET /auth/azure {}
Request at:  1477085275630 POST /auth/azure/callback {}
POST Callback Received!
Request at:  1477085275980 POST /auth/azure/callback {}
POST Callback Received!
Request at:  1477085276335 POST /auth/azure/callback {}
POST Callback Received!
Request at:  1477085276679 POST /auth/azure/callback {}
POST Callback Received!
Request at:  1477085277042 POST /auth/azure/callback {}
POST Callback Received!

You can see that that just goes on until I kill that session or browse to a different page on the site. Notice too, that while the POST Callback log is made, the log that takes place AFTER the authentication never does.

Any help would be greatly appreciated.


Solution

  • When working with the Google auth strategy, I was posting back using GET; however, when I followed the Azure sample, we began posting back with a POST.

    I was stripping out everything from the sample that I assumed was unnecessary. One of those things was bodyParser. Unfortunately, this was a necessary piece so that Passport can parse the body of the POST request to get to the information being sent back from the auth server.

    So, the required bits were as follows:

    var parser = require("body-parser")
    
    ... 
    //before passport.initialize()
    app.use(parser.urlencoded({extended: true}));
    

    That's all it took and everything began working as it ought. Hope this saves someone else all the headache!