JAVA-29331 Upgrade spring-security-web-sockets (#15468)

Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
timis1 2023-12-24 15:06:05 +02:00 committed by GitHub
parent 3838bab244
commit 37bddcdfce
14 changed files with 70 additions and 89 deletions

View File

@ -11,9 +11,9 @@
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-spring-5</artifactId> <artifactId>parent-spring-6</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-spring-5</relativePath> <relativePath>../../parent-spring-6</relativePath>
</parent> </parent>
<dependencies> <dependencies>
@ -73,6 +73,16 @@
<artifactId>hibernate-core</artifactId> <artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version> <version>${hibernate-core.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.expressly</groupId>
<artifactId>expressly</artifactId>
<version>${expressly.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
@ -92,7 +102,7 @@
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId> <artifactId>spring-security-messaging</artifactId>
<version>${spring-security.version}</version> <version>${spring-security-messaging.version}</version>
</dependency> </dependency>
<!-- Logging --> <!-- Logging -->
<dependency> <dependency>
@ -107,24 +117,9 @@
</dependency> </dependency>
<!-- Servlet --> <!-- Servlet -->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>jakarta.platform</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>jakarta.jakartaee-api</artifactId>
<version>${javax.servlet-api.version}</version> <version>${jakartaee-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>${jstl-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${javax.servlet.jsp-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency> </dependency>
<!-- Jackson Dependencies --> <!-- Jackson Dependencies -->
<dependency> <dependency>
@ -144,17 +139,11 @@
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-test</artifactId>
<version>${spring-boot-starter-test.version}</version> <version>${spring.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -194,11 +183,15 @@
</build> </build>
<properties> <properties>
<hibernate-core.version>5.2.10.Final</hibernate-core.version> <spring-security.version>6.1.5</spring-security.version>
<spring-data-jpa.version>1.11.3.RELEASE</spring-data-jpa.version> <spring-security-messaging.version>6.0.2</spring-security-messaging.version>
<spring-boot-starter-test.version>1.5.10.RELEASE</spring-boot-starter-test.version> <hibernate-core.version>6.1.7.Final</hibernate-core.version>
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
<expressly.version>5.0.0</expressly.version>
<spring-data-jpa.version>3.1.0</spring-data-jpa.version>
<spring-boot-starter-test.version>3.1.0</spring-boot-starter-test.version>
<jakartaee-api.version>10.0.0</jakartaee-api.version>
<cargo-maven2-plugin.version>1.7.6</cargo-maven2-plugin.version> <cargo-maven2-plugin.version>1.7.6</cargo-maven2-plugin.version>
<jaxb-api.version>2.3.1</jaxb-api.version>
</properties> </properties>
</project> </project>

View File

@ -9,7 +9,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver; import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver; import org.springframework.web.servlet.view.UrlBasedViewResolver;
@ -20,8 +20,9 @@ import java.sql.SQLException;
@EnableJpaRepositories @EnableJpaRepositories
@ComponentScan("com.baeldung.springsecuredsockets") @ComponentScan("com.baeldung.springsecuredsockets")
@Import({ SecurityConfig.class, DataStoreConfig.class, SocketBrokerConfig.class, SocketSecurityConfig.class }) @Import({ SecurityConfig.class, DataStoreConfig.class, SocketBrokerConfig.class, SocketSecurityConfig.class })
public class AppConfig extends WebMvcConfigurerAdapter { public class AppConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) { public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index"); registry.addViewController("/").setViewName("index");
registry.addViewController("/login").setViewName("login"); registry.addViewController("/login").setViewName("login");

View File

@ -13,7 +13,7 @@ import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory; import jakarta.persistence.EntityManagerFactory;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.Properties; import java.util.Properties;

View File

@ -6,11 +6,14 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@ -86,43 +89,30 @@ public class SecurityConfig {
*/ */
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests() http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.antMatchers("/", "/index", "/authenticate") authorizationManagerRequestMatcherRegistry
.permitAll() .requestMatchers("/", "/index", "/authenticate").permitAll()
.antMatchers("/secured/**/**", "/secured/**/**/**", "/secured/socket", "/secured/success") .requestMatchers("/secured/**/**", "/secured/**/**/**", "/secured/socket", "/secured/success").authenticated()
.authenticated() .anyRequest().authenticated())
.anyRequest() .formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer.loginPage("/login").permitAll()
.authenticated() .usernameParameter("username")
.and() .passwordParameter("password")
.formLogin() .loginProcessingUrl("/authenticate")
.loginPage("/login") .successHandler(loginSuccessHandler())
.permitAll() .failureUrl("/denied").permitAll())
.usernameParameter("username") .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutSuccessHandler(logoutSuccessHandler()))
.passwordParameter("password")
.loginProcessingUrl("/authenticate")
.successHandler(loginSuccessHandler())
.failureUrl("/denied")
.permitAll()
.and()
.logout()
.logoutSuccessHandler(logoutSuccessHandler())
.and()
/** /**
* Applies to User Roles - not to login failures or unauthenticated access attempts. * Applies to User Roles - not to login failures or unauthenticated access attempts.
*/ */
.exceptionHandling() .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> httpSecurityExceptionHandlingConfigurer.accessDeniedHandler(accessDeniedHandler()))
.accessDeniedHandler(accessDeniedHandler())
.and()
.authenticationProvider(authenticationProvider()); .authenticationProvider(authenticationProvider());
/** Disabled for local testing */ /** Disabled for local testing */
http.csrf() http.csrf(AbstractHttpConfigurer::disable);
.disable();
/** This is solely required to support H2 console viewing in Spring MVC with Spring Security */ /** This is solely required to support H2 console viewing in Spring MVC with Spring Security */
http.headers() http.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.frameOptions() .authorizeHttpRequests(Customizer.withDefaults());
.disable();
return http.build(); return http.build();
} }
@ -135,8 +125,7 @@ public class SecurityConfig {
@Bean @Bean
public WebSecurityCustomizer webSecurityCustomizer() { public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring() return (web) -> web.ignoring().requestMatchers("/resources/**");
.antMatchers("/resources/**");
} }
} }

View File

@ -8,14 +8,14 @@ import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_SPECIFIC_
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration @Configuration
@EnableWebSocketMessageBroker @EnableWebSocketMessageBroker
@ComponentScan("com.baeldung.springsecuredsockets.controllers") @ComponentScan("com.baeldung.springsecuredsockets.controllers")
public class SocketBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer { public class SocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
@Override @Override
public void configureMessageBroker(MessageBrokerRegistry config) { public void configureMessageBroker(MessageBrokerRegistry config) {

View File

@ -4,9 +4,9 @@ import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext; import jakarta.servlet.ServletContext;
import javax.servlet.ServletException; import jakarta.servlet.ServletException;
import javax.servlet.ServletRegistration; import jakarta.servlet.ServletRegistration;
public class WebAppInitializer implements WebApplicationInitializer { public class WebAppInitializer implements WebApplicationInitializer {

View File

@ -5,7 +5,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@Controller @Controller
public class CsrfTokenController { public class CsrfTokenController {

View File

@ -30,8 +30,7 @@ public class SocketController {
@MessageMapping(SECURED_CHAT) @MessageMapping(SECURED_CHAT)
@SendTo(SECURED_CHAT_HISTORY) @SendTo(SECURED_CHAT_HISTORY)
public OutputMessage sendAll(Message msg) throws Exception { public OutputMessage sendAll(Message msg) throws Exception {
OutputMessage out = new OutputMessage(msg.getFrom(), msg.getText(), new SimpleDateFormat("HH:mm").format(new Date())); return new OutputMessage(msg.getFrom(), msg.getText(), new SimpleDateFormat("HH:mm").format(new Date()));
return out;
} }
/** /**

View File

@ -1,6 +1,6 @@
package com.baeldung.springsecuredsockets.domain; package com.baeldung.springsecuredsockets.domain;
import javax.persistence.*; import jakarta.persistence.*;
import java.util.Set; import java.util.Set;
@Entity @Entity

View File

@ -1,12 +1,12 @@
package com.baeldung.springsecuredsockets.domain; package com.baeldung.springsecuredsockets.domain;
import javax.persistence.*; import jakarta.persistence.*;
import java.util.Set; import java.util.Set;
//Custom User Model //Custom User Model
@Entity @Entity
@Table(name = "user") @Table(name = "users")
public class User { public class User {
@Id @Id

View File

@ -4,9 +4,9 @@ import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.ServletException; import jakarta.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
/** /**

View File

@ -7,8 +7,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler { public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler {

View File

@ -5,15 +5,14 @@ import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import javax.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler { public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
@Override @Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException { throws IOException {
response.setStatus(HttpStatus.OK.value()); response.setStatus(HttpStatus.OK.value());
response.sendRedirect(request.getContextPath() + "/index"); response.sendRedirect(request.getContextPath() + "/index");

View File

@ -17,7 +17,7 @@ import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@Service() @Service
public class CustomUserDetailsService implements UserDetailsService { public class CustomUserDetailsService implements UserDetailsService {
Logger log = LoggerFactory.getLogger(CustomUserDetailsService.class); Logger log = LoggerFactory.getLogger(CustomUserDetailsService.class);