У меня есть приложение Spring Boot 2, защищенное с помощью OAuth 2 с использованием плитки единого входа PCF.
Как мне написать интеграционный тест с шаблоном отдыха и включенной защитой?
Вот что я сделал.Согласно документации PCF и передовой практике, я расширяю ResourceServerConfigurerAdapter.Файл конфигурации выглядит следующим образом:
@Configuration
public class SSOConfig {
private static final String PATH_FORMAT = "%s%s";
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
@Configuration
@EnableWebSecurity
@EnableResourceServer
@Profile({"sso","it"})
static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private ObjectProvider<WebEndpointProperties> webEndpointProperties;
@Autowired
private ObjectProvider<ManagementServerProperties> managementServerProperties;
@Value("${server.servlet.context-path:/}")
private String serverContextPath;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.stateless(true).resourceId("protected-myresource");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.cors().disable().csrf().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll().antMatchers(getBypassSecurityUris())
.permitAll().anyRequest().authenticated();
}
private String[] getBypassSecurityUris() {
return new String[] { prependContextPath(getActuatorRoot())};
}
private String prependContextPath(String path) {
return StringUtils.equals(this.serverContextPath, "/") ? path
: String.format(PATH_FORMAT, this.serverContextPath, path);
}
private String getActuatorRoot() {
return String.format(PATH_FORMAT,
this.managementServerProperties.getIfAvailable(ManagementServerProperties::new).getServlet()
.getContextPath(),
this.webEndpointProperties.getIfAvailable(WebEndpointProperties::new).getBasePath());
}
}
}
Я получил это из некоторого примера PCF, и он работает как шарм.На данный момент я хочу протестировать мой APi, защищенный с помощью OAuth2, однако, поскольку:
- В моих интеграционных тестах у меня нет сервера OAuth И
- Spring Boot 2 небольше не разрешать вам отключать аутентификацию (если вы не используете MockMvc);
мой тест интеграции не пройден с неавторизованным пользователем.Это то, что я пробовал до сих пор:
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 8077)
@ActiveProfiles("it")
public class MyApiIntegrationTest {
@LocalServerPort
private int port;
TestRestTemplate restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
@Test
public void testGetStatus() throws Exception {
String jwtToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
stubFor(get("/token").willReturn(okJson(jwtToken)));
stubFor(get("/token_key").willReturn(okJson("")));
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.AUTHORIZATION, jwtToken);
ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/myapi"), HttpMethod.GET, new HttpEntity<>(headers), String.class);
String expected = "{\"MY_STRING\"}";
JSONAssert.assertEquals(expected, response.getBody(), false);
}
private String createURLWithPort(String uri) {
return "http://localhost:" + port + uri;
}
}