From 127ded4e88afcd4dc9f61597c9e5c213825e4646 Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Fri, 9 Feb 2024 13:54:49 +0100
Subject: [PATCH] OZG-4939 Security with basic SecurityFilterChain

---
 pom.xml                                       | 13 +++
 .../admin/security/SecurityConfiguration.java | 82 +++++++++++++++++++
 src/main/resources/application.yaml           |  7 +-
 3 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java

diff --git a/pom.xml b/pom.xml
index 62e2687c..c2d2b74d 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 00000000..caf43f7d
--- /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 c80bcec7..b8a9219d 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
-- 
GitLab