JackONeill
JackONeill

Reputation: 123

Module passport-oauth2 in nodej.js: extra parameters to be included in the authorization request

I have a problem with implementing an Oauth2 authentication in node.js application where I need to add one extra parameter in the authorization request, but the module simply ignores the "unknown" parameters.

My code is attached below. The parameter being ignored is APIName.

var OAuth2Strategy = require('passport-oauth2').Strategy;

// load the auth variables
var configAuth = require('./auth');

module.exports = function(passport) {

    passport.use('ihealth', new OAuth2Strategy({
            authorizationURL: 'https://api.ihealthlabs.com:8443/OpenApiV2/OAuthv2/userauthorization/',
            tokenURL: 'https://api.ihealthlabs.com:8443/OpenApiV2/OAuthv2/userauthorization/',
            clientID: configAuth.iHealthAuth.clientID,
            clientSecret: configAuth.iHealthAuth.clientSecret,
            callbackURL: configAuth.iHealthAuth.callbackURL,
            APIName : 'OpenApiActivity'
        },
        function(token, refreshToken, profile, done) {

            // ...

        }
    ));
};

The reason that I know APIName is being ignored, is that I see the URL in the browser:

https://api.ihealthlabs.com:8443/OpenApiV2/OAuthv2/userauthorization/?response_type=code&redirect_uri=SOMEREDIRECTURI&client_id=SOMECLIENTID

I am wondering how to enable adding extra parameters to the authorization request? Maybe by overriding the function OAuth2Strategy.prototype.authorizationParams in node_modules/passport_oauth2/lib/strategy.js, which looks like this in the donwloaded file:

/**
 * Return extra parameters to be included in the authorization request.
 *
 * Some OAuth 2.0 providers allow additional, non-standard parameters to be
 * included when requesting authorization.  Since these parameters are not
 * standardized by the OAuth 2.0 specification, OAuth 2.0-based authentication
 * strategies can overrride this function in order to populate these parameters
 * as required by the provider.
 *
 * @param {Object} options
 * @return {Object}
 * @api protected
 */
OAuth2Strategy.prototype.authorizationParams = function(options) {
  return {};
};

Upvotes: 4

Views: 3052

Answers (2)

balafi
balafi

Reputation: 2153

You can override OAuth2Strategy.prototype.authorizationParams as follows

 var myStrategy = new OAuth2Strategy({
        authorizationURL: 'https://api.ihealthlabs.com:8443/OpenApiV2/OAuthv2/userauthorization/',
        tokenURL: 'https://api.ihealthlabs.com:8443/OpenApiV2/OAuthv2/userauthorization/',
        clientID: configAuth.iHealthAuth.clientID,
        clientSecret: configAuth.iHealthAuth.clientSecret,
        callbackURL: configAuth.iHealthAuth.callbackURL
    },
    function(token, refreshToken, profile, done) {
        // ...
    });

    myStrategy.authorizationParams = function(options) {
      return {
        APIName : 'OpenApiActivity'
      };
    };

    passport.use('ihealth',myStrategy);

For Microsoft ADFS OAuth 2, this can be used to add the required source parameter; if one wants the callback to include some specific value too, then add the state parameter.

The options in function(options) can be set when calling passport.authenticate:

router.get('/auth', passport.authenticate('ihealth', {time: Date.now()}));

Upvotes: 8

JackONeill
JackONeill

Reputation: 123

In this time I managed to find a workaround. Maybe it will help someone with a similar problem.

For the solution I didn't use the well known modules such as passport-oauth2 or simple-oauth2, but just the modules querystring for building the request URL and the module request for making the HTTP calls.

Example:

var express = require('express');
var router = express.Router();
var request = require('request');
var qs = require('querystring');
var configAuth = require('../config/auth');

var authorization_url_site = configAuth.iHealthAuth.authorizationSite;
var authorization_url_params = {
    response_type : 'code',
    client_id: configAuth.iHealthAuth.clientID,
    redirect_uri: configAuth.iHealthAuth.callbackURL,
    APIName : configAuth.iHealthAuth.APIName
};
var authorization_uri = authorization_url_site + '?' + qs.stringify(authorization_url_params);

var token_url_site = configAuth.iHealthAuth.tokenSite;
var token_url_params = {
    grant_type : 'authorization_code',
    client_id: configAuth.iHealthAuth.clientID,
    client_secret: configAuth.iHealthAuth.clientSecret,
    redirect_uri: configAuth.iHealthAuth.callbackURL,
    code: req.query.code
};
var token_uri = token_url_site + '?' + qs.stringify(token_url_params);

// Initial page redirecting to the login page
router.route('/auth')
    .get(function (req, res) {
            res.redirect(authorization_uri);
    });

// Callback service parsing the authorization token and asking for the access token
router.route('/')
    .get(function(req, res) {

        request(token_uri, function(err, response, body) {
                if(err) {
                    throw err;
                } else {
                    var data = JSON.parse(body);
                    // save token to database or file
                    saveToken(data);
                }
            });
        });
    });

module.exports = router;

Upvotes: 0

Related Questions