MST

星途 面试题库

面试题:Java之Spring Boot中WebSocket应用 - 跨域与安全机制

在Spring Boot的WebSocket应用部署到生产环境时,面临跨域问题以及安全威胁(如DDoS攻击、恶意连接等)。请详细说明如何解决跨域问题,并设计一套全面的安全机制来保障WebSocket服务的稳定运行,要求结合Spring Security等相关技术进行阐述。
45.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

解决跨域问题

  1. 使用@CrossOrigin注解: 在WebSocket配置类中,给@Configuration类添加@CrossOrigin注解,例如:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.bind.annotation.CrossOrigin;

@Configuration
@EnableWebSocketMessageBroker
@CrossOrigin(origins = "*")
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.setApplicationDestinationPrefixes("/app");
        config.enableSimpleBroker("/topic", "/queue");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-endpoint").withSockJS();
    }
}

@CrossOrigin(origins = "*")允许所有来源跨域访问,生产环境中建议指定具体的域名。

  1. 使用WebMvcConfigurer配置跨域: 创建一个配置类实现WebMvcConfigurer接口,重写addCorsMappings方法。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/websocket-endpoint/**")
              .allowedOrigins("http://allowed-origin.com")
              .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
              .allowedHeaders("*")
              .allowCredentials(true)
              .maxAge(3600);
    }
}

这种方式可以对不同的路径进行更细粒度的跨域配置。

安全机制设计

  1. Spring Security 配置
    • 依赖引入:在pom.xml中添加Spring Security依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  • 配置类:创建一个Spring Security配置类。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
           .csrf().disable()
           .authorizeRequests()
               .antMatchers("/websocket-endpoint/**").authenticated()
               .anyRequest().permitAll()
               .and()
           .httpBasic();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user =
            User.withDefaultPasswordEncoder()
               .username("user")
               .password("password")
               .roles("USER")
               .build();

        return new InMemoryUserDetailsManager(user);
    }
}
  • 上述配置中,csrf().disable()禁用了CSRF保护(对于WebSocket可能需要禁用,根据实际情况调整),antMatchers("/websocket-endpoint/**").authenticated()要求访问WebSocket端点必须经过认证,httpBasic()启用了HTTP基本认证。
  1. 防范DDoS攻击
    • 限制连接速率:可以使用Guava库的RateLimiter来限制每秒内允许的连接数。
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class RateLimitedWebSocketHandler extends TextWebSocketHandler {

    private final RateLimiter rateLimiter = RateLimiter.create(10); // 每秒允许10个连接

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        if (rateLimiter.tryAcquire()) {
            super.afterConnectionEstablished(session);
        } else {
            session.close();
        }
    }
}
  • 使用防火墙:在生产环境中,配置防火墙规则,限制来自恶意IP的连接。例如,使用云服务提供商提供的防火墙服务,或者配置Linux系统的iptables规则。
  1. 防范恶意连接

    • 身份验证和授权:通过Spring Security进行用户身份验证和授权,只有合法用户才能建立WebSocket连接。
    • 校验请求来源:在WebSocket配置或处理逻辑中,校验请求的来源是否合法,防止非法来源的连接。例如,可以检查请求头中的Origin字段是否在允许的列表中。
  2. 安全传输

    • 使用SSL/TLS:配置Spring Boot应用使用SSL/TLS证书,确保WebSocket通信在加密通道上进行。可以在application.properties中配置SSL相关属性:
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=password
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat
  • 这样所有的WebSocket通信都会通过HTTPS进行,提高数据传输的安全性。