Skip to content

Commit 7873ab8

Browse files
committed
Merge branch '6.2.x' into 6.3.x
2 parents 1f7dcc0 + 348f064 commit 7873ab8

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

docs/modules/ROOT/pages/servlet/integrations/websocket.adoc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,78 @@ This will ensure that:
205205
<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.
206206
<6> Any other Message is rejected. This is a good idea to ensure that you do not miss any messages.
207207

208+
[[migrating-spel-expressions]]
209+
=== Migrating SpEL Expressions
210+
211+
If you are migrating from an older version of Spring Security, your destination matchers may include SpEL expressions.
212+
It's recommended that these be changed to using concrete implementations of `AuthorizationManager` since this is independently testable.
213+
214+
However, to ease migration, you can also use a class like the following:
215+
216+
[source,java]
217+
----
218+
public final class MessageExpressionAuthorizationManager implements AuthorizationManager<MessageAuthorizationContext<?>> {
219+
220+
private SecurityExpressionHandler<Message<?>> expressionHandler = new DefaultMessageSecurityExpressionHandler();
221+
222+
private Expression expression;
223+
224+
public MessageExpressionAuthorizationManager(String expressionString) {
225+
Assert.hasText(expressionString, "expressionString cannot be empty");
226+
this.expression = this.expressionHandler.getExpressionParser().parseExpression(expressionString);
227+
}
228+
229+
@Override
230+
public AuthorizationDecision check(Supplier<Authentication> authentication, MessageAuthorizationContext<?> context) {
231+
EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication, context.getMessage());
232+
boolean granted = ExpressionUtils.evaluateAsBoolean(this.expression, ctx);
233+
return new ExpressionAuthorizationDecision(granted, this.expression);
234+
}
235+
236+
}
237+
----
238+
239+
And specify an instance for each matcher that you cannot get migrate:
240+
241+
[tabs]
242+
======
243+
Java::
244+
+
245+
[source,java,role="primary"]
246+
----
247+
@Configuration
248+
public class WebSocketSecurityConfig {
249+
250+
@Bean
251+
public AuthorizationManager<Message<?>> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) {
252+
messages
253+
// ...
254+
.simpSubscribeDestMatchers("/topic/friends/{friend}").access(new MessageExpressionAuthorizationManager("#friends == 'john"));
255+
// ...
256+
257+
return messages.build();
258+
}
259+
}
260+
----
261+
262+
Kotlin::
263+
+
264+
[source,kotlin,role="secondary"]
265+
----
266+
@Configuration
267+
open class WebSocketSecurityConfig {
268+
fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager<Message<?> {
269+
messages
270+
// ..
271+
.simpSubscribeDestMatchers("/topic/friends/{friends}").access(MessageExpressionAuthorizationManager("#friends == 'john"))
272+
// ...
273+
274+
return messages.build()
275+
}
276+
}
277+
----
278+
======
279+
208280
[[websocket-authorization-notes]]
209281
=== WebSocket Authorization Notes
210282

0 commit comments

Comments
 (0)