Spring security 如何使用Spring Security在现有HTTP环境中验证WebSocket

Spring security 如何使用Spring Security在现有HTTP环境中验证WebSocket,spring-security,basic-authentication,spring-websocket,java-websocket,Spring Security,Basic Authentication,Spring Websocket,Java Websocket,我有一个非常简单的要求(我使用的是Spring Security 4.0.1),但我在web上找不到任何示例,除了本页上告诉我的: 将WebSocketHandler集成到其他应用程序中相对简单 HTTP服务环境的帮助 WebSocketHttpRequestHandler 我所拥有的:一个WebSocketHandler的实现,它完成了这项工作,并使用基本身份验证为环境提供HTTP服务。我的WebApplicationInitializer如下所示: public class MyWebApp

我有一个非常简单的要求(我使用的是Spring Security 4.0.1),但我在web上找不到任何示例,除了本页上告诉我的:

将WebSocketHandler集成到其他应用程序中相对简单 HTTP服务环境的帮助 WebSocketHttpRequestHandler

我所拥有的:一个
WebSocketHandler
的实现,它完成了这项工作,并使用基本身份验证为环境提供HTTP服务。我的
WebApplicationInitializer
如下所示:

public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        ...
        // WebSocket support - Handshake
        Dynamic ws = servletContext.addServlet("webSocketHttpRequestHandler", new HttpRequestHandlerServlet());
        ws.addMapping("/streaming/*");

        // Spring Security Filter
        FilterRegistration.Dynamic springSecurity = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
        springSecurity.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
    }
}
这就是我将websocket端点插入现有web应用程序的方式。 我的WebSocket配置类看起来(非常简化)如下:

StreamingWebSocketHandler
实现
WebSocketHandler

我还有一个RESTfulWeb服务(在同一台服务器中),它使用配置的基本身份验证

工作原理:我的RESTful Web服务可以与任何Web浏览器一起工作。我可以执行一些经过身份验证的查询(可以在HTTP头中发送凭据)。 WebSocket查询正在工作,在我第一次尝试执行某些操作时,会要求进行身份验证(在FireFox下,会出现一个弹出窗口,要求提供凭据,一旦我输入凭据,客户端和服务器就可以通过WebSocket消息进行通信)。 在我的
WebSocketHandler
中,Spring对象:
WebSocketSession
包含有关经过身份验证的用户的信息是正确的(
#getPrincipal()
方法返回一个
身份验证
,其中包含授予的权限、详细信息等……)。 注意,一旦websocket经过身份验证,我就可以重新启动查询,而无需重新输入它们

我想要什么:从用户的角度来看,这是不好的,因为需要两次凭据:

  • 首先是RESTful查询
  • 第二个用于WebSocket查询
  • 如果第一次身份验证成功,如何绕过第二次身份验证?是否有方法检测客户端已通过身份验证,而不要求提供凭据


    我不想要什么:我既不想使用nor也不想使用SockJs(我不需要支持旧的web浏览器)。

    我想我终于找到了答案,但我不能完全确定。一旦我已经通过了应用程序的身份验证,握手请求就不会出现“凭证弹出窗口”。通过查看握手请求参数/cookie(例如在FF开发工具中),可以推断cookie JSESSIONID必须存在于请求中。这可以通过执行适当的登录操作来实现(例如,我应该设置一个登录页面)。然后,web浏览器将在下一个请求(包括websocket握手)中使用该cookie。
    @Configuration
    public class WebSocketServicesConfig{
        @Bean
        public WebSocketHttpRequestHandler webSocketHttpRequestHandler() {
            return new WebSocketHttpRequestHandler(new StreamingWebSocketHandler());
        }
    }