passport-azure-ad-oauth2-clientcert

0.3.0 • Public • Published

Passport-azure-ad-oauth2-clientcert

Passport strategy for authenticating with Azure AD using the OAuth 2.0 protocol and X.509 client certificate

Install

$ npm install passport-azure-ad-oauth2-clientcert

Overview

When using authorization code flow or hybrid flow in OpenID Connect, the client exchanges an authorization code for an access token. During this step, the client has to authenticate itself to the server.

One way to authenticate the client is by using a client secret like done with this passport strategy, which my package is extending.

The secret is just a string, so you have to make sure not to leak the value. The best practice is to keep the client secret out of source control. When you deploy to Azure, store the secret in an app setting.

However, anyone with access to the Azure subscription can view the app settings. Furthermore, there is always a temptation to check secrets into source control (for example, in deployment scripts), share them by email, and so on.

For additional security, you can use client assertion instead of a client secret. With client assertion, the client uses an X.509 certificate to prove the token request came from the client. The client certificate is installed on the web server. Generally, it will be easier to restrict access to the certificate, than to ensure that nobody inadvertently reveals a client secret. For more information about configuring certificates in a web app, see Using Certificates in Azure Websites Applications

Usage

Configure the strategy

Notice that the client_secret parameter is not used here. Instead, we pass one parameter:

pem: Content of a PEM file that contains the private key and the certificate. The private key is never sent on the wire, instead it's used to sign a JWT that will be eventually send to the Identity provider (AAD) to retrieve the access token.

    passport.use(new AzureAdOAuth2CertStrategy({
        authorizationURL: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
        tokenURL:'https://login.microsoftonline.com/common/oauth2/v2.0/token',
        clientID: '<client Id>',
        callbackURL: '<redirect url>',
        pem: '<PEM file content>'
    },
        function (accessToken, refresh_token, params, profile, done) {
            var decodedToken = jwt.decode(params.id_token);
            const userProfile = {
                displayName: decodedToken.name,
                emails: [{ value: decodedToken.preferred_username.toLowerCase() }],
                roles: decodedToken.roles,
                tenantID: decodedToken.tid
            };
            done(undefined, userProfile);
    }));    

Setup route handler for the root of your application that needs to be protected for authorized users only.

app.get('/', (req, res) => {
    if (!req.isAuthenticated()) {
        return res.redirect('/auth/azureadoauth2');
    }
    return res.render('index', { user: req.user });
});

Setup route that will be called when authentication is needed

app.get('/auth/azureadoauth2',
    passport.authenticate('azure_ad_oauth2_clientcert', authOptions),
    function (req, res) {
        res.redirect('/');
    });

Setup route that will handle the authentication flow after user was authenticated. In this step, we exchange the authorization code with the access token by calling the token endpoint using the client certificate

app.get('/auth/azureadoauth2/callback',
    passport.authenticate('azure_ad_oauth2_clientcert', { failureRedirect: '/login' }),
    function (req, res) {
        res.redirect('/');
    });

Setup route that will logout the user

app.get('/logout', (req, res) => {
    req.logOut();
    return res.redirect('/');
});

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 0.3.0
    3
    • latest

Version History

Package Sidebar

Install

npm i passport-azure-ad-oauth2-clientcert

Weekly Downloads

19

Version

0.3.0

License

MIT

Unpacked Size

6.82 kB

Total Files

4

Last publish

Collaborators

  • arieschwartzman