Skip to content

Instantly share code, notes, and snippets.

@mhagrelius
Created September 26, 2019 01:32
Show Gist options
  • Save mhagrelius/e8ca3287a11eba8d5400d9d6fc745859 to your computer and use it in GitHub Desktop.
Save mhagrelius/e8ca3287a11eba8d5400d9d6fc745859 to your computer and use it in GitHub Desktop.
Azure Ad + Passport.js + Microsoft Graph groups
'use strict'
const axios = require('axios').default
const passport = require('passport')
const { BearerStrategy } = require('passport-azure-ad')
const queryString = require('query-string')
const options = {
identityMetadata: `https://login.microsoftonline.com/${
process.env.AZURE_TENANTID
}/.well-known/openid-configuration`,
clientID: process.env.AZURE_CLIENTID,
passReqToCallback: true,
}
async function userFromJwt(jwt) {
const id = jwt.oid
try {
const tokenResponse = await axios.post(
`https://login.microsoftonline.com/${process.env.AZURE_TENANTID}/oauth2/v2.0/token`,
queryString.stringify({
client_id: process.env.AZURE_CLIENTID,
scope: 'https://graph.microsoft.com/.default',
client_secret: process.env.AZURE_CLIENTSECRET,
grant_type: 'client_credentials',
})
)
const accessToken = tokenResponse.data.access_token
if (id !== 'the application id itself goes here') {
const memberships = await axios.get(`https://graph.microsoft.com/v1.0/users/${id}/memberOf`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
// Could get a bit more robust here to make sure jwt properties exist
const user = {
name: jwt.name,
id,
email: jwt.upn,
groups: memberships.data.value.map(group => group.displayName),
}
return user
}
// Handle our user being the application itself
return {
name: 'Application Name',
id,
email: 'application email address',
groups: ['Admin Group '],
}
} catch (error) {
throw error
}
}
const bearerStrategy = new BearerStrategy(options, async (_, token, done) => {
userFromJwt(token)
.then(user => done(null, user))
.catch(error => done(error, null))
})
function configureAuth(app) {
app.use(passport.initialize())
passport.serializeUser((user, done) => {
done(null, user)
})
passport.deserializeUser((user, done) => {
done(null, user)
})
passport.use(bearerStrategy)
return app
}
module.exports = {
configureAuth,
userFromJwt,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment