diff --git a/pom.xml b/pom.xml index 6da03db8e519852461e906b56e32e0ded7e26d1d..fc23b61af4e0e3d21cd366e09707f26e8efce38f 100644 --- a/pom.xml +++ b/pom.xml @@ -40,10 +40,6 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java index a0d414ec0f8b44661bc2a9dd1dda47983f17eb66..e9948c36a99efc62d6d03c533da3971a5c515438 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/ApiClientConfiguration.java @@ -18,8 +18,12 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.endpoint.RestClientClientCredentialsTokenResponseClient; import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; +import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; import org.springframework.security.oauth2.client.web.client.OAuth2ClientHttpRequestInterceptor; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -30,29 +34,31 @@ import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi; import lombok.RequiredArgsConstructor; @Configuration -@EnableWebSecurity @RequiredArgsConstructor @ConditionalOnProperty(prefix = Osi2PostfachProperties.PREFIX, name = "enabled", havingValue = "true") public class ApiClientConfiguration { + private final Osi2PostfachProperties.AuthConfiguration authConfiguration; private final Osi2PostfachProperties.ApiConfiguration apiConfiguration; private final Osi2PostfachProperties.ProxyConfiguration proxyConfiguration; + private static final String CLIENT_REGISTRATION_ID = "osi2"; + @Bean MessageExchangeApi messageExchangeApi(ApiClient apiClient) { return new MessageExchangeApi(apiClient); } @Bean - ApiClient apiClient(ClientRegistrationRepository clientRegistrations) { - var apiClient = new ApiClient(restClient(clientRegistrations)); + ApiClient apiClient() { + var apiClient = new ApiClient(restClient()); apiClient.setBasePath(apiConfiguration.getUrl()); return apiClient; } - private RestClient restClient(ClientRegistrationRepository clientRegistrations) { - var requestInterceptor = new OAuth2ClientHttpRequestInterceptor(authorizedClientManager(clientRegistrations)); - requestInterceptor.setClientRegistrationIdResolver(request -> "osi2"); + private RestClient restClient() { + var requestInterceptor = new OAuth2ClientHttpRequestInterceptor(authorizedClientManager()); + requestInterceptor.setClientRegistrationIdResolver(request -> CLIENT_REGISTRATION_ID); return defaultRestClientBuilder() .requestInterceptor(requestInterceptor) @@ -88,8 +94,8 @@ public class ApiClientConfiguration { return credentialsProvider; } - private AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager( - ClientRegistrationRepository clientRegistrations) { + private AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager() { + var clientRegistrations = clientRegistrationsRepository(); var clientService = new InMemoryOAuth2AuthorizedClientService( clientRegistrations); var authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager( @@ -100,6 +106,21 @@ public class ApiClientConfiguration { return authorizedClientManager; } + private ClientRegistrationRepository clientRegistrationsRepository() { + return new InMemoryClientRegistrationRepository(osi2ClientRegistration()); + } + + private ClientRegistration osi2ClientRegistration() { + return ClientRegistration.withRegistrationId(CLIENT_REGISTRATION_ID) + .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .clientId(authConfiguration.getClientId()) + .clientSecret(authConfiguration.getClientSecret()) + .tokenUri(authConfiguration.getTokenUri()) + .scope(authConfiguration.getScope()) + .build(); + } + private OAuth2AuthorizedClientProvider authorizedClientProvider() { return OAuth2AuthorizedClientProviderBuilder.builder() .clientCredentials(builder -> @@ -130,7 +151,7 @@ public class ApiClientConfiguration { client.addParametersConverter(source -> { MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); // Pass a resource indicator parameter https://datatracker.ietf.org/doc/html/rfc8707 - parameters.add("resource", apiConfiguration.getResource()); + parameters.add("resource", authConfiguration.getResource()); return parameters; }); } diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java index cec943d8ed04fa3a27dffbb491f078e97a4ce3c4..f670ec7a5c42c51c5953aa1703ff2485b1beb3aa 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java @@ -1,5 +1,7 @@ package de.ozgcloud.nachrichten.postfach.osiv2.config; +import java.util.List; + import jakarta.annotation.Nullable; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,6 +23,20 @@ public class Osi2PostfachProperties { private boolean enabled; + @Getter + @Setter + @Configuration + @ConfigurationProperties(prefix = AuthConfiguration.PREFIX) + public static class AuthConfiguration { + public static final String PREFIX = Osi2PostfachProperties.PREFIX + ".auth"; + + private String clientId; + private String clientSecret; + private List<String> scope; + private String tokenUri; + private String resource; + } + @Getter @Setter @Configuration @@ -28,7 +44,6 @@ public class Osi2PostfachProperties { public static class ApiConfiguration { public static final String PREFIX = Osi2PostfachProperties.PREFIX + ".api"; - private String resource; private String url; private String tenant; private String nameIdentifier; diff --git a/src/main/resources/application-stage.yml b/src/main/resources/application-stage.yml index c2804acf5bd4bec3a1e037f7cf334c73b2905050..2618fc516f3b8383f3ad2d4ddfccb4c8c06eeccb 100644 --- a/src/main/resources/application-stage.yml +++ b/src/main/resources/application-stage.yml @@ -1,22 +1,13 @@ -spring: - security: - oauth2: - client: - registration: - osi2: - client-id: 'OZG-Kopfstelle' - client-secret: 'changeme' - scope: default, access_urn:dataport:osi:sh:stage:ozgkopfstelle - authorization-grant-type: 'client_credentials' - client-authentication-method: client_secret_post - provider: - osi2: - token-uri: 'https://idp.serviceportal-stage.schleswig-holstein.de/webidp2/connect/token' ozgcloud: osiv2: enabled: false - api: + auth: + client-id: 'OZG-Kopfstelle' + client-secret: 'changeme' + scope: default, access_urn:dataport:osi:sh:stage:ozgkopfstelle + token-uri: 'https://idp.serviceportal-stage.schleswig-holstein.de/webidp2/connect/token' resource: 'urn:dataport:osi:postfach:rz2:stage:sh' + api: url: 'https://api-gateway-stage.dataport.de:443/api/osi_postfach/1.0.0' tenant: 'SH' name-identifier: 'ozgkopfstelle' diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java index c4f0c35732b3d4889f0198fec5ff0569b74c22df..94405d692b164bdf5d1d3b3c51974274a314d39b 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java @@ -48,11 +48,11 @@ class OsiPostfachRemoteServiceITCase { @DynamicPropertySource static void dynamicProperties(DynamicPropertyRegistry registry) { - registry.add("spring.security.oauth2.client.provider.osi2.token-uri", OSI_MOCK_SERVER_EXTENSION::getAccessTokenUrl); - registry.add("spring.security.oauth2.client.registration.osi2.scope", () -> CLIENT_SCOPES); - registry.add("spring.security.oauth2.client.registration.osi2.client-id", () -> CLIENT_ID); + registry.add("ozgcloud.osiv2.auth.token-uri", OSI_MOCK_SERVER_EXTENSION::getAccessTokenUrl); + registry.add("ozgcloud.osiv2.auth.scope", () -> CLIENT_SCOPES); + registry.add("ozgcloud.osiv2.auth.client-id", () -> CLIENT_ID); registry.add("ozgcloud.osiv2.api.url", OSI_MOCK_SERVER_EXTENSION::getPostfachFacadeUrl); - registry.add("ozgcloud.osiv2.api.resource", () -> RESOURCE_URN); + registry.add("ozgcloud.osiv2.auth.resource", () -> RESOURCE_URN); } private WireMockServer postfachFacadeMockServer; diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java index fd5c11bc956b400822c0dd6064fa7bb4dcc7794d..4bcdb775d291573e8a3ec8f1d503726ff31b878b 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java @@ -31,7 +31,7 @@ class OsiPostfachRemoteServiceRemoteITCase { @DynamicPropertySource static void dynamicProperties(DynamicPropertyRegistry registry) { registry.add( - "spring.security.oauth2.client.registration.osi2.client-secret", + "ozgcloud.osiv2.auth.client-secret", () -> System.getenv("SH_STAGE_CLIENT_SECRET") ); registry.add( diff --git a/src/test/resources/application-dev.yml b/src/test/resources/application-dev.yml index 42c79c97a9e25c34d6547d9dee3b96bbddf5a308..ac690fd234df32535926c332fed7b75b2387df70 100644 --- a/src/test/resources/application-dev.yml +++ b/src/test/resources/application-dev.yml @@ -1,22 +1,13 @@ -spring: - security: - oauth2: - client: - registration: - osi2: - client-id: 'OZG-Kopfstelle' - client-secret: 'changeme' - scope: default, access_urn:dataport:osi:sh:stage:ozgkopfstelle - authorization-grant-type: 'client_credentials' - client-authentication-method: client_secret_post - provider: - osi2: - token-uri: 'http://localhost:8080/osi-postfach-v2-token' ozgcloud: osiv2: enabled: false - api: + auth: + client-id: 'OZG-Kopfstelle' + client-secret: 'changeme' + scope: default, access_urn:dataport:osi:sh:stage:ozgkopfstelle resource: 'urn:dataport:osi:postfach:rz2:stage:sh' + token-uri: 'http://localhost:8080/osi-postfach-v2-token' + api: url: 'http://localhost:8080' tenant: 'SH' name-identifier: 'ozgkopfstelle'