2016-07-27 168 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");