在 Spring MVC 4 应用程序中通过 websocket 连接发送的调用中,我可以java.security.Principal在将其添加为方法中的参数时获取一个对象。
但是,这基本上只有用户名,我需要UserDetails在登录期间创建的(扩展)对象。
SecurityContextHolder.getContext().getAuthentication()返回null。据我了解,因为 spring 创建了一个特殊的会话来处理 websocket 连接。
问题:有没有办法从 websocket 会话/线程内部访问安全上下文?
(能够访问会话 bean 就足够了)。
我正在尝试将 Spring Security 与 websockets 一起使用。作为示例,我正在使用“深入研究 websockets”演讲中的spring-websocket-chat ( https://github.com/salmar/spring-websocket-chat ) \xe2\x80\x94 演示应用程序。在该应用程序中,CookieHttpSessionStrategy 用于存储会话 ID,在身份验证期间存储的 Cookie 与 /info 请求一起发送。以下是演示通过 sockjs 连接到服务器的代码(此请求发送 cookie)https://github.com/salmar/spring-websocket-chat/blob/master/src/main/webapp/js/services.js。我编写了自己的客户端,使用 sockjs 和 stomp,但在 /info 请求期间没有发送 cookie。这是我的代码
\n\n$connectButton.click(function () {\n var serverHost = $host.val();\n console.log("sockjs created");\n stomp = Stomp.over(new SockJS(serverHost));\n console.log("stomp over");\n stomp.connect({},\n function () {\n console.log("connected");\n },\n function () {\n console.log("error");\n })\n console.log("pressed");\n});\nRun Code Online (Sandbox Code Playgroud)\n Spring WebSocket的最新版本可与SockJS和StompJS库配合使用。但我不喜欢在我的应用程序中使用主题。那么如何使用HTML5 WebSocket API 创建 Spring WebSocket 应用程序 并将我们的应用程序与Spring Security集成?
我有一个用于 Web 套接字的 Spring boot 应用程序。我没有使用 Stomp Web 套接字。有没有办法可以在微服务的多个实例之间共享 Web 套接字会话。
有没有办法在 Redis 或 cassandra 中保存 websocket 会话?
我的用例是,我的微服务的多个实例正在运行,它正在侦听 kafka 队列,因此当收到消息时,我需要使用 Web 套接字会话将其发送到客户端。我将会话保存在将微服务作为 MAP。我的问题是我的任何一个微服务正在获取消息,如果该微服务的会话不可用,则消息不会发送到客户端。
如果我能够将 websocket 会话保存在 REDIS 或 Cassandra 中,我就可以查询会话并将其发送到客户端。
我无法按照要求使用 Stomp Web 套接字,它必须是普通的 Web 套接字。
我将 spring security 与 Websocket 一起使用,我有以下方法,
@PreAuthorize("hasAuthority('ROLE_CREATE_USER')")
@MessageMapping("/cashDeposit")
public void cashDeposit(CashDepositRequest cashDepositRequest) {
Run Code Online (Sandbox Code Playgroud)
我有 websocket 安全配置。现在的问题是,当访问被拒绝时,它会抛出异常,
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
Run Code Online (Sandbox Code Playgroud)
我搜索了 Stackoverflow,发现大多数问题都与 Servlet(HTTPServletRequest/Response)相关,而不是与 Websocket 相关。
请让我知道如何处理 websocket 的 AccessDeniedException 以及如何向用户发送 403 禁止的 websocket 消息。
我的安全配置
@Configuration
public class WebSocketSecurityConfig extends
AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages.simpMessageDestMatchers("/topic/**").permitAll()
.anyMessage().authenticated();
}
@Override
protected boolean sameOriginDisabled() {
//disable CSRF for websockets for now...
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我的其余服务的安全配置,
@Override
protected void configure(HttpSecurity http) throws …Run Code Online (Sandbox Code Playgroud) 我正在开发Websocket Java客户端,但我总是无法连接到服务器。我很感激你帮助我。
错误信息
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: javax.websocket.DeploymentException: Connection to 'wss://localhost:8443/index' failed.
at com.lge.racss.test.WebsocketClientEndpoint.<init>(WebsocketClientEndpoint.java:88)
at com.lge.racss.test.Application.main(Application.java:16)
... 6 more
Caused by: javax.websocket.DeploymentException: Connection to 'wss://localhost:8443/index' failed.
at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket._connect(GrizzlyClientSocket.java:382)
at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket.access$000(GrizzlyClientSocket.java:103)
at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket$1.call(GrizzlyClientSocket.java:228)
at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket$1.call(GrizzlyClientSocket.java:224)
at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket.connect(GrizzlyClientSocket.java:242)
at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientContainer.openClientSocket(GrizzlyClientContainer.java:95)
at org.glassfish.tyrus.client.ClientManager$1$1.run(ClientManager.java:575)
at org.glassfish.tyrus.client.ClientManager$1.run(ClientManager.java:622)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:775)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:447)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:337)
at com.lge.racss.test.WebsocketClientEndpoint.<init>(WebsocketClientEndpoint.java:84)
... 7 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] …Run Code Online (Sandbox Code Playgroud) 我使用 Spring 4.3.5 和 WebSocket 以及 SockJS、STOMP 和 SimpleBrokerMessageHandler。
在我的应用程序中,我有三个单独的 WebSocket 端点在不同的地址上运行:/endPointA、/ednpointB、/endpointC 更具体地说,我有三个单独的配置类,并用 @Configuration @EnableWebSocketMessageBroker 注释进行注释。
我还有一个具有 @Autowired SimpMessagingTemplate 的类。
最后,我有三个客户端,每个客户端都连接到一个不同的端点。然而,所有这些都订阅了“相同”的频道地址,即/topic/messages
当我使用SimpMessagingTemplate向/topic/messages发送内容时,所有客户端都会收到此消息。
之后我有两个问题:
我做了一些调查(堆转储分析),发现对于我的配置,我有:
所以我想知道,在所有端点上的消息传播是否是 SimpleBrokerMessageHandler 或 SimpMessagingTemplate 的“功能”。
我有一个使用 ng2-stomp-service 的 Angular 2 应用程序。它与 Spring WebSocket 一起使用,但没有安全性。
但我无法将身份验证凭据发送到 Spring Security。这是 Spring Security 中的配置:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/demo-websocket/info").permitAll()
.antMatchers("/demo-websocket/**/websocket").permitAll()
.antMatchers("/info", "/health").permitAll()
.antMatchers("/info", "/health").permitAll()
.antMatchers("/api/**", "/advisor").hasRole("USER")
.anyRequest().authenticated();
}
}
Run Code Online (Sandbox Code Playgroud)
这是 Spring WebSocket 安全设置:
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry registry) {
registry
.simpTypeMatchers(CONNECT).permitAll()
.simpTypeMatchers(UNSUBSCRIBE, DISCONNECT).permitAll()
.simpMessageDestMatchers("/app/**").permitAll()
.simpSubscribeDestMatchers("/topic/**").permitAll()
.anyMessage().authenticated()
;
}
@Override
protected boolean sameOriginDisabled() {
//disable CSRF for …Run Code Online (Sandbox Code Playgroud) 目前,我正在尝试使用 webflux 将 STOMP 与 websockets 一起使用。为了向 STOMP 主题发送消息,我需要使用SimpMessagingTemplate,这是我添加时由 spring boot 自动配置提供的@EnableWebSocketMessageBroker
但问题是,@EnableWebSocketMessageBroker间接地希望我spring-mvc在类路径中有库
@EnableWebSocketMessageBroker @ImportsDelegatingWebSocketMessageBrokerConfiguration扩展WebSocketMessageBrokerConfigurationSupport&WebSocketMessageBrokerConfigurationSupport#stompWebSocketHandlerMapping方法期望HandlerMapping返回该类
我的问题是
我用教程创建了一个基本的网络套接字。
这是一个配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat");
registry.addEndpoint("/chat").withSockJS();
}
}
Run Code Online (Sandbox Code Playgroud)
这是消息处理控制器:
@MessageMapping("/chat")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
return new OutputMessage("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但根据我的调查,默认情况下 WebSockets 看起来有一个应用程序范围(通过连接到通道,我可以看到来自所有用户的所有调用)。
我想要做的是只能看到来自当前用户会话或当前视图的调用。关于如何应用这些配置的任何想法?
java websocket spring-boot spring-messaging spring-websocket
spring-websocket ×10
websocket ×6
java ×3
spring ×3
spring-boot ×3
stomp ×3
spring-mvc ×2
angular ×1
javascript ×1
sockjs ×1
spring-4 ×1
ssl ×1