Fix GrpcDisableCsrfHttpConfigurer logic and add metadata

Fix the `GrpcDisableCsrfHttpConfigurer` logic so that the property
`spring.grpc.server.security.csrf.enabled` is used correctly.

Also add missing metadata.

Fixes gh-50145
This commit is contained in:
Phillip Webb
2026-04-21 19:58:39 -07:00
parent 58c316c1d4
commit 752be34e1c
3 changed files with 28 additions and 6 deletions
@@ -50,7 +50,7 @@ class GrpcDisableCsrfHttpConfigurer extends AbstractHttpConfigurer<GrpcDisableCs
public void init(HttpSecurity http) {
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
if (context != null && isCsrfConfigurerPresent(http) && hasBean(context, GrpcServiceDiscoverer.class)
&& hasBean(context, GrpcServletRegistration.class) && isCsrfEnabled(context)) {
&& hasBean(context, GrpcServletRegistration.class) && !isCsrfEnabled(context)) {
http.csrf(this::disable);
}
}
@@ -65,7 +65,7 @@ class GrpcDisableCsrfHttpConfigurer extends AbstractHttpConfigurer<GrpcDisableCs
}
private boolean isCsrfEnabled(ApplicationContext context) {
return context.getEnvironment().getProperty("spring.grpc.server.security.csrf.enabled", Boolean.class, true);
return context.getEnvironment().getProperty("spring.grpc.server.security.csrf.enabled", Boolean.class, false);
}
private void disable(CsrfConfigurer<HttpSecurity> csrf) {
@@ -24,6 +24,13 @@
"type": "java.lang.Boolean",
"description": "Whether to enable Reflection on the gRPC server.",
"defaultValue": true
},
{
"name": "spring.grpc.server.security.csrf.enabled",
"type": "java.lang.Boolean",
"description": "Whether to enable CSRF protection.",
"defaultValue": false
}
]
}
@@ -112,7 +112,21 @@ class GrpcDisableCsrfHttpConfigurerTests {
}
@Test
void initWhenEnabledPropertyFalseDoesNothing() {
void initWhenEnabledPropertyTrueDoesNothing() {
ObjectPostProcessor<Object> objectPostProcessor = ObjectPostProcessor.identity();
AuthenticationManagerBuilder authenticationBuilder = new AuthenticationManagerBuilder(objectPostProcessor);
HttpSecurity http = new HttpSecurity(objectPostProcessor, authenticationBuilder, new HashMap<>());
StaticApplicationContext applicationContext = addApplicationContext(http);
TestPropertyValues.of("spring.grpc.server.security.csrf.enabled=true").applyTo(applicationContext);
addServiceDiscoverer(applicationContext);
addGrpcServletRegistration(applicationContext);
CsrfConfigurer<?> csrf = addCsrf(http);
this.configurer.init(http);
then(csrf).should(never()).requireCsrfProtectionMatcher(any());
}
@Test
void initWhenEnabledPropertyFalseDisablesCsrf() {
ObjectPostProcessor<Object> objectPostProcessor = ObjectPostProcessor.identity();
AuthenticationManagerBuilder authenticationBuilder = new AuthenticationManagerBuilder(objectPostProcessor);
HttpSecurity http = new HttpSecurity(objectPostProcessor, authenticationBuilder, new HashMap<>());
@@ -122,16 +136,17 @@ class GrpcDisableCsrfHttpConfigurerTests {
addGrpcServletRegistration(applicationContext);
CsrfConfigurer<?> csrf = addCsrf(http);
this.configurer.init(http);
then(csrf).should(never()).requireCsrfProtectionMatcher(any());
ArgumentCaptor<RequestMatcher> matcher = ArgumentCaptor.captor();
then(csrf).should().requireCsrfProtectionMatcher(matcher.capture());
assertThat(matcher.getValue()).isSameAs(GrpcCsrfRequestMatcher.INSTANCE);
}
@Test
void initWhenEnabledPropertyTrueDisablesCsrf() {
void initWhenEnabledPropertyMissingDisablesCsrf() {
ObjectPostProcessor<Object> objectPostProcessor = ObjectPostProcessor.identity();
AuthenticationManagerBuilder authenticationBuilder = new AuthenticationManagerBuilder(objectPostProcessor);
HttpSecurity http = new HttpSecurity(objectPostProcessor, authenticationBuilder, new HashMap<>());
StaticApplicationContext applicationContext = addApplicationContext(http);
TestPropertyValues.of("spring.grpc.server.security.csrf.enabled=true").applyTo(applicationContext);
addServiceDiscoverer(applicationContext);
addGrpcServletRegistration(applicationContext);
CsrfConfigurer<?> csrf = addCsrf(http);