{"record":{"id":"616243102038104c","repo":"alibaba/nacos","slug":"client-secret-is-required-for-state-signing","errorCode":null,"errorMessage":"Client secret is required for state signing","messagePattern":"Client secret is required for state signing","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/authenticate/AuthorizationCodeHandler.java","lineNumber":363,"sourceCode":"     * @param payload   the original payload\n     * @param signature the signature to verify\n     * @return true if signature is valid\n     */\n    private boolean hmacVerify(String payload, String signature) {\n        String expectedSignature = hmacSign(payload);\n        return expectedSignature.equals(signature);\n    }\n    \n    /**\n     * Get the signing key for HMAC operations.\n     * Uses client secret as the signing key.\n     *\n     * @return signing key\n     */\n    private String getSigningKey() {\n        String clientSecret = config.getClientSecret();\n        if (StringUtils.isBlank(clientSecret)) {\n            throw new IllegalStateException(\"Client secret is required for state signing\");\n        }\n        return clientSecret;\n    }\n    \n    /**\n     * Build logout URL for RP-initiated logout.\n     *\n     * @param idToken     ID token for logout hint\n     * @param redirectUri post-logout redirect URI\n     * @return logout URL or null if not supported\n     */\n    public String buildLogoutUrl(String idToken, String redirectUri) {\n        String endSessionEndpoint;\n        try {\n            endSessionEndpoint = metadataProvider.getMetadata().getEndSessionEndpoint();\n        } catch (Exception e) {\n            LOGGER.warn(\"Failed to discover OIDC logout endpoint: {}\", e.getMessage());\n            return null;","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/authenticate/AuthorizationCodeHandler.java#L345-L381","documentation":"Thrown by getSigningKey() when the configured client-secret is blank. The OIDC authorization-code flow reuses the client secret as the HMAC key to sign the self-contained state parameter (nonce.expirationTime.signature). Without it, CSRF state protection cannot operate.","triggerScenarios":"buildAuthorizationUrl() or verifyAndDecodeState() runs while config.getClientSecret() returns blank — i.e. the authorization-code login flow is active but client-secret was never set.","commonSituations":"Public (PKCE-only) OIDC client that legitimately has no secret but the built-in handler requires one; client-secret key mistyped; secret intentionally left blank during testing; migrating from a flow that didn't need signing.","solutions":["Set nacos.plugin.auth.oidc.client-secret to a non-blank value matching the IdP client registration.","If using a public/PKCE-only client with no secret, this built-in handler does not support it — register a confidential client with the IdP instead.","Verify the config map actually delivers the secret (check OidcAuthPluginConfig.getClientSecret())."],"exampleFix":"// before\nnacos.plugin.auth.oidc.client-id=public-client\n// no client-secret configured\n// after: register a confidential client and supply its secret\nnacos.plugin.auth.oidc.client-id=confidential-client\nnacos.plugin.auth.oidc.client-secret=generated-secret","handlingStrategy":"validation","validationCode":"// Validate at startup that the authorization-code flow can sign state\nif (config.isJwtValidation() /* or auth-code flow enabled */\n        && StringUtils.isBlank(config.getClientSecret())) {\n    throw new IllegalStateException(\n        \"client-secret is required for OIDC authorization-code flow\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat a blank client-secret as a fatal config error when the auth-code flow is enabled.","Register a confidential (not public) OIDC client with the IdP.","Add a startup assertion that fails the context if client-secret is missing."],"tags":["oidc","config","authentication","authorization-code"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}