Browse Source

Add remaining methods from ExpressionUrlAuthorizationConfigurer to MessageMatcherDelegatingAuthorizationManager

- Added fullyAuthenticated
- Added rememberMe
- Added anonymous

Closes gh-11509
Evgeniy Cheban 3 years ago
parent
commit
5ecd513a57

+ 57 - 1
config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java

@@ -51,6 +51,8 @@ import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockServletConfig;
 import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.authentication.RememberMeAuthenticationToken;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.authorization.AuthorizationDecision;
 import org.springframework.security.authorization.AuthorizationManager;
@@ -58,6 +60,7 @@ import org.springframework.security.config.annotation.SecurityContextChangedList
 import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor;
 import org.springframework.security.messaging.access.intercept.MessageAuthorizationContext;
@@ -93,7 +96,7 @@ public class WebSocketMessageBrokerSecurityConfigurationTests {
 
 	AnnotationConfigWebApplicationContext context;
 
-	TestingAuthenticationToken messageUser;
+	Authentication messageUser;
 
 	CsrfToken token;
 
@@ -311,6 +314,56 @@ public class WebSocketMessageBrokerSecurityConfigurationTests {
 		assertThat(interceptors).contains(AuthorizationChannelInterceptor.class);
 	}
 
+	@Test
+	public void sendMessageWhenFullyAuthenticatedConfiguredAndRememberMeTokenThenAccessDeniedException() {
+		loadConfig(WebSocketSecurityConfig.class);
+		this.messageUser = new RememberMeAuthenticationToken("key", "user",
+				AuthorityUtils.createAuthorityList("ROLE_USER"));
+		assertThatExceptionOfType(MessageDeliveryException.class)
+				.isThrownBy(() -> clientInboundChannel().send(message("/fullyAuthenticated")))
+				.withCauseInstanceOf(AccessDeniedException.class);
+	}
+
+	@Test
+	public void sendMessageWhenFullyAuthenticatedConfiguredAndUserThenPasses() {
+		loadConfig(WebSocketSecurityConfig.class);
+		clientInboundChannel().send(message("/fullyAuthenticated"));
+	}
+
+	@Test
+	public void sendMessageWhenRememberMeConfiguredAndNoUserThenAccessDeniedException() {
+		loadConfig(WebSocketSecurityConfig.class);
+		this.messageUser = null;
+		assertThatExceptionOfType(MessageDeliveryException.class)
+				.isThrownBy(() -> clientInboundChannel().send(message("/rememberMe")))
+				.withCauseInstanceOf(AccessDeniedException.class);
+	}
+
+	@Test
+	public void sendMessageWhenRememberMeConfiguredAndRememberMeTokenThenPasses() {
+		loadConfig(WebSocketSecurityConfig.class);
+		this.messageUser = new RememberMeAuthenticationToken("key", "user",
+				AuthorityUtils.createAuthorityList("ROLE_USER"));
+		clientInboundChannel().send(message("/rememberMe"));
+	}
+
+	@Test
+	public void sendMessageWhenAnonymousConfiguredAndAnonymousUserThenPasses() {
+		loadConfig(WebSocketSecurityConfig.class);
+		this.messageUser = new AnonymousAuthenticationToken("key", "user",
+				AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
+		clientInboundChannel().send(message("/anonymous"));
+	}
+
+	@Test
+	public void sendMessageWhenAnonymousConfiguredAndLoggedInUserThenAccessDeniedException() {
+		loadConfig(WebSocketSecurityConfig.class);
+		assertThatExceptionOfType(MessageDeliveryException.class)
+				.isThrownBy(() -> clientInboundChannel().send(message("/anonymous")))
+				.withCauseInstanceOf(AccessDeniedException.class);
+
+	}
+
 	private void assertHandshake(HttpServletRequest request) {
 		TestHandshakeHandler handshakeHandler = this.context.getBean(TestHandshakeHandler.class);
 		assertThat(handshakeHandler.attributes.get(CsrfToken.class.getName())).isSameAs(this.token);
@@ -708,6 +761,9 @@ public class WebSocketMessageBrokerSecurityConfigurationTests {
 			messages
 				.simpDestMatchers("/permitAll/**").permitAll()
 				.simpDestMatchers("/authenticated/**").authenticated()
+				.simpDestMatchers("/fullyAuthenticated/**").fullyAuthenticated()
+				.simpDestMatchers("/rememberMe/**").rememberMe()
+				.simpDestMatchers("/anonymous/**").anonymous()
 				.anyMessage().denyAll();
 			// @formatter:on
 			return messages.build();

+ 28 - 0
messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java

@@ -332,6 +332,34 @@ public final class MessageMatcherDelegatingAuthorizationManager implements Autho
 				return access(AuthenticatedAuthorizationManager.authenticated());
 			}
 
+			/**
+			 * Specify that Messages are allowed by users who have authenticated and were
+			 * not "remembered".
+			 * @return the {@link Builder} for further customization
+			 * @since 5.8
+			 */
+			public Builder fullyAuthenticated() {
+				return access(AuthenticatedAuthorizationManager.fullyAuthenticated());
+			}
+
+			/**
+			 * Specify that Messages are allowed by users that have been remembered.
+			 * @return the {@link Builder} for further customization
+			 * @since 5.8
+			 */
+			public Builder rememberMe() {
+				return access(AuthenticatedAuthorizationManager.rememberMe());
+			}
+
+			/**
+			 * Specify that Messages are allowed by anonymous users.
+			 * @return the {@link Builder} for further customization
+			 * @since 5.8
+			 */
+			public Builder anonymous() {
+				return access(AuthenticatedAuthorizationManager.anonymous());
+			}
+
 			/**
 			 * Allows specifying that Messages are secured by an arbitrary expression
 			 * @param authorizationManager the {@link AuthorizationManager} to secure the