Безопасность Spring - доступ запрещен из-за CSRF

Я разрабатываю веб-сайт с использованием Spring Security, и у меня есть незащищенная страница "product / 58", где у меня есть следующая форма:

<form:form name = "offerForm" id = "offer" modelAttribute = "offerProposal" action = "/product/make/offer/" method = "post" enctype = "multipart/form-data">
     <input type = "hidden" name = "${_csrf.parameterName}" value = "${_csrf.token}"/>         

    <form:input path = "minPrice"/>
</form:form>

Проблема в том, что если я вхожу в систему и открываю страницу (я аутентифицированный пользователь), отправляю форму, безопасность Spring перенаправляет меня на запрещенный контроллер, и в журнале отображается:

2018-03-22 19:09:42,679 DEBUG [user1_308 (21C272993EC9D1BD7085533415452657)] [https://localhost:8443/standard/resources/js/slick/ajax-loader.gif] [org.springframework.security.web.context.HttpSessionSecurityContextRepository] Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@4193b3e0: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4193b3e0: Principal: com.projectx.standard.services.user.model.CustomUserDetails@58c7c40: Username: user1; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 7A5CB3F014A45BB6632A3503A7B23D02; Granted Authorities: ROLE_USER'
2018-03-22 19:09:42,680 DEBUG [user1_308 (21C272993EC9D1BD7085533415452657)] [https://localhost:8443/standard/resources/js/slick/ajax-loader.gif] [org.springframework.security.web.csrf.CsrfFilter] Invalid CSRF token found for https://localhost:8443/standard/product/make/offer/
2018-03-22 19:09:42,747 INFO [user1_308 (21C272993EC9D1BD7085533415452657)] [https://localhost:8443/standard/resources/js/slick/ajax-loader.gif] [com.projectx.standard.app.interceptor.LogInterceptor] [Start request] - ************* URL https://localhost:8443/standard/accessDenied/ *************

Конфигурация пружинной безопасности следующая:

<?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"
    xsi:schemaLocation = "http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
                           http://www.springframework.org/schema/security 
                           http://www.springframework.org/schema/security/spring-security-4.2.xsd">

    <http pattern = "/resources/css" security = "none" />
    <http pattern = "/resources/images" security = "none" />
    <http pattern = "/resources/js" security = "none" />

    <global-method-security secured-annotations = "enabled" />

    <beans:bean id = "ajaxAwareLoginUrlAuthenticationEntryPoint" class = "com.projectx.standard.app.handler.AjaxAwareLoginUrlAuthenticationEntryPoint">
        <beans:constructor-arg value = "/login/" />       
    </beans:bean>
    <http use-expressions = "true" disable-url-rewriting = "true"  entry-point-ref = "ajaxAwareLoginUrlAuthenticationEntryPoint">
        <access-denied-handler error-page = "/accessDenied/" />
        <session-management>
            <concurrency-control expired-url = "/login/" />
        </session-management>
        <logout logout-success-url = "/" invalidate-session = "true" logout-url = "/logout" />
        <intercept-url pattern = "/favicon.ico" access = "permitAll"
            requires-channel = "https" />
        <intercept-url pattern = "/robots.txt" access = "permitAll"
            requires-channel = "https" />
        <intercept-url pattern = "/product/make/offer/*" access = "hasRole('ROLE_USER')" />

        <intercept-url pattern = "/**" access = "permitAll"
            requires-channel = "https" />
        <!-- Set the login page and what to do if login fails -->
        <form-login login-page = "/login/"
            authentication-failure-handler-ref = "customAuthenticationFailureHandler"
            authentication-success-handler-ref = "customAuthenticationSuccessHandler"
            username-parameter = "j_username" 
            password-parameter = "j_password"
            login-processing-url = "/j_spring_security_check"
            always-use-default-target = "false" />

        <remember-me data-source-ref = "dataSource"
            remember-me-parameter = "_spring_security_remember_me"
            remember-me-cookie = "SPRING_SECURITY_REMEMBER_ME_COOKIE" />
    </http>

    <beans:bean id = "customAuthenticationSuccessHandler"
        class = "com.projectx.standard.app.handler.CustomAuthenticationSuccessHandler" />
    <beans:bean id = "customAuthenticationFailureHandler"
        class = "com.projectx.standard.app.handler.CustomAuthenticationFailureHandler">
        <beans:property name = "defaultFailureUrl" value = "/login/?error=true" />
    </beans:bean>

    <!-- Use a BCryptPasswordEncoder encoder since the user's passwords are 
        stored as BCryptPasswordEncoder in the database -->
    <beans:bean id = "passwordEncoder"
        class = "org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

    <authentication-manager>
        <authentication-provider user-service-ref = "loginService">
            <password-encoder ref = "passwordEncoder" />
        </authentication-provider>
    </authentication-manager>
</beans:beans>

Это похоже на CSRF, но форма как токен. Что я могу сделать, чтобы это исправить?

Спасибо

1
0
385
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Разобрался ... Если я добавил? $ {_ Csrf.parameterName} = $ {_ csrf.token} в действие формы, то все заработает.

Не знаю, лучший ли это подход, но он работает!

Другие вопросы по теме