简体   繁体   English

尽管有CSRF令牌,但SPRING CSRF仍抛出405

[英]SPRING CSRF throws 405 despite CSRF token in request

I have a web application that works when I put <security:csrf disabled="true"/> in my security config, but doesn't work when I enable it. 我有一个Web应用程序,当我将<security:csrf disabled="true"/>放入我的安全配置时,它可以工作,但是当我启用它时,它不能工作。 I conclude therefore than I'm an idiot, but can't figure out why. 因此,我得出的结论是我不是白痴,但不知道为什么。

The symptoms are: 症状是:

  • Throws 405 when deployed in Tomcat with <security:csrf/> 使用<security:csrf/>部署在Tomcat中时抛出405
  • Works in Tomcat with <security:csrf disabled="true"/> 在Tomcat中使用<security:csrf disabled="true"/>
  • Works when run under STS's Pivotal server, even with <security:csrf/> 在STS的Pivotal服务器上运行时,即使在<security:csrf/>

The precise error is: 准确的错误是:

"POST /works-1.0-SNAPSHOT/auth/register HTTP/1.1" 405 1088

Here is my registration form: 这是我的注册表:

<%@ page import="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Register</title>
    </head>
    <body>

        <h1>Register</h1>
        <div class="error">${error}</div>
        <c:url var="post_url" value="/auth/register"/>
        <form action="${post_url}" method="post" >
      <p>
        <label for="j_username">Login:</label>
        <input id="j_username" name="j_username" type="text" value="${j_username}"/>
      </p>
      <p>
        <label for="j_displayname">Name:</label>
        <input id="j_displayname" name="j_displayname" type="text" value="${j_displayname}"/>
      </p>
      <p>
        <label for="j_password">Password:</label>
        <input id="j_password" name="j_password" type="password" />
      </p>
       <input type="hidden" name="${_csrf.parameterName}"
                        value="${_csrf.token}" />
      <input  type="submit" value="Register"/>
    </form>
    <br/>
    <a href="/auth/login">Login</a>
    </body>
</html>

(If you think that this form looks suspiciously like SDN4-cineasts 's one, you're right: my project is derived from that source code.) (如果您认为这种形式看起来像SDN4-cineasts的形式,那是对的:我的项目是从该源代码派生的。)

As you can see, the CSRF token is in there. 如您所见,CSRF令牌位于其中。 When I "show source" on the displayed web page, I can see that the token is indeed present. 当我在显示的网页上“显示源代码”时,我可以看到该令牌确实存在。 Any ideas? 有任何想法吗?

Here is my pom: 这是我的pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         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>

    <groupId>de.artdecode.works</groupId>
    <artifactId>works</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>Works database</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- <spring.version>4.2.4.RELEASE</spring.version> -->
        <spring.version>4.3.2.RELEASE</spring.version>
        <spring.commons.version>1.12.0.BUILD-SNAPSHOT</spring.commons.version>
        <!-- <spring.security.version>4.0.3.RELEASE</spring.security.version> -->
        <spring.security.version>4.1.3.RELEASE</spring.security.version>
        <!-- <neo4j.version>2.3.2</neo4j.version>  -->
        <neo4j.version>3.0.3</neo4j.version>
        <!-- <sdn.version>4.1.0.M1</sdn.version> -->
        <sdn.version>4.1.2.RELEASE</sdn.version>
        <neo4j.ogm.version>2.0.4</neo4j.ogm.version>
    </properties>

    <dependencies>
        <!-- J2EE -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>


       <!-- Spring -->

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</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.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
            <version>${sdn.version}</version>
        </dependency>

        <dependency>
            <groupId>opensymphony</groupId>
            <artifactId>sitemesh</artifactId>
            <version>2.4.2</version>
        </dependency>

        <!-- Neo4j -->
        <dependency>
            <groupId>org.neo4j.app</groupId>
            <artifactId>neo4j-server</artifactId>
            <version>${neo4j.version}</version>
        </dependency>
        <!-- 
        <dependency>
          <groupId>org.neo4j</groupId>
          <artifactId>neo4j-ogm-bolt-driver</artifactId>
          <version>2.0.4</version>
        </dependency>
        -->

        <!-- Tests -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-test</artifactId>
            <version>${neo4j.ogm.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.neo4j.test</groupId>
            <artifactId>neo4j-harness</artifactId>
            <version>${neo4j.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-library</artifactId>
            <version>1.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
            <version>${sdn.version}</version>
            <type>test-jar</type>
        </dependency>

        <!-- Others -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>

    </dependencies>


    <repositories>
        <repository>
            <id>spring-libs-snapshot</id>
            <name>Spring</name>
            <url>http://repo.spring.io/libs-snapshot</url>
        </repository>

        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </repository>

        <repository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </repository>

        <repository>
            <id>neo4j</id>
            <url>http://m2.neo4j.org/content/repositories/releases</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>

    </repositories>
    <pluginRepositories>

        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
        </pluginRepository>

        <pluginRepository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </pluginRepository>

</pluginRepositories>



    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>7.6.5.v20120716</version>
                <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                    <stopKey>foo</stopKey>
                    <stopPort>9999</stopPort>
                    <jvmArgs></jvmArgs>
                    <systemProperties>
                        <systemProperty>
                            <name>username</name>
                            <value>neo4j</value>
                        </systemProperty>
                        <systemProperty>
                            <name>password</name>
                            <value>neo</value>
                        </systemProperty>
                    </systemProperties>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Here is my web.xml: 这是我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext-security.xml
            /WEB-INF/applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
    </listener>
    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>
            com.opensymphony.module.sitemesh.filter.PageFilter
        </filter-class>
    </filter>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <session-config>
      <session-timeout>60</session-timeout>
    </session-config>
</web-app>

Here is my security configuration: 这是我的安全配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <context:annotation-config/>
    <security:global-method-security secured-annotations="enabled">
    </security:global-method-security>

    <security:http> <!-- use-expressions="true" -->
        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/import/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/user/**" access="hasRole('ROLE_USER')"/>
        <security:intercept-url pattern="/auth/login" access="isAnonymous()"/>
        <security:intercept-url pattern="/auth/register" access="isAnonymous()"/>
        <security:intercept-url pattern="/resources/**" access="permitAll"/>
        <security:intercept-url pattern="/images/**" access="permitAll"/>
        <security:intercept-url pattern="/**" access="isAnonymous() || hasRole('ROLE_USER')"/>
        <security:form-login login-page="/auth/login"
            authentication-failure-url="/auth/login?login_error=true"
            default-target-url="/user"
            login-processing-url="/j_spring_security_check"
            username-parameter="username"
            password-parameter="password"/>
        <security:logout logout-success-url="/" invalidate-session="true" logout-url="/j_spring_security_logout"/>
        <security:access-denied-handler error-page="/auth/denied" />
        <security:csrf/>
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userRepository">
            <security:password-encoder hash="md5">
                <security:salt-source system-wide="cewuiqwzie"/>
            </security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>

</beans>

Problem solved: I had cookies disabled in my browser. 解决的问题:我在浏览器中禁用了cookie。 It was not a problem with either Tomcat or my code, it was a problem with my browser. Tomcat或我的代码都没有问题,浏览器也有问题。

Could someone at Spring please make it possible to distinguish between "Invalid CSRF token found" and "Expected token is empty (probably cookie not set)"? Spring有人可以区分“发现无效的CSRF令牌”和“预期的令牌为空(可能未设置cookie)”吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM