diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java new file mode 100644 index 0000000000..99c42912e4 --- /dev/null +++ b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java @@ -0,0 +1,53 @@ +package org.keycloak.adapters.authorization.integration.elytron; + +import java.security.Principal; + +import jakarta.servlet.http.HttpServletRequest; +import org.keycloak.adapters.authorization.PolicyEnforcer; +import org.keycloak.adapters.authorization.integration.jakarta.ServletPolicyEnforcerFilter; +import org.keycloak.adapters.authorization.spi.ConfigurationResolver; +import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; +import org.wildfly.security.http.oidc.OidcClientConfiguration; +import org.wildfly.security.http.oidc.OidcPrincipal; +import org.wildfly.security.http.oidc.RefreshableOidcSecurityContext; + +public class ElytronPolicyEnforcerFilter extends ServletPolicyEnforcerFilter { + + public ElytronPolicyEnforcerFilter(ConfigurationResolver configResolver) { + super(configResolver); + } + + @Override + protected String extractBearerToken(HttpServletRequest request) { + Principal principal = request.getUserPrincipal(); + + if (principal == null) { + return null; + } + + OidcPrincipal oidcPrincipal = (OidcPrincipal) principal; + RefreshableOidcSecurityContext securityContext = (RefreshableOidcSecurityContext) oidcPrincipal.getOidcSecurityContext(); + + if (securityContext == null) { + return null; + } + + return securityContext.getTokenString(); + } + + @Override + protected PolicyEnforcer createPolicyEnforcer(HttpServletRequest servletRequest, PolicyEnforcerConfig enforcerConfig) { + RefreshableOidcSecurityContext securityContext = (RefreshableOidcSecurityContext) ((OidcPrincipal) servletRequest.getUserPrincipal()).getOidcSecurityContext(); + OidcClientConfiguration configuration = securityContext.getOidcClientConfiguration(); + String authServerUrl = configuration.getAuthServerBaseUrl(); + + return PolicyEnforcer.builder() + .authServerUrl(authServerUrl) + .realm(configuration.getRealm()) + .clientId(configuration.getClientId()) + .credentials(configuration.getResourceCredentials()) + .bearerOnly(false) + .enforcerConfig(enforcerConfig) + .httpClient(configuration.getClient()).build(); + } +} diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java index 496937966d..d5bec3b955 100644 --- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java +++ b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java @@ -66,7 +66,7 @@ public class PolicyEnforcerServletContextListener implements ServletContextListe logger.debug("Policy enforcement filter is enabled."); - servletContext.addFilter("keycloak-policy-enforcer", new PolicyEnforcerFilter(configResolver)) + servletContext.addFilter("keycloak-policy-enforcer", new ElytronPolicyEnforcerFilter(configResolver)) .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); } diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java index ed4892980c..6b645fce5e 100644 --- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java +++ b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java @@ -45,7 +45,15 @@ public class ServletHttpRequest implements HttpRequest { @Override public String getRelativePath() { - return request.getServletPath(); + String uri = request.getRequestURI(); + String contextPath = request.getContextPath(); + String servletPath = uri.substring(uri.indexOf(contextPath) + contextPath.length()); + + if ("".equals(servletPath)) { + servletPath = "/"; + } + + return servletPath; } @Override diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerFilter.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java similarity index 62% rename from authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerFilter.java rename to authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java index 9ca6164490..ee0931044b 100644 --- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerFilter.java +++ b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java @@ -1,8 +1,8 @@ -package org.keycloak.adapters.authorization.integration.elytron; +package org.keycloak.adapters.authorization.integration.jakarta; import java.io.IOException; -import java.io.InputStream; import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.function.Function; @@ -21,6 +21,8 @@ import org.jboss.logging.Logger; import org.keycloak.AuthorizationContext; import org.keycloak.adapters.authorization.PolicyEnforcer; import org.keycloak.adapters.authorization.TokenPrincipal; +import org.keycloak.adapters.authorization.integration.elytron.ServletHttpRequest; +import org.keycloak.adapters.authorization.integration.elytron.ServletHttpResponse; import org.keycloak.adapters.authorization.spi.ConfigurationResolver; import org.keycloak.adapters.authorization.spi.HttpRequest; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; @@ -29,7 +31,7 @@ import org.wildfly.security.http.oidc.OidcPrincipal; import org.wildfly.security.http.oidc.RefreshableOidcSecurityContext; /** - * A {@link Filter} acting as a policy enforcer. This filter does not enforce access for anonymous subjects.
+ * A Jakarta Servlet {@link Filter} acting as a policy enforcer. This filter does not enforce access for anonymous subjects. * * For authenticated subjects, this filter delegates the access decision to the {@link PolicyEnforcer} and decide if * the request should continue. @@ -39,13 +41,13 @@ import org.wildfly.security.http.oidc.RefreshableOidcSecurityContext; * * @author Pedro Igor */ -public class PolicyEnforcerFilter implements Filter, ServletContextAttributeListener { +public class ServletPolicyEnforcerFilter implements Filter, ServletContextAttributeListener { private final Logger logger = Logger.getLogger(getClass()); private final Map