I used PreAuthorize annotation with SpEL to custom user auth validation.
From Springboot 3.2.0 SpEL argument keep passing null to validation method.
I think similar with these issues. but someone says this problem fixed from spring boot 3.2.3. Spring Boot 3.2.2 breaks SpEL interpretation spring-projects/spring-boot#39261 Parameter based cache keys on repository methods can't resolve after 6.1.2->6.1.3 spring-projects/spring-boot#32087 SpEL containing argument references not working in Spring Boot 3.2.0 spring-projects/spring-boot#38895 https://github.com/spring-projects/spring-framework/issues/32087#issuecomment-2021524617
So, I tried all 3.2 version from 3.2.0 to 3.2.4 but SpEL keeps passing null every single version. Of course it works from 3.1.10 and lower.
I wrote few codes to repeat this issue. Here is git link. https://github.com/HaniCera/SpEL-Passing-Null
@RestController
@RequestMapping("api")
@Slf4j
public class SpELPassingController {
@GetMapping("{uid}/v1")
//expects #uid parameter to be passed to PreAuthComponent.pass method
@PreAuthorize("@PreAuth.pass(#uid)")
public ResponseEntity<String> getV1(@PathVariable(name = "uid") String uid){
log.info("getV1 uid: {}", uid);
return ResponseEntity.ok("getV1 - " + uid);
}
}
@Component("PreAuth")
@Slf4j
public final class PreAuthComponent {
public boolean pass(String uid){
log.info("pass uid: {}", uid);
// null exception happens here
return !uid.isEmpty();
}
}
@EnableWebSecurity
@EnableMethodSecurity
@Configuration
public class SpELPassingSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(
conf -> conf.anyRequest().permitAll())
.build();
}
}
Am I missing something? or this way of access not available anymore?
Thanks.
Comment From: walklown
I cloned your demo library and tried it. Both PreAuthComponent and SpELPassingController obtained the uid parameter normally. And I tried switching to 3.2.0~3.2.4, but failed to reproduce the problem you mentioned.
Did I miss some information?
Hope it helps.
Comment From: mdeinum
Your code needs to be compiled with -parameters
to keep the parameter names, looking at your build.gradle
your code isn't. This is a change in Spring 6.1 with the removal of the fallback method to determine the names of the arguments.
This is also explained in the upgrade guide -> https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention
When that compiler option has been added it works.
❯ curl -X GET "http://localhost:8080/api/any-string/v1"
getV1 - any-string%
❯ curl -X GET "http://localhost:8080/api/any-string/v2"
getV2 - any-string%
Comment From: HaniCera
Your code needs to be compiled with
-parameters
to keep the parameter names, looking at yourbuild.gradle
your code isn't. This is a change in Spring 6.1 with the removal of the fallback method to determine the names of the arguments.This is also explained in the upgrade guide -> https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention
When that compiler option has been added it works.
shell ❯ curl -X GET "http://localhost:8080/api/any-string/v1" getV1 - any-string% ❯ curl -X GET "http://localhost:8080/api/any-string/v2" getV2 - any-string%
Thank you it works.