#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
возникла эта ошибка, когда я попытался создать класс для тестирования.