spring-projects-experimental / spring-grpc

90 stars 19 forks source link

Support for security configuration #3

Open dsyer opened 2 months ago

CyberZujo commented 3 weeks ago

Hi @dsyer What would be the approach on this one? Should it be able to integrate spring-security through autoconfig and to have an interceptor for incoming requests on grpc server?

dsyer commented 3 weeks ago

If you wait for the interceptor support it will probably make it easier. I think the general idea is to create an interceptor that calls out to Spring Security. You can see the existing implementations at https://github.com/LogNet/grpc-spring-boot-starter and https://github.com/grpc-ecosystem/grpc-spring.

onobc commented 3 weeks ago

Until the interceptor support is officially added (should be in the next couple days), you can register a ServerBuilderCustomizer that adds the interceptor to the builder. Then when the interceptors are added we can go back and replace the customizer w/ an interceptor directly.

CyberZujo commented 2 weeks ago

Got a small example.

        @Bean
    public SecurityInterceptor securityInterceptor() {
        return new SecurityInterceptor();
    }

    @Bean
    public ServerBuilderCustomizer<?> securityInterceptorCustomizer(SecurityInterceptor securityInterceptor) {
        return new SecurityInterceptorCustomizer<>(securityInterceptor);
    }

     public class SecurityInterceptor implements ServerInterceptor {

      @Override
      public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, 
      ServerCallHandler<ReqT, RespT> next) {
        Context context = Context.current();
        System.out.println("Intercepted GRPC call");
        return Contexts.interceptCall(context, call, headers, next);
    }
}
image

@onobc What do you think? Good direction?

onobc commented 2 weeks ago

Hi @CyberZujo , the above does look like an empty interceptor impl that could be used to hook into security. Although, you can also use a @GlobalServerInterceptor annotation instead of the customizer.

The delicate work here will be figuring out exactly what/how we want to hook into Spring Security. From the examples given by @dsyer above, we can see both the gRPC ecosystem starter (here) and the Lognet starter (here) both have quite a bit of security components. My suggestion would be to first digest each of these and summarize what they do/not cover and from that we can decide which direction to go. Another option would be to just move the gRPC ecosystem security components directly in.

@dsyer wdyt?

dsyer commented 2 weeks ago

Definitely use @GlobalServerInterceptor because it's important to control the order. I'm also slightly wondering if we should implement something with the provided token-based authentication from grpc-java and leave out Spring Security completely unless someone asks for it.

onobc commented 2 weeks ago

I'm also slightly wondering if we should implement something with the provided token-based authentication from grpc-java and leave out Spring Security completely unless someone asks for it.

If the token-based auth is sufficient then going w/ a single simpler thing for v1 would be a great idea IMO.

CyberZujo commented 2 weeks ago

If you both agree, I would like this one assigned to me, for token-based auth approach. My approach would be:

I'll come back with some example of using JWT token.

dsyer commented 2 weeks ago

I think there should already be an interceptor that does this (and on the client). Check the grpc-java source code.

CyberZujo commented 1 week ago

@dsyer Yes, found it at: https://github.com/grpc-ecosystem/grpc-spring/blob/master/grpc-server-spring-boot-starter/src/main/java/net/devh/boot/grpc/server/security/interceptors/DefaultAuthenticatingServerInterceptor.java#L61

dsyer commented 1 week ago

That wasn't what I meant. Try starting here: https://github.com/grpc/grpc-java/blob/master/auth/ and https://github.com/grpc/grpc-java/blob/master/authz

CyberZujo commented 1 week ago

Got it, sorry. Will proceed with that approach.

dsyer commented 1 week ago

I also noticed that JWT is only supported through a sample (https://github.com/grpc/grpc-java/blob/master/examples/example-jwt-auth). Maybe a Spring Security interceptor wouldn't be such a bad idea? The JWT sample is probably a good starting point anyway.

benallard commented 1 week ago

Ideally, one would just add the spring-boot-starter-oauth2-resource-server starter, configure the issuer, and could start using the SecurityContextHolder. That is similar to the approach taken by the grpc-ecosystem starter.

dsyer commented 1 week ago

That could work. The dependency on spring-web and/or the servlet API might mess things up.

benallard commented 1 week ago

That's correct, the resource-server starter 's configuration classes are dependent on the Servlet web-application type. I usually copy the content of org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration in my project to have it working.