我有一个使用PCF SSO磁贴由OAuth 2保护的Spring Boot 2应用程序。
如何编写带有Rest Template并启用安全性的集成测试?
这就是我所做的。根据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示例中获得了这一点,它的工作原理就像一个魅力。 此时,由于以下原因,我想测试由OAuth2保护的APi:
我的集成测试因未授权用户而失败。 这是我到目前为止尝试过的:
@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;
}
}