From f17bb858373a29d1247a6ea4349323434eae278c Mon Sep 17 00:00:00 2001 From: zak905 Date: Mon, 1 Jan 2024 20:47:43 +0100 Subject: [PATCH] upgrade project dependencies (including keycloak to 23.0.3) and refractor --- api-key-module/pom.xml | 10 ++----- .../providers/ApiKeyResourceProvider.java | 7 ++--- .../ApiKeyResourceProviderFactory.java | 14 +++------- .../RegisterEventListenerProvider.java | 25 ++++++----------- .../RegisterEventListenerProviderFactory.java | 10 +++---- .../providers/SESEmailSenderProvider.java | 5 +--- .../SESEmailSenderProviderFactory.java | 10 +++---- .../gwidgets/resources/ApiKeyResource.java | 27 ++++++++----------- dashboard-service/Dockerfile | 2 +- dashboard-service/pom.xml | 7 ++--- .../gwidgets/DashboardServiceApplication.java | 8 ++++++ .../com/gwidgets/SecurityConfiguration.java | 15 +++-------- docker-compose.yaml | 2 +- rest-api-service/Dockerfile | 2 +- rest-api-service/index.js | 1 + rest-api-service/package.json | 2 +- 16 files changed, 53 insertions(+), 94 deletions(-) diff --git a/api-key-module/pom.xml b/api-key-module/pom.xml index a4e6553..ce341ba 100644 --- a/api-key-module/pom.xml +++ b/api-key-module/pom.xml @@ -10,7 +10,7 @@ 11 - 21.0.1 + 23.0.3 @@ -32,16 +32,10 @@ ${keycloak.version} provided - - org.jboss.spec.javax.ws.rs - jboss-jaxrs-api_2.0_spec - 1.0.0.Final - provided - com.amazonaws aws-java-sdk-ses - 1.11.538 + 1.12.472 diff --git a/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProvider.java b/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProvider.java index 5272c8d..bf91bab 100644 --- a/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProvider.java +++ b/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProvider.java @@ -6,8 +6,7 @@ import org.keycloak.services.resource.RealmResourceProvider; public class ApiKeyResourceProvider implements RealmResourceProvider { - - private KeycloakSession session; + private final KeycloakSession session; public ApiKeyResourceProvider(KeycloakSession session) { this.session = session; @@ -17,7 +16,5 @@ public class ApiKeyResourceProvider implements RealmResourceProvider { return new ApiKeyResource(session); } - public void close() { - - } + public void close() {} } diff --git a/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProviderFactory.java b/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProviderFactory.java index 056faca..432cabf 100644 --- a/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProviderFactory.java +++ b/api-key-module/src/main/java/com/gwidgets/providers/ApiKeyResourceProviderFactory.java @@ -8,23 +8,15 @@ import org.keycloak.services.resource.RealmResourceProviderFactory; public class ApiKeyResourceProviderFactory implements RealmResourceProviderFactory { - public RealmResourceProvider create(KeycloakSession session) { return new ApiKeyResourceProvider(session); } - public void init(Config.Scope config) { + public void init(Config.Scope config) {} + public void postInit(KeycloakSessionFactory factory) {} - } - - public void postInit(KeycloakSessionFactory factory) { - - } - - public void close() { - - } + public void close() {} public String getId() { return "check"; diff --git a/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProvider.java b/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProvider.java index 035693d..57d6e81 100644 --- a/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProvider.java +++ b/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProvider.java @@ -1,9 +1,7 @@ package com.gwidgets.providers; -import java.util.Objects; -import java.util.UUID; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; import org.keycloak.common.util.SecretGenerator; import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.events.Event; @@ -13,22 +11,18 @@ import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RealmProvider; import org.keycloak.models.jpa.entities.UserAttributeEntity; import org.keycloak.models.jpa.entities.UserEntity; -public class RegisterEventListenerProvider implements EventListenerProvider { +import java.util.Objects; +import java.util.UUID; - private KeycloakSession session; - private RealmProvider model; - //keycloak utility to generate random strings, anything can be used e.g UUID,.. - private SecretGenerator secretGenerator; - private EntityManager entityManager; +public class RegisterEventListenerProvider implements EventListenerProvider { + //keycloak utility to generate random strings, anything can be used e.g. UUID,... + private final SecretGenerator secretGenerator; + private final EntityManager entityManager; public RegisterEventListenerProvider(KeycloakSession session) { - this.session = session; - this.model = session.realms(); this.entityManager = session.getProvider(JpaConnectionProvider.class).getEntityManager(); this.secretGenerator = SecretGenerator.getInstance(); } @@ -36,7 +30,6 @@ public class RegisterEventListenerProvider implements EventListenerProvider { public void onEvent(Event event) { //we are only interested in the register event if (event.getType().equals(EventType.REGISTER)) { - RealmModel realm = model.getRealm(event.getRealmId()); String userId = event.getUserId(); addApiKeyAttribute(userId); } @@ -66,7 +59,5 @@ public class RegisterEventListenerProvider implements EventListenerProvider { } @Override - public void close() { - - } + public void close() {} } diff --git a/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProviderFactory.java b/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProviderFactory.java index be9db66..217e34a 100644 --- a/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProviderFactory.java +++ b/api-key-module/src/main/java/com/gwidgets/providers/RegisterEventListenerProviderFactory.java @@ -12,15 +12,11 @@ public class RegisterEventListenerProviderFactory implements EventListenerProvid return new RegisterEventListenerProvider(keycloakSession); } - public void init(Config.Scope scope) { - } + public void init(Config.Scope scope) {} - public void postInit(KeycloakSessionFactory keycloakSessionFactory) { + public void postInit(KeycloakSessionFactory keycloakSessionFactory) {} - } - - public void close() { - } + public void close() {} public String getId() { return "api-key-registration-generation"; diff --git a/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProvider.java b/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProvider.java index e8c0b7e..cfc44dd 100644 --- a/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProvider.java +++ b/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProvider.java @@ -31,7 +31,6 @@ public class SESEmailSenderProvider implements EmailSenderProvider { @Override public void send(Map config, String address, String subject, String textBody, String htmlBody) throws EmailException { - log.info("attempting to send email using aws ses for " + address); Message message = new Message().withSubject(new Content().withData(subject)) @@ -47,7 +46,5 @@ public class SESEmailSenderProvider implements EmailSenderProvider { } @Override - public void close() { - - } + public void close() {} } diff --git a/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProviderFactory.java b/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProviderFactory.java index 8010efa..4d1a56f 100644 --- a/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProviderFactory.java +++ b/api-key-module/src/main/java/com/gwidgets/providers/SESEmailSenderProviderFactory.java @@ -16,7 +16,6 @@ public class SESEmailSenderProviderFactory implements EmailSenderProviderFactory @Override public EmailSenderProvider create(KeycloakSession session) { - //using singleton pattern to avoid creating the client each time create is called if (sesClientInstance == null) { String awsRegion = Objects.requireNonNull(System.getenv("AWS_REGION")); @@ -32,16 +31,13 @@ public class SESEmailSenderProviderFactory implements EmailSenderProviderFactory } @Override - public void init(Scope config) { - - } + public void init(Scope config) {} @Override - public void postInit(KeycloakSessionFactory factory) { } + public void postInit(KeycloakSessionFactory factory) {} @Override - public void close() { - } + public void close() {} @Override public String getId() { diff --git a/api-key-module/src/main/java/com/gwidgets/resources/ApiKeyResource.java b/api-key-module/src/main/java/com/gwidgets/resources/ApiKeyResource.java index 08c7d1c..e6efcf3 100644 --- a/api-key-module/src/main/java/com/gwidgets/resources/ApiKeyResource.java +++ b/api-key-module/src/main/java/com/gwidgets/resources/ApiKeyResource.java @@ -1,32 +1,27 @@ package com.gwidgets.resources; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.Provider; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.UserModel; - -import javax.ws.rs.GET; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.Objects; -import java.util.stream.Stream; +@Provider public class ApiKeyResource { - private KeycloakSession session; - - private final String realmName; + private final KeycloakSession session; public ApiKeyResource(KeycloakSession session) { this.session = session; - String envRealmName = System.getenv("REALM_NAME"); - this.realmName = Objects.isNull(envRealmName) || Objects.equals(System.getenv(envRealmName), "")? "example": envRealmName; } @GET @Produces("application/json") public Response checkApiKey(@QueryParam("apiKey") String apiKey) { - Stream result = session.users().searchForUserByUserAttributeStream(session.realms().getRealm(realmName), "api-key", apiKey); - return result.count() > 0 ? Response.ok().type(MediaType.APPLICATION_JSON).build(): Response.status(401).type(MediaType.APPLICATION_JSON).build(); + return session.users().searchForUserByUserAttributeStream(session.getContext().getRealm(), "api-key", apiKey) + .findFirst().isPresent() ? Response.ok().type(MediaType.APPLICATION_JSON).build(): + Response.status(401).type(MediaType.APPLICATION_JSON).build(); } } diff --git a/dashboard-service/Dockerfile b/dashboard-service/Dockerfile index 7e9e5dc..112d723 100644 --- a/dashboard-service/Dockerfile +++ b/dashboard-service/Dockerfile @@ -9,7 +9,7 @@ #RUN mvn clean package -FROM openjdk:11-jre-slim +FROM openjdk:17-alpine ARG VERSION=0.1 diff --git a/dashboard-service/pom.xml b/dashboard-service/pom.xml index c879e71..ae88056 100644 --- a/dashboard-service/pom.xml +++ b/dashboard-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.0.RELEASE + 2.7.18 com.gwidgets @@ -15,8 +15,8 @@ Demo project for Spring Boot - 11 - 21.0.1 + 17 + 23.0.3 @@ -56,6 +56,7 @@ org.springframework.boot spring-boot-maven-plugin + 2.7.18 diff --git a/dashboard-service/src/main/java/com/gwidgets/DashboardServiceApplication.java b/dashboard-service/src/main/java/com/gwidgets/DashboardServiceApplication.java index 3119267..2dd8047 100644 --- a/dashboard-service/src/main/java/com/gwidgets/DashboardServiceApplication.java +++ b/dashboard-service/src/main/java/com/gwidgets/DashboardServiceApplication.java @@ -1,11 +1,19 @@ package com.gwidgets; +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; @SpringBootApplication public class DashboardServiceApplication { public static void main(String[] args) { SpringApplication.run(DashboardServiceApplication.class, args); } + + @Bean + public KeycloakConfigResolver keycloakConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } } \ No newline at end of file diff --git a/dashboard-service/src/main/java/com/gwidgets/SecurityConfiguration.java b/dashboard-service/src/main/java/com/gwidgets/SecurityConfiguration.java index 0fac5f3..68f1c6a 100644 --- a/dashboard-service/src/main/java/com/gwidgets/SecurityConfiguration.java +++ b/dashboard-service/src/main/java/com/gwidgets/SecurityConfiguration.java @@ -1,9 +1,8 @@ package com.gwidgets; -import java.security.Principal; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.springboot.KeycloakSpringBootProperties; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; @@ -22,20 +21,14 @@ import org.springframework.security.web.authentication.session.SessionAuthentica import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; -import org.keycloak.adapters.springboot.KeycloakSpringBootProperties; + +import java.security.Principal; @EnableConfigurationProperties(KeycloakSpringBootProperties.class) @KeycloakConfiguration public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { - - @Bean - public KeycloakConfigResolver keycloakConfigResolver() { - return new KeycloakSpringBootConfigResolver(); - } - @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); @@ -45,7 +38,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) { - KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper(); @@ -65,7 +57,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter @Bean @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public KeycloakSecurityContext getKeycloakSecurityContext() { - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); Principal principal = attributes.getRequest().getUserPrincipal(); if (principal == null) { diff --git a/docker-compose.yaml b/docker-compose.yaml index ef83ce0..8b04419 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,7 +1,7 @@ version: '3.8' services: auth-server: - image: quay.io/keycloak/keycloak:21.0.1 + image: quay.io/keycloak/keycloak:23.0.3 environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin diff --git a/rest-api-service/Dockerfile b/rest-api-service/Dockerfile index 198eb2b..d644370 100644 --- a/rest-api-service/Dockerfile +++ b/rest-api-service/Dockerfile @@ -1,4 +1,4 @@ -FROM node:11-alpine +FROM node:14-alpine COPY index.js . COPY package.json . diff --git a/rest-api-service/index.js b/rest-api-service/index.js index 1835cf6..577b17d 100644 --- a/rest-api-service/index.js +++ b/rest-api-service/index.js @@ -13,6 +13,7 @@ app.use(function (req, res, next) { console.log(`checking api key ${apiKey}, auth server ${authServer}`) http.get("http://"+authServer+"/auth/realms/"+realmName+"/check?apiKey="+apiKey, (authResponse) => { + console.log(`received ${authResponse.statusCode} status from Keycloak`) if (authResponse.statusCode == 200) { next() } else { diff --git a/rest-api-service/package.json b/rest-api-service/package.json index 2dc0c64..ca2e797 100644 --- a/rest-api-service/package.json +++ b/rest-api-service/package.json @@ -9,7 +9,7 @@ "author": "", "license": "ISC", "dependencies": { - "express": "^4.17.1", + "express": "^4.17.3", "http": "0.0.0" }, "devDependencies": {}