Spring Security + контроллер тестирования Spring-Boot
Я пытаюсь проверить домашний контроллер
@RequestMapping("/")
@ResponseBody
String home() {
return "Hello World!";
}
Я использую Spring Security, используя в качестве имени пользователя "user" и проверяю как пароль по умолчанию, но @PreAuthorize не работает
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@PreAuthorize("hasRole('ADMIN')")
public class HomeControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
@WithMockUser(username = "user", password = "test", roles = "ADMIN")
public void home() throws Exception {
String body = this.restTemplate.getForObject("/", String.class);
assertThat(body).isEqualTo("Hello World!");
}
}
Результат
Ожидаемый результат:
<"[Hello World!]">
Фактический результат:
<"{" timestamp ": 1501100448216," status ": 401," error ":" Unauthorized "," message ":" Для доступа к этому ресурсу требуется полная аутентификация "," path ":" / "}]">
Я что-то пропустил?
2 ответа
Попробуйте добавить следующее в ваш тестовый класс:
@TestExecutionListeners(mergeMode = MergeMode.MERGE_WITH_DEFAULTS, listeners = {
WithSecurityContextTestExecutionListener.class
})
И следующая зависимость, если у вас ее нет:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
Для обеспечения безопасности Spring требуется дополнительный прослушиватель, который по умолчанию отсутствует в тестах, поэтому необходимо указать Spring, чтобы добавить его, указав @TestExecutionListeners
аннотация в merge
режим, так что он объединит текущих перечисленных слушателей с слушателями, которых вы хотите добавить - в этом случае WithSecurityContextTestExecutionListener
Вы использовали взломанный пароль, потому что
AuthenticationManager по умолчанию имеет одного пользователя (имя пользователя и случайный пароль, напечатанные на уровне INFO при запуске приложения) doc
Вы можете создать пользовательского пользователя и сделать тест еще раз
@Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("admin").password("passAdmin").roles("USER", "ADMIN").build());
return manager;
}