Spring Security 3.2 CSRF отключить для определенных URL-адресов
Включено CSRF в моем приложении Spring MVC с помощью Spring security 3.2.
Мой spring -security.xml
<http>
<intercept-url pattern="/**/verify" requires-channel="https"/>
<intercept-url pattern="/**/login*" requires-channel="http"/>
...
...
<csrf />
</http>
Попытка отключить CSRF для запросов, которые содержат "проверку" в URL-адресе запроса.
MySecurityConfig.java
@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
private CsrfMatcher csrfRequestMatcher = new CsrfMatcher();
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().requireCsrfProtectionMatcher(csrfRequestMatcher);
}
class CsrfMatcher implements RequestMatcher {
@Override
public boolean matches(HttpServletRequest request) {
if (request.getRequestURL().indexOf("verify") != -1)
return false;
else if (request.getRequestURL().indexOf("homePage") != -1)
return false;
return true;
}
}
}
Фильтр Csrf проверяет токен CSRF, который отправляется из "проверки" и исключение Invalid token (403), когда я отправляю запрос на https из http. Как отключить аутентификацию токена csrf в таком сценарии?
Ответы
Ответ 1
Я знаю, что это не прямой ответ, но люди (как я) обычно не указывают версию spring при поиске таких вопросов.
Итак, поскольку spring безопасность существует метод, который позволяет игнорировать некоторые маршруты:
Следующее гарантирует, что защита CSRF игнорируется:
- Любой GET, HEAD, TRACE, OPTIONS (это значение по умолчанию)
- Мы также явно заявляем, что игнорируем любой запрос, начинающийся с "/sockjs/"
http
.csrf()
.ignoringAntMatchers("/sockjs/**")
.and()
...
Ответ 2
Я надеюсь, что мой ответ может помочь кому-то еще. Я нашел этот вопрос в поиске Как отключить CSFR для конкретных URL в Spring Boot.
Я использовал решение, описанное здесь:
http://blog.netgloo.com/2014/09/28/spring-boot-enable-the-csrf-check-selectively-only-for-some-requests/
Это конфигурация Spring Security, которая позволяет отключить элемент управления CSFR для некоторых URL-адресов:
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// Build the request matcher for CSFR protection
RequestMatcher csrfRequestMatcher = new RequestMatcher() {
// Disable CSFR protection on the following urls:
private AntPathRequestMatcher[] requestMatchers = {
new AntPathRequestMatcher("/login"),
new AntPathRequestMatcher("/logout"),
new AntPathRequestMatcher("/verify/**")
};
@Override
public boolean matches(HttpServletRequest request) {
// If the request match one url the CSFR protection will be disabled
for (AntPathRequestMatcher rm : requestMatchers) {
if (rm.matches(request)) { return false; }
}
return true;
} // method matches
}; // new RequestMatcher
// Set security configurations
http
// Disable the csrf protection on some request matches
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
.and()
// Other configurations for the http object
// ...
return;
} // method configure
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
// Authentication manager configuration
// ...
}
}
Он работает с Spring Boot 1.2.2 (и Spring Security 3.2.6).
Ответ 3
Я использую Spring Security v4.1. После большого количества чтения и тестирования я отключу функцию защиты crcf для определенных URL-адресов, используя конфигурацию xml.
<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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<http pattern="/files/**" security="none" create-session="stateless"/>
<http>
<intercept-url pattern="/admin/**" access="hasAuthority('GenericUser')" />
<intercept-url pattern="/**" access="permitAll" />
<form-login
login-page="/login"
login-processing-url="/login"
authentication-failure-url="/login"
default-target-url="/admin/"
password-parameter="password"
username-parameter="username"
/>
<logout delete-cookies="JSESSIONID" logout-success-url="/login" logout-url="/admin/logout" />
<http-basic />
<csrf request-matcher-ref="csrfMatcher"/>
</http>
<beans:bean id="csrfMatcher" class="org.springframework.security.web.util.matcher.OrRequestMatcher">
<beans:constructor-arg>
<util:list value-type="org.springframework.security.web.util.matcher.RequestMatcher">
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/rest/**"/>
<beans:constructor-arg name="httpMethod" value="POST"/>
</beans:bean>
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/rest/**"/>
<beans:constructor-arg name="httpMethod" value="PUT"/>
</beans:bean>
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/rest/**"/>
<beans:constructor-arg name="httpMethod" value="DELETE"/>
</beans:bean>
</util:list>
</beans:constructor-arg>
</beans:bean>
//...
</beans:bean>
В приведенной выше конфигурации я разрешаю crcf-безопасность только для запросов POST | PUT | DELETE всех URL-адресов, начинающихся с /rest/
.
Ответ 4
Вот хорошо сделанный блог о том, как отключить CSRF-проверку для некоторых URL-адресов, используя конфигурацию xml:
http://blogs.sourceallies.com/2014/04/customizing-csrf-protection-in-spring-security/
К сожалению, он не работает с моей версией Spring Security 3.2.8.
Ответ 5
Временно эта простая строка может быть удобной:
<http pattern="/home/test**" security="none" />
Ответ 6
Использовать security = "none".
например, в spring -security-config.xml
<security:intercept-url pattern="/*/verify" security="none" />
Ответ 7
Какой класс всегда расширяет WebSecurityConfigurerAdapter
Просто добавьте это
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**")
.antMatchers("/api/payu-gateway-success")
.antMatchers("/api/payu-gateway-failure")
.antMatchers("/api/payu-gateway-dispute")
.antMatchers("/api/payu-gateway-refund");
}
И те, которые я хочу защитить, находятся в методе:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()//.disable()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(http401UnauthorizedEntryPoint())
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.rememberMeParameter("remember-me")
.key(jHipsterProperties.getSecurity().getRememberMe().getKey())
.and()
.formLogin()
.authenticationDetailsSource(authenticationDetailsSource)
.loginProcessingUrl("/api/authentication")
// .successHandler(ajaxAuthenticationSuccessHandler())
.successHandler(ajaxAuthenticationSuccessHandler())
.failureHandler(ajaxAuthenticationFailureHandler())
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler())
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/profile-info").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
// #later
//.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("api/myServlet").permitAll()
.antMatchers("/management/**").permitAll()
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN);
}
Ответ 8
Явное отключение для определенных шаблонов URL и включение для некоторых шаблонов URL.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SecurityConfig {
@Configuration
@Order
public static class GeneralWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private CustomPasswordEncoder passwordEncoder;
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/rest/**").and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/home/**","/search/**","/geo/**").authenticated().and().csrf()
.and().formLogin().loginPage("/login")
.usernameParameter("username").passwordParameter("password")
.and().exceptionHandling().accessDeniedPage("/error")
.and().sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
}
}
}