diff --git a/pom.xml b/pom.xml index 62e2687c39b41812950672f5bb68afa3d577128d..c2d2b74d878f33c503605651d53af477b7db72dd 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,14 @@ <artifactId>spring-cloud-config-server</artifactId> <version>${spring-cloud-config-server.version}</version> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> + </dependency> <!-- Dev --> <dependency> @@ -83,6 +91,11 @@ <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-test</artifactId> + <scope>test</scope> + </dependency> </dependencies> <profiles> <profile> diff --git a/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java b/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..caf43f7df508a3f2fa8d9b1e62584144951e6f3d --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch das + * Ministerium für Energiewende, Klimaschutz, Umwelt und Natur Zentrales + * IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald diese von der + * Europäischen Kommission genehmigt wurden - Folgeversionen der EUPL + * ("Lizenz"); Sie dürfen dieses Werk ausschließlich gemäß dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften gefordert oder in + * schriftlicher Form vereinbart, wird die unter der Lizenz verbreitete Software + * "so wie sie ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. Die sprachspezifischen + * Genehmigungen und Beschränkungen unter der Lizenz sind dem Lizenztext zu + * entnehmen. + */ +package de.ozgcloud.admin.security; + +import org.apache.http.HttpHeaders; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@EnableMethodSecurity(securedEnabled = true) +@EnableWebSecurity +public class SecurityConfiguration { + + @Bean + SecurityFilterChain filterChain(HttpSecurity http, ServerProperties serverProperties, @Value("${permit-all:[]}") String[] permitAll) + throws Exception { + + // Configure a resource server with JWT decoder (the customized + // jwtAuthenticationConverter is picked by Spring Boot) + http.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); + + // State-less session (state in access-token only) + http.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + + // Disable CSRF because of state-less session-management + http.csrf(csrf -> csrf.disable()); + + // Return 401 (unauthorized) instead of 302 (redirect to login) when + // authorization is missing or invalid + http.exceptionHandling(eh -> eh.authenticationEntryPoint((request, response, authException) -> { + response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Bearer realm=\"Restricted Content\""); + response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase()); + })); + + // If SSL enabled, disable http (https only) + if (serverProperties.getSsl() != null && serverProperties.getSsl().isEnabled()) { + http.requiresChannel(channel -> channel.anyRequest().requiresSecure()); + } + + // @formatter:off + http.authorizeHttpRequests(requests -> requests + .requestMatchers(HttpMethod.GET, "/api/environment").permitAll() + .requestMatchers("/api").authenticated() + .requestMatchers("/api/**").authenticated() + .requestMatchers("/actuator").permitAll() + .requestMatchers("/actuator/**").permitAll() + .requestMatchers("/configserver/*/*").permitAll() + .requestMatchers("/configserver/*/*/*").permitAll() + .anyRequest().denyAll()); + // @formatter:on + + return http.build(); + } + +} \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index c80bcec75a6c5b2c6f0824b0dd7579b84d8e716f..b8a9219d7fabe6377c5c980c0e8a6e5bf6969ec5 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -5,4 +5,9 @@ spring: cloud: config: server: - prefix: /configserver \ No newline at end of file + prefix: /configserver + security: + oauth2: + resourceserver: + jwt: + issuer-uri: https://sso.dev.by.ozg-cloud.de//realms/by-kiel-dev \ No newline at end of file