Add SAML url attributes to the SecureClientUrisPatternExecutor (#47514)

Closes #46745


Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
Ricardo Martin
2026-03-27 14:53:34 +01:00
committed by GitHub
parent f110573310
commit f2c7c673df
10 changed files with 526 additions and 242 deletions
@@ -9,7 +9,8 @@ public class OAuthTestFrameworkExtension implements TestFrameworkExtension {
@Override
public List<Supplier<?, ?>> suppliers() {
return List.of(new OAuthClientSupplier(), new TestAppSupplier(), new OAuthIdentityProviderSupplier(), new CimdProviderSupplier());
return List.of(new OAuthClientSupplier(), new TestAppSupplier(), new OAuthIdentityProviderSupplier(),
new CimdProviderSupplier(), new SectorIdentifierRedirectUrisSupplier());
}
}
@@ -0,0 +1,50 @@
package org.keycloak.testframework.oauth;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import jakarta.ws.rs.core.Response;
import org.keycloak.util.JsonSerialization;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
/**
*
* @author rmartinc
*/
public class SectorIdentifierRedirectUrisProvider implements Closeable {
public static final String CONTEXT = "/sector-identifier-redirect-uris";
private final HttpServer httpServer;
private final String[] sectorIdentifierRedirectUris;
public SectorIdentifierRedirectUrisProvider(HttpServer httpServer, String[] sectorIdentifierRedirectUris) {
this.httpServer = httpServer;
this.sectorIdentifierRedirectUris = sectorIdentifierRedirectUris;
this.httpServer.createContext(CONTEXT, new SectorIdentifierRedirectUrisHandler());
}
@Override
public void close() {
httpServer.removeContext(CONTEXT);
}
private class SectorIdentifierRedirectUrisHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
String metadata = JsonSerialization.writeValueAsString(sectorIdentifierRedirectUris);
exchange.getResponseHeaders().add("Content-Type", "application/json");
exchange.sendResponseHeaders(Response.Status.OK.getStatusCode(), metadata.length());
try (OutputStream out = exchange.getResponseBody()) {
out.write(metadata.getBytes(StandardCharsets.UTF_8));
}
}
}
}
@@ -0,0 +1,41 @@
package org.keycloak.testframework.oauth;
import java.util.List;
import org.keycloak.testframework.injection.DependenciesBuilder;
import org.keycloak.testframework.injection.Dependency;
import org.keycloak.testframework.injection.InstanceContext;
import org.keycloak.testframework.injection.RequestedInstance;
import org.keycloak.testframework.injection.Supplier;
import org.keycloak.testframework.oauth.annotations.InjectSectorIdentifierRedirectUrisProvider;
import com.sun.net.httpserver.HttpServer;
/**
*
* @author rmartinc
*/
public class SectorIdentifierRedirectUrisSupplier implements Supplier<SectorIdentifierRedirectUrisProvider, InjectSectorIdentifierRedirectUrisProvider> {
@Override
public List<Dependency> getDependencies(RequestedInstance<SectorIdentifierRedirectUrisProvider, InjectSectorIdentifierRedirectUrisProvider> instanceContext) {
return DependenciesBuilder.create(HttpServer.class).build();
}
@Override
public SectorIdentifierRedirectUrisProvider getValue(InstanceContext<SectorIdentifierRedirectUrisProvider, InjectSectorIdentifierRedirectUrisProvider> instanceContext) {
HttpServer httpServer = instanceContext.getDependency(HttpServer.class);
String[] uris = instanceContext.getAnnotation().value();
return new SectorIdentifierRedirectUrisProvider(httpServer, uris);
}
@Override
public boolean compatible(InstanceContext<SectorIdentifierRedirectUrisProvider, InjectSectorIdentifierRedirectUrisProvider> a, RequestedInstance<SectorIdentifierRedirectUrisProvider, InjectSectorIdentifierRedirectUrisProvider> b) {
return a.getAnnotation().equals(b.getAnnotation());
}
@Override
public void close(InstanceContext<SectorIdentifierRedirectUrisProvider, InjectSectorIdentifierRedirectUrisProvider> instanceContext) {
instanceContext.getValue().close();
}
}
@@ -0,0 +1,20 @@
package org.keycloak.testframework.oauth.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.keycloak.testframework.injection.LifeCycle;
/**
*
* @author rmartinc
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectSectorIdentifierRedirectUrisProvider {
LifeCycle lifecycle() default LifeCycle.GLOBAL;
String[] value();
}