diff --git a/samples/grpc-tomcat-secure/pom.xml b/samples/grpc-tomcat-secure/pom.xml index 1c70226..58b9dff 100644 --- a/samples/grpc-tomcat-secure/pom.xml +++ b/samples/grpc-tomcat-secure/pom.xml @@ -31,7 +31,7 @@ 17 0.0.39 3.25.5 - 1.63.2 + 1.69.0 diff --git a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequest.java b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequest.java index 6d903e2..c6bf41a 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequest.java +++ b/spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequest.java @@ -23,13 +23,12 @@ import java.util.function.Supplier; import java.util.stream.Stream; import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; -import org.springframework.context.ApplicationContext; +import org.springframework.grpc.server.service.GrpcServiceDiscoverer; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; -import io.grpc.BindableService; import jakarta.servlet.http.HttpServletRequest; /** @@ -43,10 +42,11 @@ public class GrpcServletRequest { /** * Returns a matcher that includes all gRPC services from the application context. The - * {@link GrpcServletRequestMatcher#excluding(Class...) excluding} method can be - * used to remove specific services by class if required. For example: + * {@link GrpcServletRequestMatcher#excluding(String...) excluding} method can be used + * to remove specific services by name if required. For example: + * *
-	 * GrpcServletRequest.all().excluding(MyCustomService.class)
+	 * GrpcServletRequest.all().excluding("my-service")
 	 * 
* @return the configured {@link RequestMatcher} */ @@ -57,9 +57,10 @@ public class GrpcServletRequest { /** * The request matcher used to match against resource locations. */ - public static final class GrpcServletRequestMatcher extends ApplicationContextRequestMatcher { + public static final class GrpcServletRequestMatcher + extends ApplicationContextRequestMatcher { - private final Set> exclusions; + private final Set exclusions; private volatile RequestMatcher delegate; @@ -67,8 +68,8 @@ public class GrpcServletRequest { this(new HashSet<>()); } - private GrpcServletRequestMatcher(Set> exclusions) { - super(ApplicationContext.class); + private GrpcServletRequestMatcher(Set exclusions) { + super(GrpcServiceDiscoverer.class); this.exclusions = exclusions; } @@ -78,44 +79,43 @@ public class GrpcServletRequest { * @param rest additional services to exclude * @return a new {@link GrpcServletRequestMatcher} */ - public GrpcServletRequestMatcher excluding(Class... rest) { + public GrpcServletRequestMatcher excluding(String... rest) { return excluding(Set.of(rest)); } /** * Return a new {@link GrpcServletRequestMatcher} based on this one but excluding * the specified services. - * @param exclusions additional services to exclude + * @param exclusions additional service names to exclude * @return a new {@link GrpcServletRequestMatcher} */ - public GrpcServletRequestMatcher excluding(Set> exclusions) { + public GrpcServletRequestMatcher excluding(Set exclusions) { Assert.notNull(exclusions, "Exclusions must not be null"); - Set> subset = new LinkedHashSet<>(this.exclusions); + Set subset = new LinkedHashSet<>(this.exclusions); subset.addAll(exclusions); return new GrpcServletRequestMatcher(subset); } @Override - protected void initialized(Supplier context) { + protected void initialized(Supplier context) { List matchers = getDelegateMatchers(context.get()).toList(); this.delegate = matchers.isEmpty() ? request -> false : new OrRequestMatcher(matchers); } - private Stream getDelegateMatchers(ApplicationContext context) { + private Stream getDelegateMatchers(GrpcServiceDiscoverer context) { return getPatterns(context).map(AntPathRequestMatcher::new); } - private Stream getPatterns(ApplicationContext context) { - return context.getBeanProvider(BindableService.class) + private Stream getPatterns(GrpcServiceDiscoverer context) { + return context.findServices() .stream() .filter(service -> !this.exclusions.stream() - .anyMatch(type -> type.isAssignableFrom(service.getClass()))) - .map(BindableService::bindService) + .anyMatch(type -> type.equals(service.getServiceDescriptor().getName()))) .map(service -> "/" + service.getServiceDescriptor().getName() + "/**"); } @Override - protected boolean matches(HttpServletRequest request, Supplier context) { + protected boolean matches(HttpServletRequest request, Supplier context) { return this.delegate.matches(request); } diff --git a/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequestTests.java b/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequestTests.java index b4bc49e..32532b9 100644 --- a/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequestTests.java +++ b/spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/server/security/GrpcServletRequestTests.java @@ -22,6 +22,8 @@ import static org.mockito.Mockito.when; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.grpc.autoconfigure.server.security.GrpcServletRequest.GrpcServletRequestMatcher; +import org.springframework.grpc.server.service.DefaultGrpcServiceDiscoverer; +import org.springframework.grpc.server.service.GrpcServiceDiscoverer; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.WebApplicationContext; @@ -40,6 +42,8 @@ public class GrpcServletRequestTests { ServerServiceDefinition serviceDefinition = ServerServiceDefinition.builder("my-service").build(); when(service.bindService()).thenReturn(serviceDefinition); this.context.registerBean(BindableService.class, () -> service); + this.context.registerBean(GrpcServiceDiscoverer.class, + () -> new DefaultGrpcServiceDiscoverer((input, info) -> input.bindService(), context)); } @Test @@ -58,7 +62,7 @@ public class GrpcServletRequestTests { @Test void requestMatcherExcludes() { - GrpcServletRequestMatcher matcher = GrpcServletRequest.all().excluding(MockService.class); + GrpcServletRequestMatcher matcher = GrpcServletRequest.all().excluding("my-service"); MockHttpServletRequest request = mockRequest("/my-service/Method"); assertThat(matcher.matches(request)).isFalse(); };