Noteworthy Programming Masterpiece
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    passport-reverseproxypublic

    Passport-ReverseProxy

    HTTP reverse proxy authentication strategies for Passport.

    This module lets you authenticate HTTP requests using HTTP header values injected by a HTTP reverse proxy server in front of your application server. Reverse proxy authentication is a technique for enterprise networks to provide Single Sign On (SSO) for enterprise users.

    By plugging into Passport, support for these schemes can be easily and unobtrusively integrated into any application or framework that supports Connect-style middleware, including Express.

    Install

    $ npm install passport-reverseproxy
    

    Usage of HTTP

    Using Apache as a reverse proxy

    Here is an example of configuring Apache for use as a reverse proxy using a local passwd file.

    Credit: Jenkins Reverse Proxy Auth Plugin

    <Location />
        AuthName "Please sign in with your Apache user name and password"
        AuthType BASIC
        AuthUserFile /etc/apache2/passwd
        Require valid-user
    
        # prevent the client from setting this header
        RequestHeader unset X-Forwarded-User
    
        # Adds the X-Forwarded-User header that indicates the current user name.
        # this portion came from http://old.nabble.com/Forcing-a-proxied-host-to-generate-REMOTE_USER-td2911573.html#a2914465
        RewriteEngine On
        # see the Apache documentation on why this has to be lookahead
        RewriteCond %{LA-U:REMOTE_USER} (.+)
        # this actually doesn't rewrite anything. what we do here is to set RU to the match above
        RewriteRule .* - [E=RU:%1]
        RequestHeader set X-Forwarded-User %{RU}e
    </Location>
    

    Notes:

    • Make sure that clients cannot bypass the reverse proxy. If they can send requests directly to Jenkins, then a malicious client can send in arbitrary header name with arbitrary value, thus compromising the security of Jenkins
    • Make sure you configure the reverse proxy to erase the header that you use to pass the authenticated user name. This prevents malicious client from setting the header name with arbitrary value, which would ruin the security.

    Configure Strategy

    The HTTP Reverse proxy authentication strategy authenticates users by inspecting a configurable set of HTTP request headers.

    By default, the strategy will look for a request header named 'X-Forwarded-User', which will be used as the value for req.user.username.

    Optionally, you can specify the request headers that should participate in authentication decisions via the options.headers map:

    var express = require('express'),
        passport = require('passport'),
        ReverseProxyStrategy = require('passport-reverseproxy');
    
    passport.use(new ReverseProxyStrategy({
        headers: {
          'X-Forwarded-User': { alias: 'username', required: true },
          'X-Forwarded-UserEmail': { alias: 'email', required: false }
        }
      })
    );
    
    // require authentication for all requests except favicon.ico
    app.configure(function() {
      app.use(express.favicon())
      app.use(express.bodyParser());
      app.use(passport.initialize());
      app.use(passport.authenticate('reverseproxy', { session: false }));
      app.use(express.static(path.join(__dirname, 'public')));
    });
    

    You can also specify a network range as a whitelist of allowed client connections to your app. The whitelist is a cursory security check to verify the end user did not circumvent the reverse proxy server. Your deployment should use this setting merely as a defense in depth layer alongside more robust network access control techniques (e.g., IPSec tunnels, VLANs, firewall rules). Advanced enterprise reverse proxy appliances may also include a non-repudiatable token, like a digital signature, that you should validate in the verify function.

    passport.use(new ReverseProxyStrategy({
        headers: {
          'X-Forwarded-User': { alias: 'username', required: true },
          'X-Forwarded-UserId': { alias: 'id', required: false }
        },
         // only allow localhost to proxy requests
        whitelist: '127.0.0.1/0'
      })
    );
    

    Unlike most Passport authentication strategies, it is unlikely you will need session caching of the authentication ticket, since the reverse proxy should inject the headers into every request to your server.

    The strategy optinally supports a verify callback, which accepts these reverse proxy header values and calls done providing a user.

    passport.use(new ReverseProxyStrategy({
       headers: { 
          'X-Forwarded-User': { alias: 'username', required: true },
          'X-Forwarded-UserId': { alias: 'id', required: false }
       },
       // only allow localhost to proxy requests
       whitelist: '127.0.0.1/0'
      },
      function(headers, user, done) {
        var err = null;
    
        // verify that the username is an email address
        if (! /^.*@.*$/.test(headers['X-Forwarded-User'])) { return done(err, false, 401); }
    
        return done(err, user);
      })
    );
    

    Authenticate Requests

    Use passport.authenticate(), specifying the 'reverseproxy' strategy, to authenticate requests. Requests relying on request header values are inherently stateless, and should not require session support, so the session option can be set to false.

    For example, as route middleware in an Express application:

    app.get('/private', 
      passport.authenticate('reverseproxy', { session: false }),
      function(req, res) {
        res.json(req.user);
      });
    

    Examples

    For a complete, working example, refer to the Reverse Proxy example.

    Credits

    License

    The MIT License

    Keywords

    none

    install

    npm i passport-reverseproxy

    Downloadsweekly downloads

    8

    version

    0.1.0

    license

    none

    repository

    githubgithub

    last publish

    collaborators

    • avatar