From 6e86878e4702c5cbf89d448e1755072fd7e9da61 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Tue, 3 Sep 2024 15:21:35 +0200 Subject: [PATCH] [Fix] Fix application not starting in OIDC mode due to wrong WebSocket configuration. --- pom.xml | 2 +- .../termit/config/OAuth2SecurityConfig.java | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 62ee8fd44..ab4877fd8 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ 2.7.0 1.6.0 2.6.0 - 2.0.4 + 2.0.5 0.15.0 diff --git a/src/main/java/cz/cvut/kbss/termit/config/OAuth2SecurityConfig.java b/src/main/java/cz/cvut/kbss/termit/config/OAuth2SecurityConfig.java index cc5184416..ed5d66bde 100644 --- a/src/main/java/cz/cvut/kbss/termit/config/OAuth2SecurityConfig.java +++ b/src/main/java/cz/cvut/kbss/termit/config/OAuth2SecurityConfig.java @@ -19,27 +19,39 @@ import cz.cvut.kbss.termit.security.AuthenticationSuccess; import cz.cvut.kbss.termit.security.HierarchicalRoleBasedAuthorityMapper; +import cz.cvut.kbss.termit.security.JwtUtils; import cz.cvut.kbss.termit.security.SecurityConstants; +import cz.cvut.kbss.termit.security.WebSocketJwtAuthorizationInterceptor; +import cz.cvut.kbss.termit.service.security.TermItUserDetailsService; import cz.cvut.kbss.termit.util.oidc.OidcGrantedAuthoritiesExtractor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; import org.springframework.core.convert.converter.Converter; +import org.springframework.messaging.Message; +import org.springframework.messaging.simp.SimpMessageType; +import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +import org.springframework.util.AntPathMatcher; import org.springframework.web.cors.CorsConfigurationSource; import java.util.Collection; @@ -96,4 +108,35 @@ private Converter grantedAuthoritiesExtractor( new HierarchicalRoleBasedAuthorityMapper().mapAuthorities(authorities)); }; } + + /** + * Part of {@link EnableWebSocketSecurity @EnableWebSocketSecurity} replacement + * + * @see WebSocketConfig + */ + @Bean + @Scope("prototype") + public MessageMatcherDelegatingAuthorizationManager.Builder messageAuthorizationManagerBuilder( + ApplicationContext context) { + return MessageMatcherDelegatingAuthorizationManager.builder().simpDestPathMatcher( + () -> (context.getBeanNamesForType(SimpAnnotationMethodMessageHandler.class).length > 0) + ? context.getBean(SimpAnnotationMethodMessageHandler.class).getPathMatcher() + : new AntPathMatcher()); + } + + /** + * WebSocket endpoint authorization + */ + @Bean + public AuthorizationManager> messageAuthorizationManager( + MessageMatcherDelegatingAuthorizationManager.Builder messages) { + return messages.simpTypeMatchers(SimpMessageType.DISCONNECT).permitAll() + .anyMessage().authenticated().build(); + } + + @Bean + public WebSocketJwtAuthorizationInterceptor webSocketJwtAuthorizationInterceptor(JwtUtils jwtUtils, + TermItUserDetailsService userDetailsService) { + return new WebSocketJwtAuthorizationInterceptor(jwtUtils, userDetailsService); + } }