From cf059644991f12a4b03706029e4c8c3ae29674e6 Mon Sep 17 00:00:00 2001 From: Guirong Hu Date: Wed, 8 Dec 2021 16:34:36 +0800 Subject: [PATCH 1/2] Add principal resolution in RSocket handler methods See gh-28444 --- .../spring-boot-autoconfigure/build.gradle | 1 + .../RSocketSecurityAutoConfiguration.java | 17 +++++++++++++- ...RSocketSecurityAutoConfigurationTests.java | 23 ++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 456481a5ac8..c5cfa8171cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -198,6 +198,7 @@ dependencies { optional("org.springframework.security:spring-security-oauth2-jose") optional("org.springframework.security:spring-security-oauth2-resource-server") optional("org.springframework.security:spring-security-rsocket") + optional("org.springframework.security:spring-security-messaging") optional("org.springframework.security:spring-security-saml2-service-provider") optional("org.springframework.security:spring-security-web") optional("org.springframework.session:spring-session-core") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java index 69235ed362c..06d20db59d8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,12 @@ package org.springframework.boot.autoconfigure.security.rsocket; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.rsocket.RSocketMessageHandlerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.rsocket.EnableRSocketSecurity; +import org.springframework.security.messaging.handler.invocation.reactive.AuthenticationPrincipalArgumentResolver; import org.springframework.security.rsocket.core.SecuritySocketAcceptorInterceptor; /** @@ -30,6 +32,7 @@ import org.springframework.security.rsocket.core.SecuritySocketAcceptorIntercept * * @author Madhura Bhave * @author Brian Clozel + * @author Guirong Hu * @since 2.2.0 */ @Configuration(proxyBeanMethods = false) @@ -42,4 +45,16 @@ public class RSocketSecurityAutoConfiguration { return (server) -> server.interceptors((registry) -> registry.forSocketAcceptor(interceptor)); } + @ConditionalOnClass(AuthenticationPrincipalArgumentResolver.class) + @Configuration(proxyBeanMethods = false) + static class RSocketSecurityMessageHandlerConfiguration { + + @Bean + RSocketMessageHandlerCustomizer springSecurityRSocketMessageHandler() { + return (messageHandler) -> messageHandler.getArgumentResolverConfigurer() + .addCustomResolver(new AuthenticationPrincipalArgumentResolver()); + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java index 8b6f2411dc2..f4ea2bdc823 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,23 @@ package org.springframework.boot.autoconfigure.security.rsocket; +import java.util.List; + import io.rsocket.core.RSocketServer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.rsocket.RSocketMessageHandlerCustomizer; import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.messaging.handler.invocation.reactive.HandlerMethodArgumentResolver; +import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler; import org.springframework.security.config.annotation.rsocket.RSocketSecurity; +import org.springframework.security.messaging.handler.invocation.reactive.AuthenticationPrincipalArgumentResolver; import org.springframework.security.rsocket.core.SecuritySocketAcceptorInterceptor; import static org.assertj.core.api.Assertions.assertThat; @@ -69,4 +75,19 @@ class RSocketSecurityAutoConfigurationTests { }); } + @Test + void autoConfigurationAddsCustomizerForMessageHandlerRSocketFactory() { + RSocketMessageHandler handler = new RSocketMessageHandler(); + this.contextRunner.run((context) -> { + RSocketMessageHandlerCustomizer customizer = context.getBean(RSocketMessageHandlerCustomizer.class); + customizer.customize(handler); + + List customResolvers = handler.getArgumentResolverConfigurer() + .getCustomResolvers(); + assertThat(customResolvers).isNotEmpty(); + assertThat(customResolvers) + .anyMatch((customResolver) -> customResolver instanceof AuthenticationPrincipalArgumentResolver); + }); + } + } From c943ef18ca42d89b7e19ff6187b8f0d736f6e635 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 4 Jan 2022 14:49:13 +0100 Subject: [PATCH 2/2] Polish "Add principal resolution in RSocket handler methods" See gh-28444 --- .../spring-boot-autoconfigure/build.gradle | 2 +- .../RSocketSecurityAutoConfiguration.java | 2 +- .../RSocketSecurityAutoConfigurationTests.java | 17 ++++------------- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index c5cfa8171cf..feb44e09ffd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -194,11 +194,11 @@ dependencies { optional("org.springframework.security:spring-security-data") { exclude group: "javax.xml.bind", module: "jaxb-api" } + optional("org.springframework.security:spring-security-messaging") optional("org.springframework.security:spring-security-oauth2-client") optional("org.springframework.security:spring-security-oauth2-jose") optional("org.springframework.security:spring-security-oauth2-resource-server") optional("org.springframework.security:spring-security-rsocket") - optional("org.springframework.security:spring-security-messaging") optional("org.springframework.security:spring-security-saml2-service-provider") optional("org.springframework.security:spring-security-web") optional("org.springframework.session:spring-session-core") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java index 06d20db59d8..108223ba497 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java @@ -50,7 +50,7 @@ public class RSocketSecurityAutoConfiguration { static class RSocketSecurityMessageHandlerConfiguration { @Bean - RSocketMessageHandlerCustomizer springSecurityRSocketMessageHandler() { + RSocketMessageHandlerCustomizer rSocketAuthenticationPrincipalMessageHandlerCustomizer() { return (messageHandler) -> messageHandler.getArgumentResolverConfigurer() .addCustomResolver(new AuthenticationPrincipalArgumentResolver()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java index f4ea2bdc823..c86748bc1fd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java @@ -16,20 +16,16 @@ package org.springframework.boot.autoconfigure.security.rsocket; -import java.util.List; - import io.rsocket.core.RSocketServer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessageHandlerCustomizer; import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.messaging.handler.invocation.reactive.HandlerMethodArgumentResolver; import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler; import org.springframework.security.config.annotation.rsocket.RSocketSecurity; import org.springframework.security.messaging.handler.invocation.reactive.AuthenticationPrincipalArgumentResolver; @@ -76,16 +72,11 @@ class RSocketSecurityAutoConfigurationTests { } @Test - void autoConfigurationAddsCustomizerForMessageHandlerRSocketFactory() { - RSocketMessageHandler handler = new RSocketMessageHandler(); + void autoConfigurationAddsCustomizerForAuthenticationPrincipalArgumentResolver() { this.contextRunner.run((context) -> { - RSocketMessageHandlerCustomizer customizer = context.getBean(RSocketMessageHandlerCustomizer.class); - customizer.customize(handler); - - List customResolvers = handler.getArgumentResolverConfigurer() - .getCustomResolvers(); - assertThat(customResolvers).isNotEmpty(); - assertThat(customResolvers) + assertThat(context).hasSingleBean(RSocketMessageHandler.class); + RSocketMessageHandler handler = context.getBean(RSocketMessageHandler.class); + assertThat(handler.getArgumentResolverConfigurer().getCustomResolvers()).isNotEmpty() .anyMatch((customResolver) -> customResolver instanceof AuthenticationPrincipalArgumentResolver); }); }