From d613518fe01f8ecbb97ea79ddca03ec3c11256f9 Mon Sep 17 00:00:00 2001
From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:32:36 -0700
Subject: [PATCH] Use Spring Boot oauth2 resource server. Authentication
works, but roles don't.
---
jpo-conflictvisualizer-api/pom.xml | 4 +
.../dot/its/jpo/ode/api/KeycloakConfig.java | 75 ++++++++-----------
2 files changed, 34 insertions(+), 45 deletions(-)
diff --git a/jpo-conflictvisualizer-api/pom.xml b/jpo-conflictvisualizer-api/pom.xml
index f2edac1dc..03739c3b7 100644
--- a/jpo-conflictvisualizer-api/pom.xml
+++ b/jpo-conflictvisualizer-api/pom.xml
@@ -145,6 +145,10 @@
org.springframework.boot
spring-boot-starter-oauth2-client
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-resource-server
+
diff --git a/jpo-conflictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/KeycloakConfig.java b/jpo-conflictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/KeycloakConfig.java
index 2d63277f8..ab7e3532b 100644
--- a/jpo-conflictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/KeycloakConfig.java
+++ b/jpo-conflictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/KeycloakConfig.java
@@ -3,9 +3,12 @@
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+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.annotation.web.configurers.AbstractHttpConfigurer;
@@ -16,6 +19,7 @@
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.session.SessionManagementFilter;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import static org.springframework.security.config.Customizer.withDefaults;
@@ -50,36 +54,18 @@ public class KeycloakConfig {
@Value("${keycloak.client-secret}")
private String clientSecret;
- @Bean
- public ClientRegistrationRepository clientRepository() {
- ClientRegistration keycloak = keycloakClientRegistration();
- return new InMemoryClientRegistrationRepository(keycloak);
- }
-
- private ClientRegistration keycloakClientRegistration() {
-
-
-
-
- var registration = ClientRegistration
- .withRegistrationId(realm)
- .clientId(resource)
- .clientSecret(clientSecret)
- .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
- .issuerUri(authServer + "/realms/" + realm)
- .redirectUri(redirectServer)
- .authorizationUri(authServer + "/realms/" + realm + "/protocol/openid-connect/auth")
- .tokenUri(authServer + "/realms/" + realm + "/protocol/openid-connect/token")
- .userInfoUri(authServer + "/realms/" + realm + "/protocol/openid-connect/userinfo")
- .userInfoAuthenticationMethod(AuthenticationMethod.HEADER)
- .build();
+ // This condition allows for disabling security
+// @ConditionalOnProperty(prefix = "security",
+// name = "enabled",
+// havingValue = "true")
+// @EnableMethodSecurity(prePostEnabled = true, jsr250Enabled = true) // Allow @PreAuthorize and @RoleAllowed annotations
+// static class Dummy {
+// public Dummy(){
+// System.out.println("Initializing Security");
+// }
+//
+// }
- System.out.println("Client Registration");
- System.out.println(registration);
-
- return registration;
-
- }
@Bean
CorsFilter corsFilter() {
@@ -95,14 +81,14 @@ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws
return httpSecurity
.addFilterBefore(corsFilter(), SessionManagementFilter.class)
.csrf(AbstractHttpConfigurer::disable)
- .authorizeHttpRequests(request -> {
- //request.requestMatchers("/**").permitAll();
- request.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll(); // Allow CORS preflight to fail
- request.anyRequest().authenticated();
- }
+ .authorizeHttpRequests(request -> request
+ .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Allow CORS preflight
+ .anyRequest().authenticated()
)
- .oauth2Client(withDefaults())
+ .oauth2ResourceServer(rs -> rs.jwt(withDefaults()))
.build();
+
+
}else{
System.out.println("Running without KeyCloak Authentication");
return httpSecurity
@@ -118,21 +104,20 @@ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws
-
+ // Keycloak admin client used for email
@Bean
public Keycloak keyCloakBuilder() {
System.out.println("Auth Server: " + authServer);
System.out.println("Realm: " + realm);
System.out.println("Resource: " + resource);
- Keycloak keycloak = KeycloakBuilder.builder()
- .serverUrl(authServer)
- .grantType("password")
- .realm("master")
- .clientId("admin-cli")
- .username(username)
- .password(password)
- .build();
- return keycloak;
+ return KeycloakBuilder.builder()
+ .serverUrl(authServer)
+ .grantType("password")
+ .realm("master")
+ .clientId("admin-cli")
+ .username(username)
+ .password(password)
+ .build();
}