Bonjour,
J'avais une appli spring boot 2.7.6 avec spring security 5.7.5 qui tournait sans problème : l'authentification fonctionne, je navigue dans les différentes pages en fonction des rôles, swagger ui est utilisable, etc.
Je n'ai pas de warning de déprecaded pour info
J'ai fait la migration vers spring boot 3.0.0 et donc spring security 6.0.0. J'ai suivi les guides de migration et le serveur démarre sans erreur. Mais mes URL ne fonctionnent plus : 401
Problème n° 1 : GET http://localhost:8080/swagger-ui/index.html entraine un 401
Dans les logs j'ai un
DEBUG org.springframework.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
Problème n° 2 : Je ne peux plus m'authentifier
L'authentification se fait en 2 temps
- POST http://localhost:8080/api/v1/auth/login ==> 200
- GET http://localhost:8080/api/v1/auth/me ==> 401
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@RestController
@RequestMapping(path = "/api/v1/auth", produces = MediaType.APPLICATION_JSON_VALUE)
public class AuthenticationController {
...
@PostMapping("/login")
public ResponseEntity<UserDto> login(@NotNull @Valid @RequestBody LoginDto loginDto) {
final Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginDto.getLogin(), loginDto.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
return ResponseEntity.ok(this.userDtoMapper.modelToDto((UserEntity) authentication.getPrincipal()));
}
@GetMapping("/me")
public ResponseEntity<UserDto> getAuthenticatedUser() throws NotFoundException {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (null == authentication || !authentication.isAuthenticated() || !(authentication.getPrincipal() instanceof UserEntity)) {
throw new SessionAuthenticationException("UNAUTHORIZED");
}
return ResponseEntity.ok(this.userDtoMapper.modelToDto(this.userService.findById(((UserEntity) authentication.getPrincipal()).getId())));
} |
pom.xml + SecurityConfig + WebMvcConfig
pom.xml :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
...
<properties>
<java.version>17</java.version>
<jjwt.version>0.11.5</jjwt.version>
<springdoc.version>1.6.0</springdoc.version>
<docx4j.version>11.3.2</docx4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>${docx4j.version}</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
<version>${docx4j.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api-parent</artifactId>
<version>3.0.1</version>
<type>pom</type>
</dependency>
</dependencies>
...
</project> |
SecurityConfig :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
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.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig {
@Autowired
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.getDefaultUserDetailsService();
}
// @Override
// public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
// authenticationManagerBuilder.userDetailsService(this.userDetailsService)
// .passwordEncoder(passwordEncoder());
// }
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
http.headers().frameOptions().disable().and()
.cors().and()
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)).and()
.formLogin().disable()
.authorizeHttpRequests(authz -> authz.requestMatchers("/api/*/auth/**").permitAll()
.requestMatchers("/api/*/public/**").permitAll()
.requestMatchers("/api/*/catalogs/*/documents/*/file").permitAll()
.requestMatchers(req -> req.getRequestURI()
.contains("swagger-ui")).permitAll()
.anyRequest().authenticated());
// @formatter:on
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()
.requestMatchers(req -> req.getRequestURI()
.contains("mail-images"))
.requestMatchers(req -> req.getRequestURI()
.contains("api-docs"))
// .requestMatchers(req -> req.getRequestURI()
// .contains("swagger-ui"))
.requestMatchers(req -> req.getRequestURI()
.contains("h2-console"));
}
} |
WebMvcConfig :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Value("#{'${cors.allowedOrigins}'.split(',')}")
private List<String> allowedOrigins;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedOriginPatterns("http://*", "https://*")
.allowedOrigins(this.allowedOrigins.toArray(String[]::new))
.allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(), HttpMethod.PATCH.name(), HttpMethod.DELETE.name(), HttpMethod.OPTIONS.name());
}
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {"classpath:/static/"};
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
} |
Auriez vous une piste de recherche parce que je sèche après plusieurs tentatives ?
Partager