Po skonfigurowaniu Spring Security 3.2 _csrf.token
nie jest powiązany z żądaniem ani obiektem sesji.
Oto konfiguracja zabezpieczeń wiosny:
<http pattern="/login.jsp" security="none"/>
<http>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=1"
default-target-url="/index.jsp"/>
<logout/>
<csrf />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="test" password="test" authorities="ROLE_USER/>
</user-service>
</authentication-provider>
</authentication-manager>
Plik login.jsp
<form name="f" action="${contextPath}/j_spring_security_check" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<button id="ingresarButton"
name="submit"
type="submit"
class="right"
style="margin-right: 10px;">Ingresar</button>
<span>
<label for="usuario">Usuario :</label>
<input type="text" name="j_username" id="u" class="" value=''/>
</span>
<span>
<label for="clave">Contraseña :</label>
<input type="password"
name="j_password"
id="p"
class=""
onfocus="vc_psfocus = 1;"
value="">
</span>
</form>
I renderuje następny html:
<input type="hidden" name="" value="" />
Wynikiem jest stan HTTP 403:
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
UPDATE Po pewnym debugowaniu obiekt żądania wychodzi dobrze z DelegatingFilterProxy, ale w linii 469 CoyoteAdapter wykonuje request.recycle (); która usuwa wszystkie atrybuty ...
Testuję w Tomcat 6.0.36, 7.0.50 z JDK 1.7.
Nie zrozumiałem tego zachowania, a raczej byłoby to możliwe, gdyby ktoś wskazał mi kierunek wojny z próbkami aplikacji ze Spring Security 3.2, który działa z CSRF.
spring
spring-security
csrf
csrf-protection
Hugo Robayo
źródło
źródło
spring-security.xml
) z Spring 4.0.0 RELEASE (GA), Spring Security 3.2.0 RELEASE (GA) (chociaż jest zintegrowany z Struts 2.3.16. Nie dałem mu spróbuj z samym Spring MVC). Jednak kończy się to niepowodzeniem, gdy żądanie jest wieloczęściowe, aby przesłać pliki o stanie 403. Trudno mi znaleźć rozwiązanie tego problemu.web.xml
jest kluczowa.MultipartFilter
należy zgłosić wcześniejspringSecurityFilterChain
. Mam nadzieję, że to pomoże. Dzięki.Odpowiedzi:
Wygląda na to, że ochrona CSRF (Cross Site Request Forgery) w Twojej aplikacji Spring jest włączona. W rzeczywistości jest domyślnie włączona.
Według spring.io :
Aby to wyłączyć:
@Configuration public class RestSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }
Jeśli jednak chcesz, aby ochrona CSRF była włączona, musisz dołączyć do swojego formularza rozszerzenie
csrftoken
. Możesz to zrobić w ten sposób:<form .... > ....other fields here.... <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> </form>
Możesz nawet dołączyć token CSRF do akcji formularza:
<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">
źródło
.csrf().ignoringAntMatchers("/h2-console/**")
Nie powinieneś dodawać do formularza logowania ?;
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
Jak stwierdzono tutaj w dokumentacji bezpieczeństwa Spring
źródło
Jeśli złożysz wniosek,
security="none"
nie zostanie wygenerowany żaden token csrf. Strona nie przejdzie przez filtr bezpieczeństwa. Użyj roli ANONYMOUS.Nie wchodziłem w szczegóły, ale to działa dla mnie.
<http auto-config="true" use-expressions="true"> <intercept-url pattern="/login.jsp" access="hasRole('ANONYMOUS')" /> <!-- you configuration --> </http>
źródło
Spróbuj to zmienić:
<csrf />
to:<csrf disabled="true"/>
. Powinien wyłączyć csfr.źródło
Do grasicy można dodać:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
źródło
Wiosenna dokumentacja dotycząca wyłączenia csrf: https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-configure
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }
źródło
Miałem kiedyś ten sam problem.
Twoja konfiguracja używa security = "none", więc nie można wygenerować _csrf:
<http pattern="/login.jsp" security="none"/>
możesz ustawić access = "IS_AUTHENTICATED_ANONYMOUSLY" dla strony /login.jsp zastąp powyższą konfigurację :
<http> <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/> <intercept-url pattern="/**" access="ROLE_USER"/> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=1" default-target-url="/index.jsp"/> <logout/> <csrf /> </http>
źródło
myślę, że csrf działa tylko z formami sprężynowymi
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
zmień
form:form
tag i zobacz, jak działa.źródło
Zobacz moją działającą przykładową aplikację na Github i porównaj z konfiguracją.
źródło
Żadne z rozwiązań u mnie nie zadziałało. Jedyne, które zadziałało dla mnie w formie wiosennej to:
action = "./ upload? $ {_ csrf.parameterName} = $ {_ csrf.token}"
WYMIANA:
action = "./ upload? _csrf = $ {_ csrf.token}"
(Wiosna 5 z włączonym csrf w konfiguracji java)
źródło
W kontrolerze dodaj następujące informacje:
@RequestParam(value = "_csrf", required = false) String csrf
A na stronie jsp dodaj
<form:form modelAttribute="someName" action="someURI?${_csrf.parameterName}=${_csrf.token}
źródło