diff --git a/src/main/java/dev/sultanov/keycloak/multitenancy/resource/AbstractAdminResource.java b/src/main/java/dev/sultanov/keycloak/multitenancy/resource/AbstractAdminResource.java index b057e1f..ae60242 100644 --- a/src/main/java/dev/sultanov/keycloak/multitenancy/resource/AbstractAdminResource.java +++ b/src/main/java/dev/sultanov/keycloak/multitenancy/resource/AbstractAdminResource.java @@ -10,6 +10,8 @@ import java.lang.reflect.Type; import org.keycloak.Config; import org.keycloak.connections.jpa.JpaConnectionProvider; +import org.keycloak.http.HttpRequest; +import org.keycloak.http.HttpResponse; import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.JWSInputException; import org.keycloak.models.ClientModel; @@ -21,6 +23,7 @@ import org.keycloak.services.managers.AppAuthManager.BearerTokenAuthenticator; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.RealmManager; +import org.keycloak.services.resources.Cors; import org.keycloak.services.resources.admin.AdminAuth; import org.keycloak.services.resources.admin.AdminEventBuilder; @@ -47,6 +50,18 @@ private void setup() { setupAuth(); setupEvents(); setupProvider(); + setupCors(); + } + + private void setupCors() { + HttpRequest request = session.getContext().getHttpRequest(); + HttpResponse response = session.getContext().getHttpResponse(); + Cors.add(request) + .allowedOrigins(auth.getToken()) + .allowedMethods(CorsResource.METHODS) + .exposedHeaders("Location") + .auth() + .build(response); } private void setupAuth() { @@ -120,4 +135,4 @@ protected final void setupProvider() { this.tenantProvider = session.getProvider(TenantProvider.class); } -} \ No newline at end of file +} diff --git a/src/main/java/dev/sultanov/keycloak/multitenancy/resource/CorsResource.java b/src/main/java/dev/sultanov/keycloak/multitenancy/resource/CorsResource.java new file mode 100644 index 0000000..a05d8fe --- /dev/null +++ b/src/main/java/dev/sultanov/keycloak/multitenancy/resource/CorsResource.java @@ -0,0 +1,26 @@ +package dev.sultanov.keycloak.multitenancy.resource; + +import jakarta.ws.rs.OPTIONS; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; +import org.keycloak.http.HttpRequest; +import org.keycloak.services.resources.Cors; + +public class CorsResource { + + public static final String[] METHODS = { + "GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS" + }; + + private final HttpRequest request; + + public CorsResource(HttpRequest request) { + this.request = request; + } + + @OPTIONS + @Path("{any:.*}") + public Response preflight() { + return Cors.add(request, Response.ok()).auth().allowedMethods(METHODS).preflight().build(); + } +} diff --git a/src/main/java/dev/sultanov/keycloak/multitenancy/resource/TenantsResourceProvider.java b/src/main/java/dev/sultanov/keycloak/multitenancy/resource/TenantsResourceProvider.java index 84cdcb7..1273c2a 100644 --- a/src/main/java/dev/sultanov/keycloak/multitenancy/resource/TenantsResourceProvider.java +++ b/src/main/java/dev/sultanov/keycloak/multitenancy/resource/TenantsResourceProvider.java @@ -1,5 +1,6 @@ package dev.sultanov.keycloak.multitenancy.resource; +import org.keycloak.http.HttpRequest; import org.keycloak.models.KeycloakSession; import org.keycloak.services.resource.RealmResourceProvider; @@ -13,7 +14,12 @@ public TenantsResourceProvider(KeycloakSession session) { @Override public Object getResource() { - return new TenantsResource(session); + HttpRequest request = session.getContext().getHttpRequest(); + if (request != null && "OPTIONS".equals(request.getHttpMethod())) { + return new CorsResource(request); + } else { + return new TenantsResource(session); + } } @Override