Bootstrap导航栏中的错误登录表单Spring

时间:2015-09-02 14:05:47

标签: java spring twitter-bootstrap spring-mvc spring-security

我有一个新的java项目,我想在其中使用Bootstrap。 我想在webapp项目的标题中创建一个navbar,我想插入登录表单。

但是当我运行我的应用程序并尝试登录时,我得到了以下错误:

  

HTTP状态403 - 在请求中找到无效的CSRF令牌“null”   参数'_csrf'或标题'X-CSRF-TOKEN'。

我尝试在堆栈上搜索解决方案,但没有结果。

有什么想法吗?

我的header.jspx

<div id="header" 
xmlns:sec="http://www.springframework.org/security/tags" 
xmlns:jsp="http://java.sun.com/JSP/Page" 
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:c="http://java.sun.com/jsp/jstl/core" 
xmlns:spring="http://www.springframework.org/tags" version="2.0">

  <jsp:directive.page contentType="text/html;charset=UTF-8" />
  <jsp:output omit-xml-declaration="yes"/>

    <spring:url value="/resources/j_spring_security_logout" var="logoutUrl"/>
    <spring:url value="/" var="homeUrl" />
    <spring:url value="/resources/j_spring_security_check" var="form_url" />

    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed"
                    data-toggle="collapse" data-target="#navbar" aria-expanded="false"
                    aria-controls="navbar">
                    <span class="sr-only"></span> <span class="sr-only">Toggle
                        navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span>
                    <span class="icon-bar"></span>

                </button>
                <a href="${homeUrl}"><span class="fa fa-home fa-2x">&#160;</span>Home</a>
                <a class="navbar-brand" href="#">PAGE TITLE</a>

            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <c:choose>
                    <c:when test="${pageContext['request'].userPrincipal != null}">
                        <sec:authentication property="principal.username" var="username" />
                        <li style="float: right; border-left: 1px solid #c6d0da;"><a
                            href="${logoutUrl}"> <span class="fa fa-sign-out fa-2x">&#160;</span>
                            <spring:message code="security_logout" />
                        </a></li>
                        <li><a href="${showLoggedUserUrl}${username}"> <span
                                class="fa fa-user fa-2x">&#160;</span>${username}
                        </a></li>
                    </c:when>
                    <c:otherwise>
                        <form action="${fn:escapeXml(form_url)}" method="POST" class="navbar-form navbar-right">
                            <div class="form-group">
                              <input type="text" placeholder="Username" class="form-control" />
                            </div>
                            <div class="form-group">
                              <input type="password" placeholder="Password" class="form-control" />
                            </div>
                            <button type="submit" class="btn btn-success">Accedi</button>

                  </form>                   
                  </c:otherwise>
                </c:choose>
            </div>
        </div>
    </nav>

</div>

我的security-context.xml是:

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

    <http auto-config="true" use-expressions="true">
        <form-login login-processing-url="/resources/j_spring_security_check" login-page="/" 
            authentication-failure-url="/login?login_error=t" />
        <!-- authentication-success-handler-ref="myAuthenticationSuccessHandler"/> -->

        <logout logout-url="/resources/j_spring_security_logout"/>

       <intercept-url pattern="/resources/**" access="permitAll" />
<!--   <intercept-url pattern="/login" access="permitAll" /> -->
       <intercept-url pattern="/" access="permitAll" />
        <intercept-url pattern="/**" access="isAuthenticated()" />

        <session-management>
            <concurrency-control max-sessions="1" />
        </session-management>

    </http>

....

    <beans:bean id="userDetailsService" class="it.ped.security.core.UserDetailsServiceImpl" />

    <!-- Enable controller method level security -->
    <sec:global-method-security pre-post-annotations="enabled" />

    <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <beans:property name="basename" value="classpath:org/springframework/security/messages"/>
    </beans:bean>

 </beans:beans> 

我的servlet-context.xml

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

    <sec:global-method-security pre-post-annotations="enabled" />

    <!-- Configure JSR-303 validation -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="validationMessageSource" ref="messageSource"/>
    </bean> 

    <!-- Allows for mapping the DispatcherServlet to "/" by forwarding static 
        resource requests to the container's default Servlet -->
    <mvc:default-servlet-handler />

    <!-- The controllers are autodetected POJOs labeled with the @Controller 
        annotation. -->
    <context:component-scan base-package="it.ped.web.controller" />
    <context:component-scan base-package="it.ped.web.validator" />
    <context:component-scan base-package="it.ped.web.editor" />

    <mvc:annotation-driven conversion-service="applicationConversionService"/>

    <!-- bean per conversione  -->
    <bean class="it.ped.format.support.ApplicationConversionServiceFactoryBean" 
        id="applicationConversionService" />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
        up static resources / -> default src/main/webap classpath:/META-INF/web-resources/ 
        -> custom JS for example -->
    <mvc:resources location="/, classpath:/META-INF/web-resources/"
        mapping="/resources/**" />

    <!-- Resolves localized messages*.properties and application.properties 
        files in the application to allow for internationalization. The messages*.properties 
        files translate messages, the application.properties resource bundle localizes 
        all application specific messages such as entity names and menu items. -->
    <bean
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
        id="messageSource" p:basenames="WEB-INF/i18n/messages,WEB-INF/i18n/application"
        p:fallbackToSystemLocale="true" />

    <!-- selects a static view for rendering without the need for an explicit 
        controller -->
    <mvc:view-controller path="/" view-name="index" />
    <mvc:view-controller path="/uncaughtException"/>
    <mvc:view-controller path="/resourceNotFound"/>
    <mvc:view-controller path="/dataAccessFailure"/>
    <mvc:view-controller path="/accessDeniedException"/>

    <!-- This bean resolves specific types of exceptions to corresponding logical - view names for error views. 
     The default behaviour of DispatcherServlet - is to propagate all exceptions to the servlet container: 
     this will happen - here with all other types of exceptions. -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:defaultErrorView="uncaughtException">
        <property name="exceptionMappings">
            <props>
                <prop key=".DataAccessException">dataAccessFailure</prop>
                <prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop>
                <prop key=".TypeMismatchException">resourceNotFound</prop>
                <prop key=".MissingServletRequestParameterException">resourceNotFound</prop>
                <prop key=".AccessDeniedException">accessDeniedException</prop>
            </props>
        </property>
    </bean>

    <!-- Tiles Configuration -->
    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
    </bean>

    <!-- register "global" interceptor beans to apply to all registered HandlerMappings -->
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang" />
    </mvc:interceptors>

    <!-- store preferred language configuration in a cookie -->
    <bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="locale"/>

    <!-- resolves localized <theme_name>.properties files in the classpath to allow for theme support -->
    <bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource" />

    <!-- store preferred theme configuration in a cookie -->
    <bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard" />

    <!-- allows for integration of file upload functionality -->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
        id="multipartResolver" />

    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
        id="tilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/layouts/layouts.xml</value>
                <!-- Scan views directory for Tiles configurations -->
                <value>/WEB-INF/views/**/views.xml</value>
            </list>
        </property>
    </bean>

</beans>

2 个答案:

答案 0 :(得分:3)

如果您导入:

xmlns:form="http://www.springframework.org/tags/form" 

进入header.jspx,然后使用:

<form:form action="${fn:escapeXml(form_url)}" method="POST" class="navbar-form navbar-right">
....

input hidden会自动加入,您不必担心添加它......

答案 1 :(得分:2)

正如错误日志所解释的那样,缺少csrf令牌,我知道两种不同的方式将它添加到您的帖子请求中:

尝试以包含csrf.token:

的形式添加隐藏输入
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

或者将其添加到您的操作网址中:

<form action="./url?${_csrf.parameterName}=${_csrf.token}" method="post">

更多信息here