【问题标题】:CSRF token not found未找到 CSRF 令牌
【发布时间】:2015-11-22 13:05:12
【问题描述】:

我正在关注关于 spring 安全性的教程,到目前为止我有以下内容: 当我尝试从我的登录页面登录时出现以下错误:

HTTP 状态 403 - 未找到预期的 CSRF 令牌。您的会话是否已过期?

我在 stackoverflow 上找到的解决方案表明要在表单中添加一个隐藏属性,我做到了。这是属性:

<input type="hidden" name="${_csrf.parameterName}" value="{_csrf.token}"/>

尽管我的代码似乎与 Udemy 教程完全匹配,但我已多次重新检查代码,但始终收到相同的 403 错误。

提前致谢。

我的 login.jsp 页面:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>

<html>

    <head>

        <title>Please login</title>
    </head>

    <body>

    <c:url value="/login" var="loginProcessingUrl"/>
 <form action="${loginProcessingUrl}" method="post">

    <fieldset>
        <legend>Please Login</legend>
        <!-- use param.error assuming FormLoginConfigurer#failureUrl contains the query parameter error -->
        <c:if test="${param.error != null}">
            <div>
                Failed to login.
                <c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
                  Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
                </c:if>
            </div>
        </c:if>
        <!-- the configured LogoutConfigurer#logoutSuccessUrl is /login?logout and contains the query param logout -->
        <c:if test="${param.logout != null}">
            <div>
                You have been logged out.
            </div>
        </c:if>
        <p>
        <label for="username">Username</label>
        <input type="text" id="username" name="username"/>
        </p>
        <p>
        <label for="password">Password</label>
        <input type="password" id="password" name="password"/>
        </p>
        <!-- if using RememberMeConfigurer make sure remember-me matches RememberMeConfigurer#rememberMeParameter -->
        <p>
        <label for="remember-me">Remember Me?</label>
        <input type="checkbox" id="remember-me" name="remember-me"/>

        </p>


        <input type="hidden" name="${_csrf.parameterName}" value="{_csrf.token}"/>
        <div>
            <button type="submit" class="btn">Log in</button>
        </div>


    </fieldset>

 </form>

    </body>


</html>

我的带有注销表单的 index.jsp:

    <!DOCTYPE html>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<html>
    <head>
        <meta charset="utf-8">
        <title>Welcome</title>
    </head> 
    <body>
        <c:url value="/showMessage.html" var="messageUrl" />
        <a href="${messageUrl}">Click to enter</a>

        <form action="logout" method="post">
            <input type="submit" value="logout"/>
            <input type="hidden" name="${_csrf.parameterName}" value="{_csrf.token}"/>

        </form>
    </body>
</html>

我的安全配置文件:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void congigureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    }

    public void configure(HttpSecurity http) throws Exception{

        http.authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
        .loginPage("/login")
            .and()
        .httpBasic();
    }
}

一个空的 WebApplicationInitializer:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}

登录控制器:

    @Controller
public class LoginController {

    @RequestMapping(value="/login", method=RequestMethod.GET)
    public String loginPage(ModelMap map){

        //prefix: /WEB-INF/view
        //postfix .jsp
        //prefix + view + postfix
        // /WEB-INF/view/login.jsp
        return "login";

    }

这是我的 application-config.xml 中的代码

<context:component-scan
        base-package="com.springsecurityexample"/>

这是我的 mvc-config.xml 文件中的代码:

<context:component-scan
        base-package="com.springsecurityexample.web"/> 


<mvc:annotation-driven />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
</bean>

还有我的 web.xml 文件:

<display-name>SpringSecurityTut1</display-name>

   <!--
        - Location of the XML file that defines the root application context.
        - Applied by ContextLoaderListener.
    -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/application-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <!--
        - Servlet that dispatches request to registered handlers (Controller implementations).
    -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

</web-app>

【问题讨论】:

  • 据我所知 Java 配置,你不必在公共 void 配置方法中添加 CSRF 令牌参数。
  • 视频中,导师没有。你会怎么做呢。我愿意尝试。
  • 查看 Spring-security 文档而不是抱怨导师没有它。下面wpj给出的答案也是正确的。
  • 我确实查看了 Spring 文档,它与导师的内容相同。一旦我解决了真正的问题,wpj 的回答不起作用并引起了另一个问题。导师的解决方案奏效了,所以我对导师的观察是有效的。无论如何,这是一个拼写错误。我忘记了价值赋值语句中的 $。顺便说一句,我想出了如何在配置方法中添加一个 CSRF 令牌并且它起作用了。尽管如此,即使没有我添加令牌,它也能正常工作。表面上看,这是因为 Spring 4 及更高版本自动启用了令牌。感谢您的意见。

标签: java xml spring jsp


【解决方案1】:

这是一个简单的错误,花了我一整天的时间。我在登录页面和索引页面的赋值中都忘记了“$”。

我有 value="{_csrf.token} 而不是 value="${_csrf.token}

就是这样。缺少美元符号!!感谢所有提供意见的人。

【讨论】:

    【解决方案2】:

    也许你需要&lt;form:form&gt;&lt;/form:form&gt; 因为

     <input type="hidden"
                   name="${_csrf.parameterName}"
                   value="${_csrf.token}"/>
    

    是弹簧标签

    【讨论】:

    • 我试过了,消息从:HTTP Status 403 - Expected CSRF token not found。你的会话过期了吗?所以我仍然卡住了。收件人:HTTP 状态 403 - 在请求参数“_csrf”或标头“X-CSRF-TOKEN”上发现无效的 CSRF 令牌“{_csrf.token}”。
    • 一个遗漏导致了原来的问题。我省略了第二个 $。一旦我修复了遗漏错误,使用
      似乎会导致我的 onClick 事件未注册。尽管进行了更正,但遗漏还是解决了我原来的问题。感谢您的意见。
    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 2017-05-02
    • 2016-05-24
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2018-06-19
    • 2020-03-12
    相关资源
    最近更新 更多