I'm trying to adapt the sample B2C code referenced here and here to work against our organizations AAD.
I have a SPA app that is successfully authenticating with AAD via MSAL and receiving a token. The SPA app can use the token to pull data from the MS Graph API -- so I'm certain the token is valid.
The SPA is currently running locally @ localhost:9000.
I have a second app that is a Nodejs API running @ localhost:3000. The SPA app makes a call to the API passing the same token used for the GraphAPI. The API app is supposed to use that token to authenticate the user and provide access to the API; however, I only ever get back a 401 - Unauthorized.
(I'm using Aurelia for my client side code. HTTP request is made using Aurelia's HTTP client).
Here is the SPA code used to call the API:
//Not entirely sure what to use as the scope here!! API is registered to allow user.read Graph API scope.
this.config.msClient.acquireTokenSilent(["user.read"]).then(token => {
console.log("Token acquired silently.");
this.makeAPICall(token);
}, error => { ... }
);
makeAPICall(token) {
this.http.configure(config => {
config
.withBaseUrl('http://localhost:3000/')
.withDefaults({
headers: {
'Authorization': 'Bearer ' + token
}
}
this.http.fetch("user/0")
.then(response => {
debugger; //response is 401 Unauthenticated at this point
}, error => { ... });
}
I've registered an Application at apps.dev.microsoft.com for my API. And here is my server side (API) Nodejs code:
const express = require("express")
const port = 3000
const passport = require("passport")
var BearerStrategy = require("passport-azure-ad").BearerStrategy;
var userList = [
{id: 1, first: "Mickey", last: "Mouse", age: 95},
{id: 2, first: "Donald", last: "Duck", age: 85},
{id: 3, first: "Pluto", last: "leDog", age: 70}
]
var options = {
identityMetadata: "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration",
clientID: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", //My registered App Id
passReqToCallback: false,
validateIssuer: true,
issuer: "xxxxxxx" //Our tenant name
};
var strategy = new BearerStrategy(options, (token, done) => {
console.log(token);
done(null,{}, {scope: '*'});
})
const app = express()
app.use(passport.initialize())
passport.use(strategy);
//Allow CORS
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin","*");
res.header("Access-Control-Allow-Headers","Authorization, Origin, X-Requested-With, Content-Type,Accept");
next();
})
app.get("/",(request, response) => { //Unauthenticated -- always works
response.send("Hello World!")
})
app.get("/user/:id",passport.authenticate('oauth-bearer',{session: false }),
(request, response) => {
//Never seem to get here (when debugging) as authenticate always fails
let id = request.params["id"];
let user = userList[id];
if(user) response.json(user);
else response.send("No user found")
})
app.listen(port, () => {
console.log("Listening on port " + port)
})
I'm sure I'm just misunderstanding how this all works but would appreciate some guidance as to what I need to change to get this to work.