开启 Spring Security 时创建 WebSocket 连接失败
Posted
技术标签:
【中文标题】开启 Spring Security 时创建 WebSocket 连接失败【英文标题】:Failed to create WebSocket connection when Spring Security is on 【发布时间】:2015-10-12 17:38:35 【问题描述】:我正在使用订阅基于 Spring-Boot 的服务器应用程序的 Java WebSocket 客户端。 一切正常,但是在添加了对 Spring Security 的支持以对用户进行身份验证和授权后,WebSocket Java 客户端停止工作。 我收到以下错误(POST 请求失败,出现 405 Not Allowed 错误)
19:56:49.813 [main] INFO o.s.s.c.ThreadPoolTaskScheduler -
Initializing ExecutorService 19:56:49.819 [main] DEBUG
StompWebSocketTestClient - Connecting and subscribing 1 users
19:56:49.886 [main] DEBUG o.s.w.s.s.c.RestTemplateXhrTransport -
Executing SockJS Info request, url=http:<//>localhost:9090/hello/info
19:56:49.923 [main] DEBUG o.s.web.client.RestTemplate - Created GET
request for "http:<//>localhost:9090/hello/info" 19:56:49.941 [main]
DEBUG o.s.web.client.RestTemplate - GET request for
"http:<//>localhost:9090/hello/info" resulted in 200 (OK) 19:56:49.974
[main] DEBUG o.s.w.s.s.client.WebSocketTransport - Starting WebSocket
session
url=ws:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/websocket
19:56:49.974 [main] DEBUG o.s.w.s.c.s.StandardWebSocketClient -
Connecting to
ws:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/websocket
19:56:50.120 [SimpleAsyncTaskExecutor-1] ERROR
o.s.w.s.s.c.DefaultTransportRequest -
TransportRequest[url=ws:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/websocket]
failed. Falling back on next transport.
javax.websocket.DeploymentException: The HTTP response from the server
[HTTP/1.1 200 OK ] did not permit the HTTP upgrade to WebSocket at
org.apache.tomcat.websocket.WsWebSocketContainer.parseStatus(WsWebSocketContainer.java:619)
~[tomcat-embed-websocket-8.0.15.jar:8.0.15] at
org.apache.tomcat.websocket.WsWebSocketContainer.processResponse(WsWebSocketContainer.java:603)
~[tomcat-embed-websocket-8.0.15.jar:8.0.15] at
org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:300)
~[tomcat-embed-websocket-8.0.15.jar:8.0.15] at
org.springframework.web.socket.client.standard.StandardWebSocketClient$1.call(StandardWebSocketClient.java:152)
~[spring-websocket-4.2.0.RC1.jar:4.2.0.RC1] at
org.springframework.web.socket.client.standard.StandardWebSocketClient$1.call(StandardWebSocketClient.java:149)
~[spring-websocket-4.2.0.RC1.jar:4.2.0.RC1] at
java.util.concurrent.FutureTask.run(FutureTask.java:266)
~[na:1.8.0_45] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
19:56:50.122 [SimpleAsyncTaskExecutor-1] DEBUG
o.s.w.s.s.c.RestTemplateXhrTransport - Starting XHR Streamingsession
url=http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr_streaming
19:56:50.128 [SimpleAsyncTaskExecutor-1] DEBUG
o.s.web.client.RestTemplate - Created POST request for
"http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr_streaming"
19:56:50.133 [SimpleAsyncTaskExecutor-1] WARN
o.s.web.client.RestTemplate - POST request for
"http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr_streaming"
resulted in 405 (Method Not Allowed); invoking error handler
19:56:50.139 [SimpleAsyncTaskExecutor-1] ERROR
o.s.w.s.s.c.DefaultTransportRequest -
TransportRequest[url=http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr_streaming]
failed. Falling back on next transport.
org.springframework.web.client.HttpClientErrorException: 405 Method
Not Allowed at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:615)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:573)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:544)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.socket.sockjs.client.RestTemplateXhrTransport$1.run(RestTemplateXhrTransport.java:128)
~[spring-websocket-4.2.0.RC1.jar:4.2.0.RC1] at
java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] 19:56:50.140
[SimpleAsyncTaskExecutor-1] DEBUG o.s.w.s.s.c.RestTemplateXhrTransport
- Starting XHR Streamingsession url=http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr
19:56:50.155 [SimpleAsyncTaskExecutor-2] DEBUG
o.s.web.client.RestTemplate - Created POST request for
"http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr"
19:56:50.163 [SimpleAsyncTaskExecutor-2] WARN
o.s.web.client.RestTemplate - POST request for
"http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr"
resulted in 405 (Method Not Allowed); invoking error handler
19:56:50.166 [SimpleAsyncTaskExecutor-2] ERROR
o.s.w.s.s.c.DefaultTransportRequest - No more fallback transports
after
TransportRequest[url=http:<//>localhost:9090/hello/912/d93d47eb2bdd4700a26c0e19e10a33df/xhr]
org.springframework.web.client.HttpClientErrorException: 405 Method
Not Allowed at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:615)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:573)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:544)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.socket.sockjs.client.RestTemplateXhrTransport$1.run(RestTemplateXhrTransport.java:128)
~[spring-websocket-4.2.0.RC1.jar:4.2.0.RC1] at
java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] 19:56:50.167
[SimpleAsyncTaskExecutor-2] DEBUG o.s.m.simp.stomp.DefaultStompSession
- Failed to connect session id=318180fa-47bc-5649-c136-db91a339837a org.springframework.web.client.HttpClientErrorException: 405 Method
Not Allowed at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:615)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:573)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:544)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.socket.sockjs.client.RestTemplateXhrTransport$1.run(RestTemplateXhrTransport.java:128)
~[spring-websocket-4.2.0.RC1.jar:4.2.0.RC1] at
java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] 19:56:50.170
[SimpleAsyncTaskExecutor-2] ERROR StompWebSocketTestClient - Transport
error org.springframework.web.client.HttpClientErrorException: 405
Method Not Allowed at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:615)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:573)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:544)
~[spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] at
org.springframework.web.socket.sockjs.client.RestTemplateXhrTransport$1.run(RestTemplateXhrTransport.java:128)
~[spring-websocket-4.2.0.RC1.jar:4.2.0.RC1] at
java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
这里是 Spring Security 配置文件:
@Override
protected void configure(HttpSecurity http) throws Exception
http.
csrf().disable().
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
and().
authorizeRequests().
//TODO: as a workaround for WS 401 error, tried but did not work: antMatchers("/hello").permitAll(). possible related to the StompClient URL which is ws://
antMatchers(actuatorEndpoints()).hasRole(backendAdminRole).
anyRequest().authenticated().
and().
anonymous().disable().
exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint());
http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class).
addFilterBefore(new ManagementEndpointAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
请注意我没有使用 WebClient,因此我的安全配置禁用了 Spring 的默认 Spring LoginForm
这里是 WebSocket 配置
@Override
public void configureMessageBroker(MessageBrokerRegistry config)
config.enableSimpleBroker("/topic/");
config.setApplicationDestinationPrefixes("/app");
@Override
public void registerStompEndpoints(StompEndpointRegistry registry)
registry.addEndpoint("/hello").withSockJS();
这里是 WebSocket 安全配置 (我尝试了很多配置 - 尝试了我在网络上找到的所有配置,但没有成功)
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages)
messages
// message types other than MESSAGE and SUBSCRIBE
.nullDestMatcher().authenticated()
// matches any destination that starts with /rooms/
.simpDestMatchers("/topic/**").authenticated()
// (i.e. cannot send messages directly to /topic/, /queue/)
// (i.e. cannot subscribe to /topic/messages/* to get messages sent to
// /topic/messages-user<id>)
.simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll()
// catch all
.anyMessage().denyAll();
/**
* Disables CSRF for Websockets.
*/
@Override
protected boolean sameOriginDisabled()
return true;
这是我的 Java 客户端
List<Transport> transports = new ArrayList<>(2);
StandardWebSocketClient standardWebSocketClient = new StandardWebSocketClient();
transports.add(new WebSocketTransport(standardWebSocketClient));
RestTemplateXhrTransport restTemplateXhrTransport = new RestTemplateXhrTransport();
//setting the authentication token
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("X-Auth-Token", token);
restTemplateXhrTransport.setRequestHeaders(httpHeaders);
transports.add(restTemplateXhrTransport);
SockJsClient sockJsClient = new SockJsClient(transports);
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.afterPropertiesSet();
String stompUrl = "ws://localhost:9090/hello";
stompClient.setMessageConverter(new StringMessageConverter());
stompClient.setTaskScheduler(taskScheduler);
stompClient.setDefaultHeartbeat(new long[] 10, 10);
WebSocketHttpHeaders headers = new WebSocketHttpHeaders(httpHeaders);
WebSocketSession webSocketSession;
logger.debug("Connecting and subscribing " + NUMBER_OF_USERS + " users ");
StopWatch stopWatch = new StopWatch("STOMP Broker Relay WebSocket Load Tests");
stopWatch.start();
List<ConsumerStompSessionHandler> consumers = new ArrayList<>();
for (int i=0; i < NUMBER_OF_USERS; i++)
consumers.add(new ConsumerStompSessionHandler(BROADCAST_MESSAGE_COUNT, connectLatch,
subscribeLatch, messageLatch, disconnectLatch, failure));
stompClient.connect(stompUrl, headers, consumers.get(i), host, port);
应用程序在 stompClient.connect() 行失败 在哪里: host 是 Web 应用程序服务器的地址(当然是 Spring 基础)——在我的例子中是“localhost”。 'port' 参数是 Web 应用程序服务器正在侦听的端口。 标头:包括“X-Auth-Token”标头
这是我正在使用的当前 pom.xml(嗯,自从我写这篇文章以来它发生了一些变化)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.9.RELEASE</version>
</parent>
<groupId>my-group</groupId>
<artifactId>my.id</artifactId>
<version>1.0.0</version>
<properties>
<org.springframework-version>4.1.3.RELEASE</org.springframework-version>
<app.version>1.0</app.version>
<spring-boot.version>1.1.3.RELEASE</spring-boot.version>
<!-- Generic properties -->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Logging
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>-->
<log4j.version>1.2.17</log4j.version>
<tomcat.version>8.0.8</tomcat.version>
<spring.version>4.1.0.RELEASE</spring.version>
<!-- Test -->
<junit.version>4.11</junit.version>
<springloaded.version>1.2.0.RELEASE</springloaded.version>
<spring-security.version>4.0.0.RC1</spring-security.version>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>$log4j.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>$org.springframework-version</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>$org.springframework-version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>$org.springframework-version</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>redis.embedded</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>$org.springframework-version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
<!-- PERSISTANCE -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1101-jdbc41</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- SECURITY -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>$spring-security.version</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
<version>$spring-security.version</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>$spring-security.version</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>$spring-security.version</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.3</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<!--ASPECT-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--CONVERTERS-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.0</version>
</dependency>
<!-- JODA Time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
<!-- LOMBOK -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.14.8</version>
</dependency>
<!-- JSON Support -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>0.8.1</version>
<scope>test</scope>
</dependency>
<!-- TESTING -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>$junit.version</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.0.M1</version>
</dependency>
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.4.1</version>
</dependency>
<!--JSON Doc-->
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>0.8.2</version>
</dependency>
<dependency>
<groupId>org.jsondoc</groupId>
<artifactId>spring-boot-starter-jsondoc</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.jsondoc</groupId>
<artifactId>jsondoc-ui-webjar</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>$springloaded.version</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptor>src/assembly/dep.xml</descriptor>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
<repository>
<id>closure</id>
<url>http://clojars.org/repo</url>
</repository>
<repository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
<repository>
<id>java-net</id>
<url>https://maven.java.net/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
提前感谢您的帮助
更新
我将以下 LoginController 作为我的项目控制器类的一部分。 /authenticate Controller 与 Spring Security 使用的 X-Auth 认证机制的 POST 方法有关。我发现一旦从项目中删除了这个控件 - HTTP 405 Not Allowed 错误就消失了。 我不得不承认我不知道原因。我只是使用试验和错误来尝试找到 405 错误的问题。 感谢有人可以帮助我了解可能是什么问题。 tnx
package com.iotiki.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
public class LoginController
@Autowired
private LoginBusinessLogic loginBusinessLogic;
@RequestMapping(value=ApiController.AUTHENTICATE_URL/*"/authenticate"*/,method= RequestMethod.POST)
public String login(@Valid @RequestBody LoginDTO loginDTO) throws UnAuthorizedException
return "this method should not be called, since Spring Security should take over";
@RequestMapping(method=RequestMethod.GET)
public LoginDTO getLoginDTO()
return new LoginDTO();
【问题讨论】:
请提供更多细节。您使用的是什么春季版本?另外,主机属性的价值是多少。它包含 /portfolio 吗? 我已经用项目的 pom.xml 文件更新了帖子(它有很多依赖项,因为我尝试了很多选项)。 'host' 值只是 'localhost',它不包括 /portforlio 它。基本上,我试图了解客户端在与服务器握手过程中尝试发出的 POST 请求是什么,服务器响应是 - 405 Not Allowed。 tnx 提前为您提供帮助 【参考方案1】:我遇到了确切的问题,我认为它也可能与您的问题有关。我的一个@RestController
s 在课堂上没有@RequestMapping("/myendpoint")
。
仅此一项就导致我的 websocket 出现405 method not allowed
错误。
我也想不出这种行为的原因,但“也许”控制器上没有 @RequestMapping 导致来自 websocket 的请求最终到达该控制器的端点,因为控制器默认只接受 POST 请求
你会得到405 method not allowed
。
我相信如果您为 @RequestMapping
s 指定了端点,特别是 GET 类型:
@RequestMapping(value = "/me/myendpoint" , method = RequestMethod.GET)
public LoginDTO getLoginDTO()
return new LoginDTO();
它会解决你的问题。
【讨论】:
【参考方案2】:问题在于 x-auth-token 方法通过允许 Spring Session 覆盖 HttpSession 实现(在 x-auth-token 标头中查找会话 ID 并在 Redis 中查找会话)来工作。然后 Spring Security 表现正常(即它尝试在 HttpSession 中查找当前用户)。
但是,您提供的配置(为清晰起见已重新格式化)
http
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).
.and()
.authorizeRequests()
告诉 Spring Security 不要咨询 HttpSession。所以解决方法是删除 sessionManagement 部分。
http
.csrf().disable()
.authorizeRequests()
【讨论】:
嗨,罗伯。 Tnx 为您解答。不幸的是,这不是问题。即使我删除了您指出的行,问题仍然存在。我最终所做的是将您的“spring-websocket-portfolio”项目示例,对其进行一些更改以用作 Spring boot webapp,然后开始将我的 POC 项目代码移入其中。我发现我在项目中定义的 LoginController(请参阅原始问题中的 LoginController)是导致 405 错误的问题。我不得不承认,我不知道为什么会出现问题。如果您能看一看,我将不胜感激。 tnx以上是关于开启 Spring Security 时创建 WebSocket 连接失败的主要内容,如果未能解决你的问题,请参考以下文章
spring-security 开启注解权限控制为什么没有效果
Spring Security(三十七):Part IV. Web Application Security
微服务:整合 Spring Boot Admin - 开启Security安全认证
将 spring-security 与 spring-webflux 一起使用时禁用 WebSession 创建
如何使用 Spring-Boot 播种 Spring-Security
使用spring security的spring boot:创建名为“securityFilterChainRegistration”的bean时出错