Как отправить запрос на контроллер, который защищен с помощью Spring Security?

Как получить доступ к защищенным контроллерам через запросы с "доверенного" стороннего сервиса в Spring Security, используя csrf защиту? Какие заголовки необходимо использовать и как получить csrf токен? Если есть другие альтернативы, пожалуйста, подскажите.
  • 21 сентября 2023 г. 21:27
Ответы на вопрос 1
Чтобы отправить запрос на контроллер, защищенный с помощью Spring Security, вам необходимо включить csrf защиту и использовать csrf токен при отправке запроса.

1. Включите csrf защиту в вашем приложении, добавив следующую конфигурацию в класс, наследующий WebSecurityConfigurerAdapter:

```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}
```

2. В вашем контроллере добавьте аннотацию `@CrossOrigin` для разрешения доступа к контроллеру из "доверенного" стороннего сервиса:

```java
@RestController
@CrossOrigin(origins = "http://trusted-service.com")
public class MyController {

    @GetMapping("/endpoint")
    public String endpoint() {
        // Обработка запроса
    }
}
```

3. Чтобы получить csrf токен, вы можете отправить GET запрос на /csrf с использованием подходящих заголовков:

```java
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange("http://your-app-url/csrf", HttpMethod.GET, entity, String.class);
String csrfToken = response.getBody();
```

4. Включите csrf токен в заголовки при отправке запроса:

```java
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("X-XSRF-TOKEN", csrfToken);
HttpEntity<String> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange("http://your-app-url/endpoint", HttpMethod.GET, entity, String.class);
String result = response.getBody();
```

Альтернативой использованию csrf защиты может быть отключение csrf защиты для определенного пути в вашей конфигурации Spring Security, используя `ignoring()` метод:

```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/public-endpoint").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}
```

В этом случае, публичные эндпоинты, такие как "/public-endpoint", будут доступны без csrf токена.

Помните, что отключение csrf защиты может представлять угрозу безопасности вашего приложения, поэтому необходимо быть осторожным при применении данного подхода.
Похожие вопросы