grpc-spring-boot-starter
grpc-spring-boot-starter copied to clipboard
PreAuthorize expression not finding bean reference
I'm receiving this error Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1057E: No bean resolver registered in the context to resolve access to bean 'securityService'
when trying to access an existing bean inside a @PreAuthorize
annotation. I've used this pattern before on REST controllers. Using hasRole
works as expected, so I think I have my security setup correctly. I'm curious if this is a known issue or limitation. I'm using Spring Boot 2.7.3 and Java 17.
UPDATE: Here is a sample project that demonstrates this https://github.com/pcalouche/grpc-starter
Thanks for hard work on this library.
// Example bean used in PreAuthorize expression
public class SecurityService {
public boolean allow(AuthenticatedPrincipal principal) {
// more complex stuff could be here
return true;
}
public boolean block(AuthenticatedPrincipal principal) {
// more complex stuff could be here
return false;
}
}
// Security configuration
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Bean // registered bean
public SecurityService securityService() {
return new SecurityService();
}
@Bean
public InMemoryUserDetailsManager userDetailsService() {
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
UserDetails user =
User.withUsername("user")
.password(passwordEncoder.encode("password"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
@GRpcService
@Slf4j
public class GreetingService extends GreetingServiceGrpc.GreetingServiceImplBase {
@PreAuthorize("@securityService.allow(#principal)") // does not work
// @PreAuthorize("hasRole('ADMIN')") // works as expected
public void sayHello(GreetingRequest request, StreamObserver<GreetingResponse> responseObserver) {
GreetingResponse reply =
GreetingResponse.newBuilder().setMessage("Acknowledging " + request.getMessage()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
@RestController
@RequestMapping("test")
public class TestController {
@PreAuthorize("@securityService.block(#principal)") // works as expected
// @PreAuthorize("hasRole('ADMIN')") // works as expected
@GetMapping
public String hello() {
return "Hello";
}
}
syntax = "proto3";
package net.energyhub.example.grpc.protos;
option java_multiple_files = true;
option java_package = "net.energyhub.example.grpc.protos";
service GreetingService {
rpc sayHello(GreetingRequest) returns (GreetingResponse){}
}
message GreetingRequest {
string message = 1;
}
message GreetingResponse {
string message = 1;
}
I don't see you inherit GrpcSecurityConfigurerAdapter
and configuring GrpcSecurity
I had this at one point, but it didn't make a difference from what I could tell. Basic auth with something like @PreAuthorize("hasRole('ADMIN')")
works fine with out this two, which I find confusing.
I would not doubt I'm missing something else here. I can work on getting the entire project posted in a public repo. It's in a private work repo at the moment.
@Configuration
public class CustomGrpcSecurityConfigurerAdapter extends GrpcSecurityConfigurerAdapter {
@Override
public void configure(GrpcSecurity builder) throws Exception {
builder.authorizeRequests().anyMethod();
}
}
I'll try to reproduce it in this repo
Btw. I updated the original post with a sample repo that demonstrates this. This is the repo https://github.com/pcalouche/grpc-starter.
404
My apologies. It should be public now.
Thanks, @pcalouche , I'll be able to have a look after 14/10 (vacation )
Please try with 4.9.1-SNAPSHOT
I've also added test that uses current Authentication
object to make access decision.
@jvmlet The changes in 4.9.1-SNAPSHOT
worked for me. Thank you so much for addressing this issue.
4.9.1
was released