{"record":{"id":"f9d5ad7b43340290","repo":"spring-projects/spring-security","slug":"an-authentication-object-was-not-found-in-the-secu","errorCode":null,"errorMessage":"An Authentication object was not found in the SecurityContext","messagePattern":"An Authentication object was not found in the SecurityContext","errorType":"exception","errorClass":"AuthenticationCredentialsNotFoundException","httpStatus":null,"severity":"error","filePath":"messaging/src/main/java/org/springframework/security/messaging/access/intercept/AuthorizationChannelInterceptor.java","lineNumber":103,"sourceCode":"\tpublic void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {\n\t\tthis.authentication = getAuthentication(securityContextHolderStrategy);\n\t}\n\n\t/**\n\t * Use this {@link AuthorizationEventPublisher} to publish the\n\t * {@link AuthorizationManager} result.\n\t * @param eventPublisher\n\t */\n\tpublic void setAuthorizationEventPublisher(AuthorizationEventPublisher eventPublisher) {\n\t\tAssert.notNull(eventPublisher, \"eventPublisher cannot be null\");\n\t\tthis.eventPublisher = eventPublisher;\n\t}\n\n\tprivate Supplier<Authentication> getAuthentication(SecurityContextHolderStrategy strategy) {\n\t\treturn () -> {\n\t\t\tAuthentication authentication = strategy.getContext().getAuthentication();\n\t\t\tif (authentication == null) {\n\t\t\t\tthrow new AuthenticationCredentialsNotFoundException(\n\t\t\t\t\t\t\"An Authentication object was not found in the SecurityContext\");\n\t\t\t}\n\t\t\treturn authentication;\n\t\t};\n\t}\n\n\tprivate static class NoopAuthorizationEventPublisher implements AuthorizationEventPublisher {\n\n\t\t@Override\n\t\tpublic <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,\n\t\t\t\t@Nullable AuthorizationResult result) {\n\n\t\t}\n\n\t}\n\n}\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/messaging/src/main/java/org/springframework/security/messaging/access/intercept/AuthorizationChannelInterceptor.java#L85-L121","documentation":"AuthorizationChannelInterceptor.getAuthentication() builds the authentication Supplier lazily. If the SecurityContextHolderStrategy's context contains no Authentication object when a message send is being authorized, it throws AuthenticationCredentialsNotFoundException('An Authentication object was not found in the SecurityContext').","triggerScenarios":"A STOMP message arrives for authorization while SecurityContextHolder.getContext().getAuthentication() returns null — e.g. an unauthenticated CONNECT, authentication not propagated to the channel thread, or setSecurityContextHolderStrategy called with a strategy whose context has no auth.","commonSituations":"WebSocket CONNECT not secured (no spring-security-messaging integration on the inbound channel), so no user is bound before sends; anonymous authentication disabled so unauthenticated sessions carry null; client sends messages before CONNECT completes.","solutions":["Secure the STOMP CONNECT so authentication is established (enableInbound + authentication on the connect message, e.g. with an AuthenticationInterceptor or CSRF-token session binding).","Enable anonymous authentication (AnonymousAuthenticationFilter / setAnonymousAuthentication) so unauthenticated channels carry a non-null Authentication.","Ensure SecurityContext is propagated to the message-handling thread (use the channel interceptors provided by spring-security-messaging).","Client-side: always complete CONNECT/auth handshake before sending messages to protected destinations."],"exampleFix":"// before: anonymous disabled -> null authentication on channel thread\nhttp.anonymous().disable();\n// after: allow anonymous principal for messaging authorization\nhttp.anonymous().principal(\"guest\").authorities(\"ROLE_ANONYMOUS\");","handlingStrategy":"type-guard","validationCode":"Authentication auth = SecurityContextHolder.getContext().getAuthentication();\nif (auth == null) {\n    throw new MessagingException(\"Authenticate via CONNECT before sending messages\");\n}","typeGuard":"boolean isAuthenticated() {\n    Authentication a = SecurityContextHolder.getContext().getAuthentication();\n    return a != null && a.isAuthenticated() && !(a instanceof AnonymousAuthenticationToken);\n}","tryCatchPattern":"try {\n    channel.send(message);\n} catch (MessageDeliveryException e)\n    if (e.getCause() instanceof AuthenticationCredentialsNotFoundException) {\n        // session not authenticated; redirect client to CONNECT/login\n    }\n}","preventionTips":["Secure the STOMP CONNECT so an Authentication exists on the channel thread.","Enable anonymous authentication if unauthenticated sends are legitimate.","Have clients wait for CONNECT receipt before sending to protected destinations.","Propagate SecurityContext to async/channel threads via spring-security-messaging interceptors."],"tags":["websocket","stomp","authentication","spring-security","security-context"],"backgroundTag":"authentication-required","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}