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(); }