Search code examples
spring-securityspring-webfluxspring-elpre-authentication

Spring Boot Webflux @PrePreAuthorize with SpEL keep passing null value


Spring boot 3.2.2 + Webflux Security

I tried to build custom @PreAuthorize via ReactiveMethodSecurity.

This code check user's authorization about "space"

@Component(value = "SpaceAccess")
@RequiredArgsConstructor
@Slf4j
public class SpaceAccessValidation {

    public final Mono<Boolean> readable(String spaceId){
        log.info("spaceId: {}", spaceId);
        Mono<Boolean> access = AuthUtils.getMemberDetailsMono()
                .map(memberDetails -> memberDetails.spaces()
                        .stream()
                        .anyMatch(o -> StringUtils.equals(o.id(), spaceId) && o.role().readable))
                .switchIfEmpty(AuthUtils.getAccessId()
                        .flatMap(accessId -> compareSpaceMemberRoleLevel(spaceId, accessId, SpaceRoleType.VIEWER))
                );
        return Mono.zip(access, spaceExist(spaceId), (a, b) -> a && b);
    }
}

AuthUtils just bring principal from ReactiveSecurityContextHolder.

The matter is when this method has been executed by RestController passed parameter spaceId is null.

@RestController
@RequestMapping("search/spaces/{spaceId}")
public class SearchRestController {


    @GetMapping("memos")
    @PreAuthorize("@SpaceAccess.readable(#spaceId)")
    @ResponseStatus(HttpStatus.OK)
    public Mono<PagingResultRecord> findMemos(@PathVariable(name = "spaceId") String spaceId){

        //call method
    }
}

When I call this api SpEL #spaceId keep passing null value.

I think #spaceId is correct expression. do you have any idea?

I've checked several questions from stackoverflow and SpEL expression document. but everywhere said when I pass the parameter dynamically #variable is correct one.


Solution

  • Self Answer:

    Spring method security SpEL annotations always give 401 after upgrading Spring-boot to 3.2.2

    It is bug from Spring Framework.

    but today I tried spring boot 3.2.4. This bug still exists.

    Spring boot 3.1.10 works.