upgrade project dependencies (including keycloak to 23.0.3) and refractor

This commit is contained in:
zak905 2024-01-01 20:47:43 +01:00 committed by Zakaria Amine
parent 1838975ab1
commit f17bb85837
16 changed files with 53 additions and 94 deletions

View file

@ -10,7 +10,7 @@
<properties> <properties>
<java.version>11</java.version> <java.version>11</java.version>
<keycloak.version>21.0.1</keycloak.version> <keycloak.version>23.0.3</keycloak.version>
</properties> </properties>
<dependencies> <dependencies>
@ -32,16 +32,10 @@
<version>${keycloak.version}</version> <version>${keycloak.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>com.amazonaws</groupId> <groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-ses</artifactId> <artifactId>aws-java-sdk-ses</artifactId>
<version>1.11.538</version> <version>1.12.472</version>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -6,8 +6,7 @@ import org.keycloak.services.resource.RealmResourceProvider;
public class ApiKeyResourceProvider implements RealmResourceProvider { public class ApiKeyResourceProvider implements RealmResourceProvider {
private final KeycloakSession session;
private KeycloakSession session;
public ApiKeyResourceProvider(KeycloakSession session) { public ApiKeyResourceProvider(KeycloakSession session) {
this.session = session; this.session = session;
@ -17,7 +16,5 @@ public class ApiKeyResourceProvider implements RealmResourceProvider {
return new ApiKeyResource(session); return new ApiKeyResource(session);
} }
public void close() { public void close() {}
}
} }

View file

@ -8,23 +8,15 @@ import org.keycloak.services.resource.RealmResourceProviderFactory;
public class ApiKeyResourceProviderFactory implements RealmResourceProviderFactory { public class ApiKeyResourceProviderFactory implements RealmResourceProviderFactory {
public RealmResourceProvider create(KeycloakSession session) { public RealmResourceProvider create(KeycloakSession session) {
return new ApiKeyResourceProvider(session); return new ApiKeyResourceProvider(session);
} }
public void init(Config.Scope config) { public void init(Config.Scope config) {}
public void postInit(KeycloakSessionFactory factory) {}
} public void close() {}
public void postInit(KeycloakSessionFactory factory) {
}
public void close() {
}
public String getId() { public String getId() {
return "check"; return "check";

View file

@ -1,9 +1,7 @@
package com.gwidgets.providers; package com.gwidgets.providers;
import java.util.Objects; import jakarta.persistence.EntityManager;
import java.util.UUID;
import javax.persistence.EntityManager;
import org.keycloak.common.util.SecretGenerator; import org.keycloak.common.util.SecretGenerator;
import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.connections.jpa.JpaConnectionProvider;
import org.keycloak.events.Event; 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.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.KeycloakSession; 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.UserAttributeEntity;
import org.keycloak.models.jpa.entities.UserEntity; import org.keycloak.models.jpa.entities.UserEntity;
public class RegisterEventListenerProvider implements EventListenerProvider { import java.util.Objects;
import java.util.UUID;
private KeycloakSession session; public class RegisterEventListenerProvider implements EventListenerProvider {
private RealmProvider model; //keycloak utility to generate random strings, anything can be used e.g. UUID,...
//keycloak utility to generate random strings, anything can be used e.g UUID,.. private final SecretGenerator secretGenerator;
private SecretGenerator secretGenerator; private final EntityManager entityManager;
private EntityManager entityManager;
public RegisterEventListenerProvider(KeycloakSession session) { public RegisterEventListenerProvider(KeycloakSession session) {
this.session = session;
this.model = session.realms();
this.entityManager = session.getProvider(JpaConnectionProvider.class).getEntityManager(); this.entityManager = session.getProvider(JpaConnectionProvider.class).getEntityManager();
this.secretGenerator = SecretGenerator.getInstance(); this.secretGenerator = SecretGenerator.getInstance();
} }
@ -36,7 +30,6 @@ public class RegisterEventListenerProvider implements EventListenerProvider {
public void onEvent(Event event) { public void onEvent(Event event) {
//we are only interested in the register event //we are only interested in the register event
if (event.getType().equals(EventType.REGISTER)) { if (event.getType().equals(EventType.REGISTER)) {
RealmModel realm = model.getRealm(event.getRealmId());
String userId = event.getUserId(); String userId = event.getUserId();
addApiKeyAttribute(userId); addApiKeyAttribute(userId);
} }
@ -66,7 +59,5 @@ public class RegisterEventListenerProvider implements EventListenerProvider {
} }
@Override @Override
public void close() { public void close() {}
}
} }

View file

@ -12,15 +12,11 @@ public class RegisterEventListenerProviderFactory implements EventListenerProvid
return new RegisterEventListenerProvider(keycloakSession); 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() { public String getId() {
return "api-key-registration-generation"; return "api-key-registration-generation";

View file

@ -31,7 +31,6 @@ public class SESEmailSenderProvider implements EmailSenderProvider {
@Override @Override
public void send(Map<String, String> config, String address, String subject, String textBody, String htmlBody) throws EmailException { public void send(Map<String, String> config, String address, String subject, String textBody, String htmlBody) throws EmailException {
log.info("attempting to send email using aws ses for " + address); log.info("attempting to send email using aws ses for " + address);
Message message = new Message().withSubject(new Content().withData(subject)) Message message = new Message().withSubject(new Content().withData(subject))
@ -47,7 +46,5 @@ public class SESEmailSenderProvider implements EmailSenderProvider {
} }
@Override @Override
public void close() { public void close() {}
}
} }

View file

@ -16,7 +16,6 @@ public class SESEmailSenderProviderFactory implements EmailSenderProviderFactory
@Override @Override
public EmailSenderProvider create(KeycloakSession session) { public EmailSenderProvider create(KeycloakSession session) {
//using singleton pattern to avoid creating the client each time create is called //using singleton pattern to avoid creating the client each time create is called
if (sesClientInstance == null) { if (sesClientInstance == null) {
String awsRegion = Objects.requireNonNull(System.getenv("AWS_REGION")); String awsRegion = Objects.requireNonNull(System.getenv("AWS_REGION"));
@ -32,16 +31,13 @@ public class SESEmailSenderProviderFactory implements EmailSenderProviderFactory
} }
@Override @Override
public void init(Scope config) { public void init(Scope config) {}
}
@Override @Override
public void postInit(KeycloakSessionFactory factory) { } public void postInit(KeycloakSessionFactory factory) {}
@Override @Override
public void close() { public void close() {}
}
@Override @Override
public String getId() { public String getId() {

View file

@ -1,32 +1,27 @@
package com.gwidgets.resources; 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.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 { public class ApiKeyResource {
private KeycloakSession session; private final KeycloakSession session;
private final String realmName;
public ApiKeyResource(KeycloakSession session) { public ApiKeyResource(KeycloakSession session) {
this.session = session; this.session = session;
String envRealmName = System.getenv("REALM_NAME");
this.realmName = Objects.isNull(envRealmName) || Objects.equals(System.getenv(envRealmName), "")? "example": envRealmName;
} }
@GET @GET
@Produces("application/json") @Produces("application/json")
public Response checkApiKey(@QueryParam("apiKey") String apiKey) { public Response checkApiKey(@QueryParam("apiKey") String apiKey) {
Stream<UserModel> result = session.users().searchForUserByUserAttributeStream(session.realms().getRealm(realmName), "api-key", apiKey); return session.users().searchForUserByUserAttributeStream(session.getContext().getRealm(), "api-key", apiKey)
return result.count() > 0 ? Response.ok().type(MediaType.APPLICATION_JSON).build(): Response.status(401).type(MediaType.APPLICATION_JSON).build(); .findFirst().isPresent() ? Response.ok().type(MediaType.APPLICATION_JSON).build():
Response.status(401).type(MediaType.APPLICATION_JSON).build();
} }
} }

View file

@ -9,7 +9,7 @@
#RUN mvn clean package #RUN mvn clean package
FROM openjdk:11-jre-slim FROM openjdk:17-alpine
ARG VERSION=0.1 ARG VERSION=0.1

View file

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version> <version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.gwidgets</groupId> <groupId>com.gwidgets</groupId>
@ -15,8 +15,8 @@
<description>Demo project for Spring Boot</description> <description>Demo project for Spring Boot</description>
<properties> <properties>
<java.version>11</java.version> <java.version>17</java.version>
<keycloak.version>21.0.1</keycloak.version> <keycloak.version>23.0.3</keycloak.version>
</properties> </properties>
<dependencies> <dependencies>
@ -56,6 +56,7 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.18</version>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>

View file

@ -1,11 +1,19 @@
package com.gwidgets; package com.gwidgets;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication @SpringBootApplication
public class DashboardServiceApplication { public class DashboardServiceApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(DashboardServiceApplication.class, args); SpringApplication.run(DashboardServiceApplication.class, args);
} }
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
} }

View file

@ -1,9 +1,8 @@
package com.gwidgets; package com.gwidgets;
import java.security.Principal;
import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext; 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.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; 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.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; 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) @EnableConfigurationProperties(KeycloakSpringBootProperties.class)
@KeycloakConfiguration @KeycloakConfiguration
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
super.configure(http); super.configure(http);
@ -45,7 +38,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
@Autowired @Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) { public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper(); SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
@ -65,7 +57,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
@Bean @Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public KeycloakSecurityContext getKeycloakSecurityContext() { public KeycloakSecurityContext getKeycloakSecurityContext() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
Principal principal = attributes.getRequest().getUserPrincipal(); Principal principal = attributes.getRequest().getUserPrincipal();
if (principal == null) { if (principal == null) {

View file

@ -1,7 +1,7 @@
version: '3.8' version: '3.8'
services: services:
auth-server: auth-server:
image: quay.io/keycloak/keycloak:21.0.1 image: quay.io/keycloak/keycloak:23.0.3
environment: environment:
KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin KEYCLOAK_ADMIN_PASSWORD: admin

View file

@ -1,4 +1,4 @@
FROM node:11-alpine FROM node:14-alpine
COPY index.js . COPY index.js .
COPY package.json . COPY package.json .

View file

@ -13,6 +13,7 @@ app.use(function (req, res, next) {
console.log(`checking api key ${apiKey}, auth server ${authServer}`) console.log(`checking api key ${apiKey}, auth server ${authServer}`)
http.get("http://"+authServer+"/auth/realms/"+realmName+"/check?apiKey="+apiKey, (authResponse) => { http.get("http://"+authServer+"/auth/realms/"+realmName+"/check?apiKey="+apiKey, (authResponse) => {
console.log(`received ${authResponse.statusCode} status from Keycloak`)
if (authResponse.statusCode == 200) { if (authResponse.statusCode == 200) {
next() next()
} else { } else {

View file

@ -9,7 +9,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.17.1", "express": "^4.17.3",
"http": "0.0.0" "http": "0.0.0"
}, },
"devDependencies": {} "devDependencies": {}