在没有互联网的持续集成环境中模拟 auth0 服务器

mock auth0 server in continuous integration environment with no internet

我想编写可以 运行 在我们的 CI 环境中编写的 e2e 测试,该环境被严格锁定且无法访问互联网。

我正在使用 auth0 react loginWithRedirect function,它将尝试重定向到他们服务器上的 auth0 登录,并会在 CI.

时超时

我可以在 express:

中拦截对 /authorize 的调用
app.get('/auth0/:simulation_id/authorize', middleware, (req, res) => {
  const { client_id, redirect_uri, scope, state } = req.query;

我现在可以生成将被 @auth0/react 客户端代码接受的模拟 oauth 令牌吗?

是的。使用 jsrsasign.js 库,其中 accessKey 包含私钥:

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;
}

根据 auth0 创建的令牌设置受众、主题、scp 和任何其他属性。

您可能还需要模拟 jwk 端点,但我怀疑图书馆会关心。如果它不起作用,那将是由于令牌上的某些属性不可用。

您可能还需要创建一个 ID 令牌,具体取决于您的设置。

访问密钥类似于:

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");

继续前进,直到模拟出整个 IdP 平台 :)(几年前我基本上对 OpenAM 做了同样的事情)。

除了@stringy05 的回复;如果你有后端服务(例如 Java、.NET 等)由你的 React 应用程序调用并且需要进行 JWT 验证,你可能需要静态托管你自己的 OpenID 配置和 JSON Web 密钥在您自己的环境中设置端点。

这是因为 JWT 验证(通过后端服务)仍然需要与外部授权服务器通信。对于基于 JWT 的身份验证,这通常仅限于单个(预先或延迟加载)请求以获取用于签名验证的 public 密钥,但也可能有其他调用,例如当服务在 JWT 上遇到未知的 kid(密钥 ID)以及定期刷新间隔(例如每天)时。

对于 Auth0 OpenID 配置和 JSON Web 密钥集端点托管在以下位置:

  • OpenID 配置: https://[tenant-name].[2-letter-iso-country-code].auth0.com/.well-known/openid-configuration
  • JSON Web 密钥集: https://[tenant-name].[2-letter-iso-country-code].auth0.com/.well-known/jwks.json

这些只是静态 JSON 文档。您可能只需从现有租户之一复制这些内容,进行相应修改,然后在您自己的环境中托管。您需要进行的修改包括:

  • OpenID 配置以引用本地 jwks_uri 端点。
  • 更新 JSON Web 密钥集端点中的密钥信息。注意:您可以使用 OpenSSL 生成非对称密钥对,有关如何从 public 密钥(JWKS 文档需要)中提取模数和指数的信息,请参阅 here。注意:在您的 React 应用程序中,您需要使用您生成的私钥对令牌进行签名。

完成上述操作后,您的后端服务可以引用本地托管的 OpenID 配置,并且无需与外部授权服务器通信即可进行 JWT 验证。