TestRestTemplate и spring security

#spring-mvc #spring-security #integration-testing #spring5

#spring-mvc #spring-безопасность #интеграция-тестирование #spring5

Вопрос:

Я изучаю spring rest. Я медленно создаю приложение. У меня было полное интеграционное тестирование, которое хорошо работало с использованием TestRestTemplate.
Тем не менее, я только начал добавлять spring security в свое приложение. Буквально, как только я добавляю зависимость spring security, мое тестирование завершается неудачей.

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
 

Я получаю эти ошибки следующим образом:

 Error while extracting response for type [class [Lcom.myproject.model.viewobjects.AView;] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `[Lcom.myproject.model.viewobjects.AView;` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `[Lcom.myproject.model.viewobjects.AView;` out of START_OBJECT token
 at [Source: (PushbackInputStream); line: 1, column: 1]
 

Когда я выполняю отладку, возвращаемый объект, который он пытается десериализовать, равен нулю. Если я установлю точку останова на контроллере rest, она даже не попадет туда.

Похоже, что простое добавление зависимости включает множество значений по умолчанию. Как мне выполнить тестирование с включенной защитой? 1) Могу ли я как-то отключить защиту для тестирования?

2) Могу ли я как-то разрешить отсутствие учетных данных или отправить приемлемые поддельные учетные данные? (Я видел примеры @WithMockUser, но это не работает с TestRestTemplate)

Редактировать: я попытался добавить реализацию безопасности в свой тестовый класс, чтобы включить анонимный доступ и разрешить все:

 @EnableWebSecurity
class TestSecurityConfig extends WebSecurityConfigurerAdapter
    {
    @Override
    protected void configure(HttpSecurity http) throws Exception
        {
        http.anonymous().and().authorizeRequests().antMatchers("/**").permitAll();
        }
    }
 

Результатом этого является то, что @GetMapping работает. Я могу отследить, что вызовы доходят до контроллера. Но @PostMapping по-прежнему не работают. Вызовы никогда не доходят до контроллера.
Вызовы post выглядят так:

 updatedAView = restTemplate.postForObject(create_aview_url, aView, AView.class);
 

Почему бы получить работу, но не опубликовать???
Кроме того, чтобы убедиться, что не было ничего другого, я снова пошел и удалил зависимость spring-boot-starter-security и весь связанный с ней код. Внезапно все работает. Так что это определенно конфигурация безопасности, которая делает это.

Комментарии:

1. что вы пробовали, вы даже читали документацию Spring security перед публикацией здесь? вы задаете здесь абсолютно основные вопросы, прежде чем что-либо пробовать. я рекомендую вам ознакомиться с основами spring security в официальной документации.

2. @Toerktumlare Я перепробовал миллион вещей, я кручу колеса здесь. Я только что опубликовал редактирование, показывающее, как я пытался настроить конфигурацию безопасности для тестового класса, который широко открыт, и как это позволило мне выполнить Get, но у меня все те же проблемы с PostMapping, PutMapping и DeleteMapping. Я бы подумал, что это обычная ситуация, поскольку в большинстве приложений включена безопасность. Поэтому люди должны тестировать с помощью TestRestTemplate и security.

3. @Toerktumlare с точки зрения чтения документации, пожалуйста, поймите, что у меня действительно работает приложение с проверкой подлинности. Проблема в том, что все мои тесты терпят неудачу. Я буквально трачу больше времени на то, чтобы заставить тесты работать, чем приложение.

Ответ №1:

Если вы включаете зависимость spring-boot-starter-security, spring security включена по умолчанию. Запросы TestRestTemplate будут обрабатываться через систему безопасности.

Если вы хотите протестировать без аутентификации, вы можете настроить версию WebSecurityConfigurerAdapter с помощью @EnableWebSecurity для тестирования только разрешительной. Возможно, вам потребуется исключить другие конфигурации, чтобы они не переопределяли это.

Вот пример:

 @EnableWebSecurity
class TestSecurityConfig extends WebSecurityConfigurerAdapter
    {
    @Override
    protected void configure(HttpSecurity http) throws Exception
        {
        http.anonymous().and().csrf().disable().authorizeRequests().antMatchers("/**").permitAll();
        }
    }
 

Это позволяет отправлять запросы без учетных данных пользователя

 http.anonymous()
 

Если вы не включаете:

 csrf().disable()
 

@GetMapping будет работать, но не будет PostMapping или запросов, которые изменяют данные, поскольку именно тогда вступает в действие csrf, и он включен по умолчанию.

Это позволяет вам получить доступ ко всем URL-адресам в вашем приложении. Вы, конечно, можете ограничить это, если хотите:

authorizeRequests().antMatchers(«/**»).PermitAll()

Комментарии:

1. @Order on WebSecurityConfigurers must be unique. Order of 100 was already used возникла эта ошибка, когда я попытался создать класс для тестирования.