{"record":{"id":"b533eeb44c288d3b","repo":"apereo/cas","slug":"request-is-not-signed-but-should-be","errorCode":null,"errorMessage":"Request is not signed but should be","messagePattern":"Request is not signed but should be","errorType":"exception","errorClass":"SAMLException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/AbstractSamlIdPProfileHandlerController.java","lineNumber":440,"sourceCode":"\n    protected void verifyAuthenticationContextSignature(final Pair<? extends SignableSAMLObject, MessageContext> authenticationContext,\n                                                        final HttpServletRequest request, final RequestAbstractType authnRequest,\n                                                        final SamlRegisteredServiceMetadataAdaptor adaptor,\n                                                        final SamlRegisteredService registeredService) throws Throwable {\n        val ctx = authenticationContext.getValue();\n        verifyAuthenticationContextSignature(ctx, request, authnRequest, adaptor, registeredService);\n    }\n\n    protected void verifyAuthenticationContextSignature(final MessageContext ctx,\n                                                        final HttpServletRequest request,\n                                                        final RequestAbstractType authnRequest,\n                                                        final SamlRegisteredServiceMetadataAdaptor adaptor,\n                                                        final SamlRegisteredService registeredService) throws Throwable {\n        if (!SAMLBindingSupport.isMessageSigned(ctx)) {\n            LOGGER.trace(\"The authentication context is not signed\");\n            if (adaptor.isAuthnRequestsSigned() && !registeredService.isSkipValidatingAuthnRequest()) {\n                LOGGER.error(\"Metadata for [{}] says authentication requests are signed, yet request is not\", adaptor.getEntityId());\n                throw new SAMLException(\"Request is not signed but should be\");\n            }\n            LOGGER.trace(\"Request is not signed or validation is skipped, so there is no need to verify its signature.\");\n        } else if (adaptor.isAuthnRequestsSigned() && !registeredService.isSkipValidatingAuthnRequest()) {\n            LOGGER.trace(\"The authentication context is signed; Proceeding to validate signatures...\");\n            configurationContext.getSamlObjectSignatureValidator().verifySamlProfileRequest(authnRequest, adaptor, request, ctx);\n        }\n    }\n\n    protected Pair<SamlRegisteredService, SamlRegisteredServiceMetadataAdaptor> getRegisteredServiceAndFacade(\n        final AuthnRequest authnRequest, final HttpServletRequest httpServletRequest) {\n        val issuer = SamlIdPUtils.getIssuerFromSamlObject(authnRequest);\n        LOGGER.debug(\"Located issuer [{}] from authentication context\", issuer);\n\n        val registeredService = verifySamlRegisteredService(issuer, httpServletRequest);\n\n        LOGGER.debug(\"Located SAML metadata for [{}]\", registeredService.getServiceId());\n        val adaptor = getSamlMetadataFacadeFor(registeredService, authnRequest);\n","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/AbstractSamlIdPProfileHandlerController.java#L422-L458","documentation":"During SP-initiated AuthnRequest validation the IdP checks whether the request message is signed. If the IdP metadata says AuthnRequests must be signed and the SP has not opted out of signature validation, an unsigned request is rejected with SAMLException.","triggerScenarios":"verifyAuthenticationContextSignature sees SAMLBindingSupport.isMessageSigned(ctx)==false while adaptor.isAuthnRequestsSigned() is true and registeredService.isSkipValidatingAuthnRequest() is false — i.e. an unsigned AuthnRequest (e.g. via redirect binding without sigAlg) arrives for a service requiring signed requests.","commonSituations":"SP sends unsigned redirect-binding AuthnRequests while IdP metadata flag WantAuthnRequestsSigned/authnRequestsSigned is enabled; SP never signs requests; service registered with wrong metadata lacking the signed-requests flag.","solutions":["Configure the SP to sign its AuthnRequests (sign redirect binding with sigAlg, or use POST binding signed).","Set cas.authn.saml.idp.webflow... skip validation for the service: registeredService.setSkipValidatingAuthnRequest(true) if policy allows unsigned requests.","Correct the SP metadata so isAuthnRequestsSigned reflects the SP's actual behavior.","Verify the signature arrived but failed binding-level detection — check the SigAlg/Signature query parameters are intact (no proxy stripping)."],"exampleFix":"// before\nservice.setSkipValidatingAuthnRequest(false); // SP sends unsigned requests\n// after\nservice.setSkipValidatingAuthnRequest(true); // or configure SP to sign AuthnRequests","handlingStrategy":"try-catch","validationCode":"val signed = SAMLBindingSupport.isMessageSigningContext(ctx) || request.getParameter(\"Signature\") != null;\nval mustSign = adaptor.isAuthnRequestsSigned() && !registeredService.isSkipValidatingAuthnRequest();\nif (mustSign && !signed) LOGGER.warn(\"Service [{}] will reject this unsigned AuthnRequest\", registeredService.getName());","typeGuard":"boolean willPassSignatureCheck(ctx, adaptor, service) {\n    return SAMLBindingSupport.isMessageSigned(ctx) || !adaptor.isAuthnRequestsSigned() || service.isSkipValidatingAuthnRequest();\n}","tryCatchPattern":"try {\n    response = idpController.handleRequest(request, response);\n} catch (SAMLException e) {\n    showSpConfigurationErrorPage(\"Sign your AuthnRequests or ask the IdP admin to relax the policy\");\n}","preventionTips":["Align the authnRequestsSigned flag in SP metadata with the SP's actual signing behavior.","Enable request signing on the SP (Shibboleth SP: signedRedirect/POST profile settings) when required.","Only set skipValidatingAuthnRequest=true as a deliberate, documented policy exception.","Test SP-initiated SSO after any SP metadata change."],"tags":["saml","signature","authn-request","sp","security"],"backgroundTag":"signature-verification-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}