I'm using this Okta Spring Boot starter, but I cannot disable the auto configuration for integration testing. Normally, you would do something like this:
@SpringBootTest
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class, OktaOAuth2AutoConfig.class })
class ApplicationTests {
@Test
void contextLoads() {
}
}
However, the OktaOAuth2AutoConfig class is package protected and you cannot disable it. I've tried component scanning filters and a bunch of other techniques, but the problem is that it is still loading and requiring okta.oauth2.issuer
(along with client id and secret) and calling it to make sure it is a valid OAuth2 provider. I don't want this functionality in case the tests have to run somewhere where the auto config can't call the issuer. Any ideas?
You should be able to mock things so OIDC discovery can happen. I show how to do it for a JHipster app in this blog post. Since you're using the Okta Spring Boot starter, I'm guessing you can do something like this.
TestSecurityConfiguration.java
class.@TestConfiguration
public class TestSecurityConfiguration {
private final ClientRegistration clientRegistration;
public TestSecurityConfiguration() {
this.clientRegistration = clientRegistration().build();
}
@Bean
ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(clientRegistration);
}
private ClientRegistration.Builder clientRegistration() {
Map<String, Object> metadata = new HashMap<>();
metadata.put("end_session_endpoint", "https://example.org/logout");
return ClientRegistration.withRegistrationId("okta")
.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.scope("read:user")
.authorizationUri("https://example.org/login/oauth/authorize")
.tokenUri("https://example.org/login/oauth/access_token")
.jwkSetUri("https://example.org/oauth/jwk")
.userInfoUri("https://api.example.org/user")
.providerConfigurationMetadata(metadata)
.userNameAttributeName("id")
.clientName("Client Name")
.clientId("client-id")
.clientSecret("client-secret");
}
@Bean
JwtDecoder jwtDecoder() {
return mock(JwtDecoder.class);
}
@Bean
public OAuth2AuthorizedClientService authorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository(OAuth2AuthorizedClientService authorizedClientService) {
return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
}
}
Then in classes that use @SpringBootTest
, configured this class as a configuration source.
@SpringBootTest(classes = {YourMainApp.class, TestSecurityConfiguration.class})
Another blog post, The Hitchhiker's Guide to Testing Spring Boot APIs and Angular Components with WireMock, Jest, Protractor, and Travis CI, has some additional information on mocking APIs for testing. Specifically, see Mock Okta’s API with WireMock.