我有一个新的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"> </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"> </span>
<spring:message code="security_logout" />
</a></li>
<li><a href="${showLoggedUserUrl}${username}"> <span
class="fa fa-user fa-2x"> </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>
答案 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