passport-shraga is a passport.js authentication strategy that utilizes Shraga as an saml-idp proxy.
usage of passport-shraga is as followed:
const passport = require("passport");
const { Strategy } = require("passport-shraga");
passport.serializeUser((user, cb) => {
//serialize function
});
passport.deserializeUser((id, cb) => {
///deserialize function
});
const config = {};
passport.use(new Strategy(config, (profile, done) => {
console.log(`My Profile Is: ${profile}`);
done(null, profile);
}))// must be used for passport session
const session = require("express-session");
// must be used so passport can save and use cookies
const cookieParser = require("cookie-parser");
// require passport
const passport = require("passport");
// require code from previous section
const shraga = require("./passport.js");
// app intialization
app.use(cookieParser());
app.use(session({...config}));
app.use(passport.initialize());
app.use(passport.session());Two routes must be configured with passport authenticate middleware
app.get('/my/auth/route', passport.authenticate("shraga"), (req,res,next) => {
// user will not get here and will be redirected to shraga instance configured.
});
app.post('/my/auth/callback/route', passport.authenticate("shraga"), (req,res,next) => {
// user will be authenticated and exist in request.
console.log(req.user);
res.redirect('/home');
});callbackURL: callback url for Shraga to return the signed JWT. Can be absolute or relative ( http://my-domian/path-to-callback OR /path-to-callback )
shragaURL: Full URL to the Shraga instance running.
transform: Function Or Mapping-Object that transforms profile returned from Shraga.
useEnrichId: (boolean) set to true if you want Shraga to return user profile with enrichId. set to false to return user profile with SAML provider id.
allowedProviders: Array of allowed identity provider names - if argument is provided only identity providers in this list are allowed to return user profiles. disallowed providers will be followed with authentication failure.
RelayState: If RelayState is provided its value will be returned with user profile inside jwtBody ( as 'RelayState' ).
the tranform option can be configured if early manipulation of the User profile is required. transform can ve a function or an object:
- in case of
Function: the function will recieve the profile and do any manipulation wanted then returns a new profile object to replace current user Profile. example:
const tranform = (user) => {
const fullName = `${user.firstName} ${user.lastNmae}`;
return {...user, fullName};
}- in case of Object: the object will act as a mapper and can decide which user properties will be passed on to Authenticate function and under which name they will be passed on as. example:
const transform = {"id": "userId", "firstName":"fname", "lastName":"lname"};the returned object would be:
{userId: ObjectID, fname: String, lname: String}If 'RelayState' exists in request query params in 'get' method middleware then RelayState option will be set as the value of the query param.
const relayState = req.query.RelayState;
options.RelayState = options.RelayState || relayState; 'RelayState' should be concated to req.path or added ro req.query when you want your application to redirect to the value of req.user.RelayState like the following:
app.use('/auth/shraga', passport.autheticate('shraga'), (req,res,next) => {
const { RelayState } = req.user;
res.redirect(`${RelayState}`);
});