You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Spring 5 WebSocket添加安全防护

Securing Your Spring 5 WebSocket Application

Great to hear your WebSocket app is running smoothly! Let's walk through how to add robust security to your setup, tailored to your existing GreetingController.

1. Add Spring Security Dependencies

First, make sure you've got the necessary dependencies in your build file to enable Spring Security for WebSockets:

For Maven (pom.xml):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-messaging</artifactId>
</dependency>

For Gradle (build.gradle):

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-messaging'

2. Configure WebSocket-Specific Security Rules

Create a configuration class to control access to your STOMP endpoints and message destinations:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
import org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer;

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages
            // Require authentication to send messages to /hello
            .simpDestMatchers("/hello").authenticated()
            // Restrict subscription to /topic/greetings to users with USER role
            .simpSubscribeDestMatchers("/topic/greetings").hasRole("USER")
            // All other STOMP traffic requires authentication
            .anyMessage().authenticated();
    }

    @Override
    protected boolean sameOriginDisabled() {
        // Disable same-origin check if you need to handle cross-origin requests
        return true;
    }
}

3. Set Up Core Authentication

Add a basic Spring Security configuration to handle user authentication (this example uses an in-memory user store—replace it with your actual user service later):

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .passwordEncoder(new BCryptPasswordEncoder())
            .withUser("user")
            .password(new BCryptPasswordEncoder().encode("password"))
            .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin() // Enable form-based login for testing
            .and()
            .csrf().ignoringAntMatchers("/ws/**"); // Skip CSRF checks for WebSocket endpoints if needed
    }
}

4. Add Method-Level Security to Your Controller

Enforce security directly on your controller methods using Spring Security annotations. First, enable method-level security:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}

Then update your GreetingController to restrict access to the greeting method:

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.web.util.HtmlUtils;

@Controller
public class GreetingController {

    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    @PreAuthorize("hasRole('USER')") // Only authenticated users with USER role can call this
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
    }
}

5. Access Authenticated User Details (Optional)

You can retrieve the authenticated user's details in your controller if needed:

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

// Inside your greeting method
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String currentUsername = auth.getName(); // Get the logged-in user's username

Key Notes

  • CSRF Protection: For browser clients, ensure you include the CSRF token in the WebSocket handshake request. Spring Security can auto-inject this into frontend templates.
  • Cross-Origin Requests: If your app handles cross-origin traffic, configure CORS in your WebSocket config and update security rules to allow trusted origins.
  • Production-Grade Authentication: Replace the in-memory user store with your actual user service (e.g., JPA, LDAP) or use OAuth2/JWT for token-based authentication.

Test your setup by logging in with the credentials you defined—unauthenticated users should be blocked from sending messages to /hello or subscribing to /topic/greetings.

内容的提问来源于stack exchange,提问作者gstackoverflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:30:23