2016-07-27 258 views
0

我有一个完美运行的Spring 4 MVC +安全应用程序。HDIV + Spring Security 4:HDIV_PARAMETER_DOES_NOT_EXIST

我想HDIV与之集成,并已通过文档和展示例如:https://github.com/hdiv/hdiv-spring-mvc-showcase/

当我使用avoidValidationInUrlsWithoutParams =真,一切工作正常,直到地步,我没有参数(显然)。

当我删除该部分时,它只是引发我到安全错误页面。 我试着调试,我看到Spring Security的成功验证 - 但HDIV抛出HDIV_PARAMETER不存在错误 - 这是我在日志中:

2016-07-27 08:24:34 [http-apr-8080-exec-5] INFO org.hdiv.logs.Logger - HDIV_PARAMETER_DOES_NOT_EXIST;/EmployeePortal/modules/dashboard.htm;177622190;;;127.0.0.1;127.0.0.1;MALLIKAM; 

显然,我明白页面从那里找到了HDIV_STATE,但它找不到CSRF? (我假设3分号用于HDIV试图找到的一些参数,并且该参数是CSRF?)

另外,我能够在索引页上看到生成的csrf(这让我怀疑是否有因为最后一次,当我尝试过时,所有隐藏的字段将显示不同 - 空白或0,如果我正确记得正确设置HDIV。)

如果是这样,我想知道为什么和什么我可以解决它吗?

这是我到目前为止有:

的web.xml

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml, /WEB-INF/spring-security.xml, /WEB-INF/hdiv-config.xml, ...</param-value> 
</context-param> 

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

<!-- For HTTPSession events --> 
<listener> 
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> 
</listener> 

<!-- HDIV Listener --> 
<listener> 
    <listener-class>org.hdiv.listener.InitListener</listener-class> 
</listener> 

<filter> 
    <filter-name>ValidatorFilter</filter-name> 
    <filter-class>org.hdiv.filter.ValidatorFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>ValidatorFilter</filter-name> 
    <!-- Spring MVC Servlet name--> 
    <servlet-name>serv1</servlet-name> 
</filter-mapping> 

<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> 

    <servlet> 
    <servlet-name>serv1</servlet-name> 
    <servlet-class> 
        org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring-web-config.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

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

<session-config> 
    <session-timeout>30</session-timeout> 
</session-config> 

弹簧security.xml文件

<!-- To let spring create login page --> 
<http auto-config="false" disable-url-rewriting="true" 
    use-expressions="true"> 

    <access-denied-handler ref="accessDeniedHandler" /> 

    <!-- CSRF is enabled by default Spring 4 onwards --> 

    <!-- check roles --> 
    <intercept-url pattern="/modules/favicon.ico" access="isAnonymous()" /> 
    <intercept-url pattern="/login.htm" access="isAnonymous()" /> 
    <intercept-url pattern="/login.htm?error" access="isAnonymous()" /> 
    <intercept-url pattern="/logout" access="isAnonymous()" /> 
    <intercept-url pattern="/modules/**" access="hasAnyRole('ROLE_y','ROLE_x')" /> 

    <form-login login-page="/" default-target-url="/modules/dashboard.htm" 
     username-parameter="username" password-parameter="password" 
     authentication-failure-url="/login.htm?error" /> 


    <custom-filter after="SECURITY_CONTEXT_FILTER" ref="hdivFilter" /> 

    <!-- Logout --> 
    <logout logout-url="/logout.htm" delete-cookies="JSESSIONID" 
     invalidate-session="true" logout-success-url="/login.htm" /> 

    <!-- Session Management: Invalid Session Url is for SessionTimeout as well 
     as invalid login --> 
    <session-management session-fixation-protection="newSession" 
     invalid-session-url="/login.htm" session-authentication-error-url="/login.htm"> 

     <!-- Concurrency control is to check number of sessions and act accordingly. 
      Error If Max exceeded stops a user from logging in if max-sessions have been 
      exceeded. Expired Url is different from invalid url. --> 
     <concurrency-control max-sessions="2" 
      expired-url="/login.htm" error-if-maximum-exceeded="true" /> 
    </session-management> 

</http> 

<!-- Spring security authentication manager --> 
<authentication-manager alias="authenticationManager"> 
    <!-- Custom Auth Provider checks for login with DB and LDAP both --> 
    <authentication-provider ref="customAuthenticationProvider"> 
    </authentication-provider> 
</authentication-manager> 

<!-- Bean implements AuthenticationProvider and checks if user is valid --> 
<beans:bean id="customAuthenticationProvider" 
    class="..employeeportal.common.util.CustomAuthenticationProvider"> 
    <beans:property name="passwordEncoder" ref="encoder" /> 
</beans:bean> 

<!-- BCrypt Password encoder --> 
<beans:bean id="encoder" 
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /> 

<!-- Access Denied Handler --> 
<beans:bean id="accessDeniedHandler" 
    class="..employeeportal.common.util.AccessDeniedHandler"> 
</beans:bean> 

<beans:bean id="hdivFilter" class="org.hdiv.filter.ValidatorFilter" /> 

春天的Web-config.xml中

<mvc:annotation-driven validator="hdivEditableValidator"/> 

...

的applicationContext.xml

...有所有的服务/ DAO层成分扫描线:

<context:component-scan 
    base-package="..common.service, ..common.dao" /> 

HDIV-config.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:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:hdiv="http://www.hdiv.org/schema/hdiv" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
    http://www.hdiv.org/schema/hdiv http://www.hdiv.org/schema/hdiv/hdiv.xsd"> 

<hdiv:config excludedExtensions="css,ico,js,woff,woff2,ttf,jpg,jpeg,png,gif,eot" 
    errorPage="/security-error" randomName="true" confidentiality="true" debugMode="true"> 
    <hdiv:startPages method="get">/,/login.htm</hdiv:startPages> 
    <hdiv:startPages method="post">/logout, /logout.htm</hdiv:startPages> 
    <hdiv:startParameters>_csrf</hdiv:startParameters> 
</hdiv:config> 

<!-- Accepted pattern within the application for all editable parameters (generated from textbox and textarea) --> 
<hdiv:validation id="safeText"> 
    <hdiv:acceptedPattern><![CDATA[^[[email protected]\-_]*$]]></hdiv:acceptedPattern> 
</hdiv:validation> 

<!-- Finally, it's necessary to define editable data validation list for 
    the application --> 
<hdiv:editableValidations> 
    <hdiv:validationRule url="/modules/.*"></hdiv:validationRule> 
    <hdiv:validationRule url="/modules/.*" enableDefaults="false">safeText</hdiv:validationRule> 
</hdiv:editableValidations> 

的index.jsp

<form:form name='loginForm' modelAttribute="loginForm" 
        action="login" method='POST'> 

        <div class="form-group"> 
         <div class="input-group"> 
          <span class="input-group-addon"><i class="fa fa-user"></i></span> 

          <form:input path="username" name="username" id="username"/> 
         </div> 
        </div> 
        <div class="form-group"> 
         <div class="input-group"> 

          <form:input path="password" id="password" name="password"/> 
         </div> 
        </div> 
        <div class="form-group no-border margin-top-20"> 
         <input type="submit" 
          class="btn btn-success btn-block" value="Submit" /> 
        </div> 
       </form:form> 

任何帮助,将不胜感激。

回答

1

看来问题与CSRF无关。

Hdiv验证所有传入的请求,为此,所有URL和参数必须在服务器端使用一些支持的技术(如Spring MVC标记)呈现。

您是否使用Spring MVC URL标记来渲染包含在错误文件中的URL?

一旦你使用Spring MVC标签,Hdiv会在URL中包含一个额外的参数(HDIV_STATE),你将避免这个问题。

此参数可以防止对定义的URL进行任何篡改攻击。

其他可能的解决方案是取消使用URL排除对此特定URL或URLS类型的验证,其中Hdiv不验证这些URL。

请参阅此示例:https://github.com/hdiv/hdiv-spring-mvc-showcase-jc/blob/master/src/main/java/org/hdiv/samples/mvc/config/HdivSecurityConfig.java 其中addExclusions方法中定义了不同的排除项。

问候,

罗伯托·贝拉斯科

HDIV安全

+0

我有GitHub的库同样的问题,但我不知道你的意思与MVC URL标签和我需要改变。你可以添加更多的细节吗?谢谢 – megloff

0

我找到了解决办法。 HDIV要求所有链接都在其URL中增加“_HDIV_STATE_”参数。为了实现这一点,你必须使用HDIV中的taglib,而不是原来的JSTL taglib。

请同时参阅HDIV

reference documentation

例如在你的POM中

<dependency> 
     <groupId>org.hdiv</groupId> 
     <artifactId>hdiv-jstl-taglibs-1.2</artifactId> 
     <version>${org.hdiv-version}</version> 
    </dependency> 

例如在你的JSP(在标签库声明注意“www.hdiv.org”)

<%@ taglib prefix="c" uri="http://www.hdiv.org/jsp/jstl/core"%> <c:url value="/messages/messages" var="url" /> <li><a href="${url}">Messages</a></li>

所以你需要通过日<c:url>工具标签来显示URL。然后,这使得与所需的HDIV参数的URL即

localhost:8080/spring-security-example/messages/message?_HDIV_STATE_=26-0-830046F08D66980D1B35F52F2D6677E0 

另一个选择可能是使用从HDIV的实用工具类, 也看到LinkUrlProcessor类别在HDIV

LinkUrlProcessor urlProcessor = HDIVUtil.getLinkUrlProcessor(servletContext); 
String processUrl = urlProcessor.processUrl(request, "/messages/messages");