justauth/JustAuth · error · AuthException

5015

5015

Error message

Invalid client secret

What it means

AuthException with AuthResponseStatus.ILLEGAL_CLIENT_SECRET (code 5015) from AuthAppleRequest.checkConfig: config.getClientSecret() is empty. For Apple this field must hold the .p8 private key content — JustAuth itself builds the JWT client secret from it in getToken().

Source

Thrown at src/main/java/me/zhyd/oauth/request/AuthAppleRequest.java:102

        // https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#3383773
        return AuthUser.builder()
            .rawUserInfo(object)
            .uuid(object.getString("sub"))
            .email(object.getString("email"))
            .username(authToken.getUsername())
            .token(authToken)
            .source(source.toString())
            .build();
    }

    @Override
    protected void checkConfig(AuthConfig config) {
        super.checkConfig(config);
        if (StringUtils.isEmpty(config.getClientId())) {
            throw new AuthException(AuthResponseStatus.ILLEGAL_CLIENT_ID, source);
        }
        if (StringUtils.isEmpty(config.getClientSecret())) {
            throw new AuthException(AuthResponseStatus.ILLEGAL_CLIENT_SECRET, source);
        }
        if (StringUtils.isEmpty(config.getKid())) {
            throw new AuthException(AuthResponseStatus.ILLEGAL_KID, source);
        }
        if (StringUtils.isEmpty(config.getTeamId())) {
            throw new AuthException(AuthResponseStatus.ILLEGAL_TEAM_ID, source);
        }
    }

    /**
     * 获取token
     * @see <a href="https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret">creating-a-client-secret</a>
     * @return jwt token
     */
    private String getToken() {
        return Jwts.builder().header().add(AbstractJwk.KID.getId(), this.config.getKid()).and()
            .issuer(this.config.getTeamId())
            .subject(this.config.getClientId())

View on GitHub (pinned to 694bbf1b01)

Solutions

  1. Paste the full contents of the .p8 key (including BEGIN/END PRIVATE KEY lines) into clientSecret
  2. If loading from a file/vault, read it into the string at startup before building AuthConfig
  3. Do not confuse clientSecret (.p8 PEM) with kid (key identifier) or teamId

Example fix

// before
.clientSecret("/etc/keys/AuthKey_ABC123.p8")

// after
String pem = new String(Files.readAllBytes(Path.of("/etc/keys/AuthKey_ABC123.p8")), UTF_8);
AuthConfig.builder().clientSecret(pem)...
Defensive patterns

Strategy: validation

Validate before calling

String pem = config.getClientSecret();
if (StringUtils.isEmpty(pem) || !pem.contains("BEGIN PRIVATE KEY")) {
    throw new IllegalStateException("APPLE clientSecret must be the .p8 PEM content");
}

Prevention

When it happens

Trigger: Constructing AuthAppleRequest without clientSecret, or with a path to the .p8 file instead of the file's PEM content.

Common situations: Developer put the file path or key id into clientSecret instead of the PEM body; the .p8 content loaded with escaped newlines (\n literals) making it 'present' but unusable — here it must merely be non-empty, but empty values fail this check; secret managed via vault and not injected.

Related errors


AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14). Data as JSON: /api/errors/ad719b52698e6c24. Report an issue: GitHub.