parent
							
								
									16272f634c
								
							
						
					
					
						commit
						8b9fe13c88
					
				|  | @ -208,6 +208,78 @@ This will ensure that: | |||
| <5> Any other message of type MESSAGE or SUBSCRIBE is rejected. Due to 6 we do not need this step, but it illustrates how one can match on specific message types. | ||||
| <6> Any other Message is rejected. This is a good idea to ensure that you do not miss any messages. | ||||
| 
 | ||||
| [[migrating-spel-expressions]] | ||||
| === Migrating SpEL Expressions | ||||
| 
 | ||||
| If you are migrating from an older version of Spring Security, your destination matchers may include SpEL expressions. | ||||
| It's recommended that these be changed to using concrete implementations of `AuthorizationManager` since this is independently testable. | ||||
| 
 | ||||
| However, to ease migration, you can also use a class like the following: | ||||
| 
 | ||||
| [source,java] | ||||
| ---- | ||||
| public final class MessageExpressionAuthorizationManager implements AuthorizationManager<MessageAuthorizationContext<?>> { | ||||
| 
 | ||||
| 	private SecurityExpressionHandler<Message<?>> expressionHandler = new DefaultMessageSecurityExpressionHandler(); | ||||
| 
 | ||||
| 	private Expression expression; | ||||
| 
 | ||||
| 	public MessageExpressionAuthorizationManager(String expressionString) { | ||||
| 		Assert.hasText(expressionString, "expressionString cannot be empty"); | ||||
| 		this.expression = this.expressionHandler.getExpressionParser().parseExpression(expressionString); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationDecision check(Supplier<Authentication> authentication, MessageAuthorizationContext<?> context) { | ||||
| 		EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication, context.getMessage()); | ||||
| 		boolean granted = ExpressionUtils.evaluateAsBoolean(this.expression, ctx); | ||||
| 		return new ExpressionAuthorizationDecision(granted, this.expression); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| ---- | ||||
| 
 | ||||
| And specify an instance for each matcher that you cannot get migrate: | ||||
| 
 | ||||
| [tabs] | ||||
| ====== | ||||
| Java:: | ||||
| + | ||||
| [source,java,role="primary"] | ||||
| ---- | ||||
| @Configuration | ||||
| public class WebSocketSecurityConfig { | ||||
| 
 | ||||
|     @Bean | ||||
|     public AuthorizationManager<Message<?>> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { | ||||
|         messages | ||||
|                 // ... | ||||
|                 .simpSubscribeDestMatchers("/topic/friends/{friend}").access(new MessageExpressionAuthorizationManager("#friends == 'john")); | ||||
|                 // ... | ||||
| 
 | ||||
|         return messages.build(); | ||||
|     } | ||||
| } | ||||
| ---- | ||||
| 
 | ||||
| Kotlin:: | ||||
| + | ||||
| [source,kotlin,role="secondary"] | ||||
| ---- | ||||
| @Configuration | ||||
| open class WebSocketSecurityConfig { | ||||
|     fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager<Message<?> { | ||||
|         messages | ||||
|             // .. | ||||
|             .simpSubscribeDestMatchers("/topic/friends/{friends}").access(MessageExpressionAuthorizationManager("#friends == 'john")) | ||||
|             // ... | ||||
| 
 | ||||
|         return messages.build() | ||||
|     } | ||||
| } | ||||
| ---- | ||||
| ====== | ||||
| 
 | ||||
| [[websocket-authorization-notes]] | ||||
| === WebSocket Authorization Notes | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue