12 Aralık 2019 Perşembe

SpringSecurity CsrfConfigurer Sınıfı

Giriş
Şu satırları dahil ederiz.
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
Cross-Site Request Forgery (csrf veya xsrf) SpringSecurity projesinde otomatik olarak etkindir. Açıklaması şöyle.
If you are using Spring MVC tag, the CsrfToken is automatically included for you using the CsrfRequestDataValueProcessor.
Bu Sınıf Ne Yapar
org.springframework.security.web.csrf.CsrfFilter nesnesini yaratır. Bu nesneye de bir tane repository takılır. Repository CSRF token değerlerini saklar.

Hata Mesajı

İstemci tarafında şu hatayı alıyorsak CSRF etkindir ancak istemci parametreleri göndermiyordur.
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'
_csrf  parametresi Synchronizer token" anlamına gelir. Formlarda kullanılır.
X-CSRF-TOKEN parametresi "Cookie-to-header token" anlamına gelir.

Get İsteği
Get isteğinde tarayıcı csrf token gönderir. Şöyle görebiliriz.
@RequestMapping(value = "/first", method = RequestMethod.GET)
public ResponseEntity get(HttpServletRequest request) {
  CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
  System.out.println(token.getHeaderName()+" = "+token.getToken());
  return ResponseEntity.ok("...");
}
Post İsteği
Form'larda ise şöyledir"Synchronizer token" kullanır.
<form>
  ...
  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
Örnek 
Şöyle yaparız. Hem "Synchronizer token" hem de  "Cookie-to-header token" pattern kullanır
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_headerName" th:content="${_csrf.headerName}">
Örnek 
Şöyle yaparız. Hem "Synchronizer token" hem de  "Cookie-to-header token" pattern kullanır
<html>
  <head>
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>
    ...
  </head>


$(function () {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
});
Örnek - Form
Şöyle yaparız. "Synchronizer token" kullanır.
<input th:name="${_csrf.parameterName}" th:value="${_csrf.token}" type="hidden"/>
Örnek - Form
Şöyle yaparız"Synchronizer token" kullanır.
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
    method="post">
  <input type="submit"
    value="Log out" />
  <input type="hidden"
    name="${_csrf.parameterName}"
    value="${_csrf.token}"/>
</form
constructor
Şöyle yaparız
@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .csrf()
      .csrfTokenRepository(new PerRequestCsrfTokenRepository())
    .and()
    .authorizeRequests()
    .anyRequest().authenticated()
    .and()
    .formLogin().permitAll();
}
disable metodu
Bu metod csrf desteğini kapamayı sağlar.

Örnek
Şöyle yaparız.
http.csrf().disable()
Örnek
Şöyle yaparız.
private final CorsFilter corsFilter = ...;

http
  .csrf()
  .disable()
  .addFilterBefore(corsFilter, CsrfFilter.class)
  .headers()
  .frameOptions()
  .disable()
csrfTokenRepository metodu
Spring 3 çeşit CsrfTokenRepository sınıfı sunar. Bunlar şöyle

1. CookieCsrfTokenRepository - Angular İçin Gerekir
CookieCsrfTokenRepository yazısına taşıdım.

2. HttpSessionCsrfTokenRepository
HttpSessionCsrfTokenRepository yazısına bakabilirsiniz. Tüm session boyunca kullanılacak Csrf token'ı saklar.

3. LazyCsrfTokenRepository
Açıklaması şöyle
Delays saving the new CSRF token until its generated attributes are accessed.
ignoringAntMatchers metodu
Şöyle yaparız.
private  final String LOGIN_URL= "";//your login url
private  final String LOGOUT_URL = "";//your logout url

protected void configure(HttpSecurity http) throws Exception {
    // other code here.........
    http.csrf().ignoringAntMatchers(LOGIN_URL, LOGOUT_URL);
}
requireCsrfProtectionMatcher metodu
Şöyle yaparız.
http
  // Enable csrf only on some request matches
  .csrf()
  .requireCsrfProtectionMatcher(csrfRequestMatcher)
Nesne için şöyle yaparız.
RequestMatcher csrfRequestMatcher = new RequestMatcher() {

  private AntPathRequestMatcher[] requestMatchers = {
    new AntPathRequestMatcher("/run/connect/**")
  };

  @Override
  public boolean matches(HttpServletRequest request) {
    for (AntPathRequestMatcher rm : requestMatchers) {
      // If request matches specified urls, apply csfr
      if (rm.matches(request)) { return true; }
    }
    return false;
  }

}; 

Hiç yorum yok:

Yorum Gönder