私は、フル機能のActiveMQブローカでWebSocket実装のSpringのSTOMPを使用しています。トピックへのユーザーSUBSCRIBE
の場合、正常に購読される前に通過しなければならないいくつかの許可ロジックがあります。以下に構成された私は、権限のロジックを適用するChannelInterceptorを使用しています:Spring WebSocketを使用してSTOMPクライアントにERRORメッセージを送信するには?
WebSocketConfig.java:
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/topic", "/queue")
.setRelayHost("relayhost.mydomain.com")
.setRelayPort(61613);
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new MySubscriptionInterceptor());
}
}
WebSocketSecurityConfig.java:
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpSubscribeDestMatchers("/stomp/**").authenticated()
.simpSubscribeDestMatchers("/user/queue/errors").authenticated()
.anyMessage().denyAll();
}
}
MySubscriptionInterceptor.java:
public class MySubscriptionInterceptor extends ChannelInterceptorAdapter {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor headerAccessor= StompHeaderAccessor.wrap(message);
Principal principal = headerAccessor.getUser();
if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
checkPermissions(principal);
}
return message;
}
private void checkPermissions(Principal principal) {
// apply permissions logic
// throw Exception permissions not sufficient
}
}
制限付きトピックの購読を試みるクライアントは、トピックからのメッセージを実際に受け取ることはありませんが、サブスクリプションを拒否した例外は通知されません。代わりに、クライアントは、ActiveMQブローカーが何も知らないデッドサブスクリプションを手渡されます。
正常に接続された後、私はusers/{subscribingUsername}/queue/errors
に登録して、users/queue/errors
をJavaテストクライアントでプレーングしてみましたが、これまでのところ、私はこれを持っていますクライアントに配信されたサーバーからのサブスクリプション例外に関するエラーメッセージの一種を取得できませんでした。アクセスが拒否されたことがクライアントに通知されることはないので、明らかに理想的ではありません。
おかげで、私はそれを与えました試してみる。残念ながら、 '@ SubscribeMapping'メソッドで例外がスローされ、' @ MessageExceptionHandler'メソッドで処理されると、メッセージISはクライアントのエラーキューに送られますが、サブスクリプションは依然としてブローカに転送され、クライアントは引き続きメッセージを受け取りますトピックから。 – hartz89
そのため、 '@ MessageExceptionHandler'から' clientOutboundChannel'に直接 'send'を使ってみてください。 –
@ArtemBilan OutboundChannelの入手方法を教えてください。質問をしました:http://stackoverflow.com/questions/39641477/send-stomp-error-from-spring-websocket-program –