打开Spring Security时无法创建WebSocket连接

时间:2015-07-22 17:26:39

标签: java spring security websocket

我使用Java WebSocket客户端订阅基于Spring-Boot的服务器应用程序。 一切都运行得很好,但在添加对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 base) - 在我的例子中是'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作为项目Controller类的一部分。 / 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();
    }
}

2 个答案:

答案 0 :(得分:0)

问题在于x-auth-token方法的工作原理是允许Spring Session覆盖HttpSession实现(查看会话ID的x-auth-token标头并在Redis中查找会话)。然后Spring Security正常运行(即它尝试在HttpSession中查找当前用户)。

但是,您提供的配置(为清晰起见重新格式化)

http
   .csrf().disable()
   .sessionManagement()
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS).
       .and()
   .authorizeRequests()

告诉Spring Security不要咨询HttpSession。所以解决方法是删除sessionManagement部分。

http
   .csrf().disable()
   .authorizeRequests()

答案 1 :(得分:0)

我有确切的问题,我认为这也可能与您的问题有关。我的@RestController中有一个在班上没有@RequestMapping("/myendpoint")。 仅此一项就给我的Websocket造成了405 method not allowed错误。

我也无法弄清楚这种行为的原因,但是“也许”控制器上缺少@RequestMapping导致来自websocket的请求最终在该控制器的端点上结束,因为控制器默认情况下仅接受POST请求 您会得到405 method not allowed

我相信您是否已为@RequestMapping的端点指定了GET类型:

@RequestMapping(value = "/me/myendpoint" , method = RequestMethod.GET)
public LoginDTO getLoginDTO(){
    return new LoginDTO();
}

它将解决您的问题。