Search code examples
oauthauth0

mock auth0 server in continuous integration environment with no internet


I want to write e2e tests that can run in our CI environment which is tightly locked down and has no internet access.

I am using the auth0 react loginWithRedirect function which will attempt to redirect to the auth0 login on their servers and will timeout on CI.

I am able to intercept the call to /authorize in express:

app.get('/auth0/:simulation_id/authorize', middleware, (req, res) => {
  const { client_id, redirect_uri, scope, state } = req.query;

Is it now possible for me to generate a mock oauth token that will be accepted by the @auth0/react client code?


Solution

  • Yes. Using the jsrsasign.js library, where accessKey contains a private key:

    function createJwt(username, type, realm, scopes, sessionId, expires_in, audience) {
    
        var oHeader = {
            alg: 'RS256',
            typ: 'JWT'
        };
        // Payload
        var oPayload = {};
        var tNow = jwt.KJUR.jws.IntDate.get('now');
        var token_expiry = expires_in;
        var tEnd = tNow + token_expiry;
    
        oPayload.sub = username;
        oPayload.auditTrackingId = uuidv4();
        oPayload.iss = "https://mock.org/identities/v1/" + realm + "/token";
        oPayload.tokenName = type;
        oPayload.token_type = 'Bearer';
        oPayload.authGrantId = !sessionId ? uuidv4() : sessionId;
        oPayload.aud = (audience ? audience : "https://mock.org/identities/v1/" + realm + "/token");
    
        oPayload.nbf = tNow;
        oPayload.scope = scopes;
        // oPayload.auth_time = tNow;
        oPayload.realm = '/' + realm;
    
        oPayload.exp = tEnd;
        oPayload.expires_in = token_expiry * 100000;
        oPayload.iat = tNow;
    
        oPayload.jti = uuidv4();
    
        var sHeader = JSON.stringify(oHeader);
        var sPayload = JSON.stringify(oPayload);
    
        var prvKey = accessKey;
    
        var sJWT = jwt.KJUR.jws.JWS.sign("RS256", sHeader, sPayload, prvKey);
    
    
        return sJWT;
    }
    

    Set the audience, subject, scp and any other properties in line with the tokens that auth0 is creating.

    You also might need to mock out the jwk endpoints, but I doubt the library will care. If it doesn't work it will be due to certain properties not being available on the token.

    You might need to create an id token as well, depending on your setup.

    Access key is similar to this:

    var accessKey = jwt.KEYUTIL.getKey("-----BEGIN PRIVATE KEY-----\n" +
        "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC0g+nePEZ6aFiH\n" +
        "ccnle/ryqz1lNvloPGuA5b6GeE8MrT7SATxv54zQ2LnvuRp86cd32elL0YAw3GMc\n" +
    
    ... snip ...
    
        "Rno3R82z6SAvy9HgIMzfti5NSVgqC9nmhFEs+ChFWuboGotVV99COVJId9S/567n\n" +
        "kz90cLENtD/8JTYAhLea5F/PJBJJHSvQT298ZxR4bw1vQ5Bq2FMnLSYuIOQMkQdr\n" +
        "Yqt+8gXW0+3kfyb3cCyI+2HKcQ==\n" +
        "-----END PRIVATE KEY-----\n");
    

    And keep going til you've mocked out the entire IdP platform :) (I basically did the same thing with OpenAM a few years ago).