Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e93c4724b |
No files matched your search
@@ -32,10 +32,6 @@ To build the distribution run:
|
||||
|
||||
Once completed you will find distribution archives in `distribution`.
|
||||
|
||||
To build only the server run:
|
||||
|
||||
mvn -Pdistribution -pl distribution/server-dist -am -Dmaven.test.skip clean install
|
||||
|
||||
|
||||
Starting Keycloak
|
||||
-----------------
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+23
-35
@@ -28,7 +28,6 @@ import org.jboss.logging.Logger;
|
||||
import org.keycloak.AuthorizationContext;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.OIDCHttpFacade;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.spi.HttpFacade.Request;
|
||||
import org.keycloak.authorization.client.AuthzClient;
|
||||
import org.keycloak.authorization.client.ClientAuthorizationContext;
|
||||
@@ -166,7 +165,7 @@ public abstract class AbstractPolicyEnforcer {
|
||||
policyEnforcer.getPathMatcher().removeFromCache(getPath(request));
|
||||
}
|
||||
|
||||
return hasValidClaims(actualPathConfig, permission, httpFacade, authorization);
|
||||
return hasValidClaims(actualPathConfig, httpFacade, authorization);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -188,22 +187,35 @@ public abstract class AbstractPolicyEnforcer {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasValidClaims(PathConfig actualPathConfig, Permission permission, OIDCHttpFacade httpFacade, Authorization authorization) {
|
||||
Map<String, Set<String>> grantedClaims = permission.getClaims();
|
||||
private boolean hasValidClaims(PathConfig actualPathConfig, OIDCHttpFacade httpFacade, Authorization authorization) {
|
||||
Map<String, Map<String, Object>> claimInformationPointConfig = actualPathConfig.getClaimInformationPointConfig();
|
||||
|
||||
if (grantedClaims != null) {
|
||||
Map<String, List<String>> claims = resolveClaims(actualPathConfig, httpFacade);
|
||||
if (claimInformationPointConfig != null) {
|
||||
Map<String, List<String>> claims = new HashMap<>();
|
||||
|
||||
if (claims.isEmpty()) {
|
||||
return false;
|
||||
for (Entry<String, Map<String, Object>> entry : claimInformationPointConfig.entrySet()) {
|
||||
ClaimInformationPointProviderFactory factory = policyEnforcer.getClaimInformationPointProviderFactories().get(entry.getKey());
|
||||
|
||||
if (factory == null) {
|
||||
throw new RuntimeException("Could not find claim information provider with name [" + entry.getKey() + "]");
|
||||
}
|
||||
|
||||
claims.putAll(factory.create(entry.getValue()).resolve(httpFacade));
|
||||
}
|
||||
|
||||
for (Entry<String, Set<String>> entry : grantedClaims.entrySet()) {
|
||||
List<String> requestClaims = claims.get(entry.getKey());
|
||||
Map<String, List<String>> grantedClaims = authorization.getClaims();
|
||||
|
||||
if (requestClaims == null || requestClaims.isEmpty() || !entry.getValue().containsAll(requestClaims)) {
|
||||
if (grantedClaims != null) {
|
||||
if (claims.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Entry<String, List<String>> entry : grantedClaims.entrySet()) {
|
||||
List<String> requestClaims = claims.get(entry.getKey());
|
||||
|
||||
if (requestClaims == null || requestClaims.isEmpty() || !entry.getValue().containsAll(requestClaims)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,28 +342,4 @@ public abstract class AbstractPolicyEnforcer {
|
||||
private PathConfig getPathConfig(Request request) {
|
||||
return isDefaultAccessDeniedUri(request) ? null : policyEnforcer.getPathMatcher().matches(getPath(request));
|
||||
}
|
||||
|
||||
protected Map<String, List<String>> resolveClaims(PathConfig pathConfig, OIDCHttpFacade httpFacade) {
|
||||
Map<String, List<String>> claims = getClaims(getEnforcerConfig().getClaimInformationPointConfig(), httpFacade);
|
||||
|
||||
claims.putAll(getClaims(pathConfig.getClaimInformationPointConfig(), httpFacade));
|
||||
|
||||
return claims;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getClaims(Map<String, Map<String, Object>>claimInformationPointConfig, HttpFacade httpFacade) {
|
||||
Map<String, List<String>> claims = new HashMap<>();
|
||||
|
||||
if (claimInformationPointConfig != null) {
|
||||
for (Entry<String, Map<String, Object>> claimDef : claimInformationPointConfig.entrySet()) {
|
||||
ClaimInformationPointProviderFactory factory = getPolicyEnforcer().getClaimInformationPointProviderFactories().get(claimDef.getKey());
|
||||
|
||||
if (factory != null) {
|
||||
claims.putAll(factory.create(claimDef.getValue()).resolve(httpFacade));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return claims;
|
||||
}
|
||||
}
|
||||
+46
-18
@@ -22,6 +22,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
@@ -86,6 +87,19 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
grantedPermissions.add(newPermission);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, List<String>> newClaims = newAuthorization.getClaims();
|
||||
|
||||
if (newClaims != null) {
|
||||
Map<String, List<String>> claims = authorization.getClaims();
|
||||
|
||||
if (claims == null) {
|
||||
claims = new HashMap<>();
|
||||
authorization.setClaims(claims);
|
||||
}
|
||||
|
||||
claims.putAll(newClaims);
|
||||
}
|
||||
}
|
||||
|
||||
original.setAuthorization(authorization);
|
||||
@@ -140,7 +154,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
|
||||
private AccessToken requestAuthorizationToken(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, OIDCHttpFacade httpFacade) {
|
||||
if (getEnforcerConfig().getUserManagedAccess() != null) {
|
||||
if (getPolicyEnforcer().getDeployment().isBearerOnly() || (isBearerAuthorization(httpFacade) && getEnforcerConfig().getUserManagedAccess() != null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -151,15 +165,20 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
AccessToken accessToken = securityContext.getToken();
|
||||
AuthorizationRequest authzRequest = new AuthorizationRequest();
|
||||
|
||||
if (isBearerAuthorization(httpFacade) || accessToken.getAuthorization() != null) {
|
||||
authzRequest.addPermission(pathConfig.getId(), methodConfig.getScopes());
|
||||
}
|
||||
if (getEnforcerConfig().getUserManagedAccess() != null) {
|
||||
String ticket = getPermissionTicket(pathConfig, methodConfig, getAuthzClient(), httpFacade);
|
||||
authzRequest.setTicket(ticket);
|
||||
} else {
|
||||
if (accessToken.getAuthorization() != null) {
|
||||
authzRequest.addPermission(pathConfig.getId(), methodConfig.getScopes());
|
||||
}
|
||||
|
||||
Map<String, List<String>> claims = resolveClaims(pathConfig, httpFacade);
|
||||
Map<String, List<String>> claims = getClaims(pathConfig, httpFacade);
|
||||
|
||||
if (!claims.isEmpty()) {
|
||||
authzRequest.setClaimTokenFormat("urn:ietf:params:oauth:token-type:jwt");
|
||||
authzRequest.setClaimToken(Base64.encodeBytes(JsonSerialization.writeValueAsBytes(claims)));
|
||||
if (!claims.isEmpty()) {
|
||||
authzRequest.setClaimTokenFormat("urn:ietf:params:oauth:token-type:jwt");
|
||||
authzRequest.setClaimToken(Base64.encodeBytes(JsonSerialization.writeValueAsBytes(claims)));
|
||||
}
|
||||
}
|
||||
|
||||
if (accessToken.getAuthorization() != null) {
|
||||
@@ -167,14 +186,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
}
|
||||
|
||||
LOGGER.debug("Obtaining authorization for authenticated user.");
|
||||
AuthorizationResponse authzResponse;
|
||||
|
||||
if (isBearerAuthorization(httpFacade)) {
|
||||
authzRequest.setSubjectToken(accessTokenString);
|
||||
authzResponse = getAuthzClient().authorization().authorize(authzRequest);
|
||||
} else {
|
||||
authzResponse = getAuthzClient().authorization(accessTokenString).authorize(authzRequest);
|
||||
}
|
||||
AuthorizationResponse authzResponse = getAuthzClient().authorization(accessTokenString).authorize(authzRequest);
|
||||
|
||||
if (authzResponse != null) {
|
||||
return AdapterRSATokenVerifier.verifyToken(authzResponse.getToken(), deployment);
|
||||
@@ -188,7 +200,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getPermissionTicket(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AuthzClient authzClient, OIDCHttpFacade httpFacade) {
|
||||
private String getPermissionTicket(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AuthzClient authzClient, HttpFacade httpFacade) {
|
||||
if (getEnforcerConfig().getUserManagedAccess() != null) {
|
||||
ProtectionResource protection = authzClient.protection();
|
||||
PermissionResource permission = protection.permission();
|
||||
@@ -197,7 +209,7 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
permissionRequest.setResourceId(pathConfig.getId());
|
||||
permissionRequest.setScopes(new HashSet<>(methodConfig.getScopes()));
|
||||
|
||||
Map<String, List<String>> claims = resolveClaims(pathConfig, httpFacade);
|
||||
Map<String, List<String>> claims = getClaims(pathConfig, httpFacade);
|
||||
|
||||
if (!claims.isEmpty()) {
|
||||
permissionRequest.setClaims(claims);
|
||||
@@ -209,6 +221,22 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getClaims(PathConfig pathConfig, HttpFacade httpFacade) {
|
||||
Map<String, List<String>> claims = new HashMap<>();
|
||||
Map<String, Map<String, Object>> claimInformationPointConfig = pathConfig.getClaimInformationPointConfig();
|
||||
|
||||
if (claimInformationPointConfig != null) {
|
||||
for (Entry<String, Map<String, Object>> claimDef : claimInformationPointConfig.entrySet()) {
|
||||
ClaimInformationPointProviderFactory factory = getPolicyEnforcer().getClaimInformationPointProviderFactories().get(claimDef.getKey());
|
||||
|
||||
if (factory != null) {
|
||||
claims.putAll(factory.create(claimDef.getValue()).resolve(httpFacade));
|
||||
}
|
||||
}
|
||||
}
|
||||
return claims;
|
||||
}
|
||||
|
||||
private boolean isBearerAuthorization(OIDCHttpFacade httpFacade) {
|
||||
List<String> authHeaders = httpFacade.getRequest().getHeaders("Authorization");
|
||||
if (authHeaders == null || authHeaders.size() == 0) {
|
||||
|
||||
-11
@@ -271,17 +271,7 @@ public class PolicyEnforcer {
|
||||
List<ResourceRepresentation> matchingResources = authzClient.protection().resource().findByMatchingUri(targetUri);
|
||||
|
||||
if (!matchingResources.isEmpty()) {
|
||||
Map<String, Map<String, Object>> cipConfig = null;
|
||||
|
||||
if (pathConfig != null) {
|
||||
cipConfig = pathConfig.getClaimInformationPointConfig();
|
||||
}
|
||||
|
||||
pathConfig = PathConfig.createPathConfig(matchingResources.get(0));
|
||||
|
||||
if (cipConfig != null) {
|
||||
pathConfig.setClaimInformationPointConfig(cipConfig);
|
||||
}
|
||||
}
|
||||
} catch (Exception cause) {
|
||||
LOGGER.errorf(cause, "Could not lazy load resource with path [" + targetUri + "] from server");
|
||||
@@ -329,7 +319,6 @@ public class PolicyEnforcer {
|
||||
config.setMethods(originalConfig.getMethods());
|
||||
config.setParentConfig(originalConfig);
|
||||
config.setEnforcementMode(originalConfig.getEnforcementMode());
|
||||
config.setClaimInformationPointConfig(originalConfig.getClaimInformationPointConfig());
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-fuse7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-fuse7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-6
@@ -86,9 +86,6 @@ public class PaxWebIntegrationService {
|
||||
return httpContext;
|
||||
}
|
||||
|
||||
public void setHttpContext(HttpContext httpContext) {
|
||||
this.httpContext = httpContext;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() {
|
||||
@@ -118,9 +115,7 @@ public class PaxWebIntegrationService {
|
||||
|
||||
protected WebContainer addingWebContainerCallback(ServiceReference webContainerServiceReference) {
|
||||
WebContainer service = (WebContainer) bundleContext.getService(webContainerServiceReference);
|
||||
if (httpContext == null) {
|
||||
httpContext = service.createDefaultHttpContext();
|
||||
}
|
||||
httpContext = service.createDefaultHttpContext();
|
||||
|
||||
addJettyWebXml(service);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-fuse7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-fuse7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-6
@@ -70,9 +70,6 @@ public class PaxWebIntegrationService {
|
||||
return httpContext;
|
||||
}
|
||||
|
||||
public void setHttpContext(HttpContext httpContext) {
|
||||
this.httpContext = httpContext;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() {
|
||||
@@ -102,9 +99,7 @@ public class PaxWebIntegrationService {
|
||||
|
||||
protected WebContainer addingWebContainerCallback(ServiceReference webContainerServiceReference) {
|
||||
WebContainer service = (WebContainer) bundleContext.getService(webContainerServiceReference);
|
||||
if (httpContext == null) {
|
||||
httpContext = service.createDefaultHttpContext();
|
||||
}
|
||||
httpContext = service.createDefaultHttpContext();
|
||||
|
||||
if (constraintMappings == null) {
|
||||
throw new IllegalStateException("constraintMappings was null!");
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Jetty Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -161,14 +161,6 @@ declare namespace Keycloak {
|
||||
* the user's profile to a new preferred locale.
|
||||
*/
|
||||
kcLocale?: string;
|
||||
|
||||
/**
|
||||
* Specifies arguments that are passed to the Cordova in-app-browser (if applicable).
|
||||
* Options 'hidden' and 'location' are not affected by these arguments.
|
||||
* All available options are defined at https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/.
|
||||
* Example of use: { zoom: "no", hardwareback: "yes" }
|
||||
*/
|
||||
cordovaOptions?: { [optionName: string]: string };
|
||||
}
|
||||
|
||||
type KeycloakPromiseCallback<T> = (result: T) => void;
|
||||
|
||||
@@ -250,16 +250,7 @@
|
||||
baseUrl = kc.endpoints.authorize();
|
||||
}
|
||||
|
||||
var scope;
|
||||
if (options && options.scope) {
|
||||
if (options.scope.indexOf("openid") != -1) {
|
||||
scope = options.scope;
|
||||
} else {
|
||||
scope = "openid " + options.scope;
|
||||
}
|
||||
} else {
|
||||
scope = "openid";
|
||||
}
|
||||
var scope = (options && options.scope) ? "openid " + options.scope : "openid";
|
||||
|
||||
var url = baseUrl
|
||||
+ '?client_id=' + encodeURIComponent(kc.clientId)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -99,12 +99,6 @@
|
||||
<version>${cxf.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+7
-31
@@ -25,7 +25,6 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -35,36 +34,14 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
|
||||
|
||||
@Override
|
||||
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
|
||||
String uri = request.getURI();
|
||||
String relativePath = request.getRelativePath();
|
||||
String webContext = null;
|
||||
if (relativePath == null || !uri.contains(relativePath)) {
|
||||
String[] urlTokens = uri.split("/");
|
||||
if (urlTokens.length < 4) {
|
||||
throw new IllegalStateException("Not able to determine the web-context to load the correspondent keycloak.json file");
|
||||
}
|
||||
|
||||
webContext = urlTokens[3];
|
||||
} else {
|
||||
URI parsedURI = URI.create(uri);
|
||||
String path = parsedURI.getPath();
|
||||
path = path.substring(0, path.indexOf(relativePath));
|
||||
while (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
webContext = path;
|
||||
if ("".equals(webContext)) {
|
||||
path = relativePath;
|
||||
while (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
if (path.contains("/")) {
|
||||
path = path.substring(0, path.indexOf("/"));
|
||||
}
|
||||
webContext = path;
|
||||
}
|
||||
String path = request.getURI();
|
||||
String[] urlTokens = path.split("/");
|
||||
if (urlTokens.length < 4) {
|
||||
throw new IllegalStateException("Not able to determine the web-context to load the correspondent keycloak.json file");
|
||||
}
|
||||
|
||||
String webContext = urlTokens[3];
|
||||
|
||||
KeycloakDeployment deployment = cache.get(webContext);
|
||||
if (null == deployment) {
|
||||
// not found on the simple cache, try to load it from the file system
|
||||
@@ -77,8 +54,7 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
|
||||
keycloakConfig = karafEtc;
|
||||
}
|
||||
|
||||
String absolutePath = keycloakConfig + File.separator + webContext + ("".equals(webContext) ? "" : "-")
|
||||
+ "keycloak.json";
|
||||
String absolutePath = keycloakConfig + File.separator + webContext + "-keycloak.json";
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(absolutePath);
|
||||
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.adapters.osgi;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.OIDCHttpFacade;
|
||||
import org.keycloak.adapters.spi.AuthenticationError;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.spi.LogoutError;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class PathBasedKeycloakConfigResolverTest {
|
||||
|
||||
@Test
|
||||
public void relativeURIsAndContexts() throws Exception {
|
||||
PathBasedKeycloakConfigResolver resolver = new PathBasedKeycloakConfigResolver();
|
||||
|
||||
assertNotNull(populate(resolver, "test")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/a/b/c")));
|
||||
|
||||
assertNotNull(populate(resolver, "test")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/a/b")));
|
||||
|
||||
// means default context and actually we use first segment
|
||||
assertNotNull(populate(resolver, "test")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/test/a/b/c")));
|
||||
|
||||
assertNotNull(populate(resolver, "test/a")
|
||||
.resolve(new MockRequest("http://localhost/test/a/b/c?d=e", "/b/c")));
|
||||
|
||||
assertNotNull(populate(resolver, "")
|
||||
.resolve(new MockRequest("http://localhost/", "/")));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private PathBasedKeycloakConfigResolver populate(PathBasedKeycloakConfigResolver resolver, String context)
|
||||
throws Exception {
|
||||
Field f = PathBasedKeycloakConfigResolver.class.getDeclaredField("cache");
|
||||
f.setAccessible(true);
|
||||
Map<String, KeycloakDeployment> cache = (Map<String, KeycloakDeployment>) f.get(resolver);
|
||||
cache.clear();
|
||||
cache.put(context, new KeycloakDeployment());
|
||||
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private class MockRequest implements OIDCHttpFacade.Request {
|
||||
|
||||
private String uri;
|
||||
private String relativePath;
|
||||
|
||||
public MockRequest(String uri, String relativePath) {
|
||||
this.uri = uri;
|
||||
this.relativePath = relativePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRelativePath() {
|
||||
return this.relativePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstParam(String param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryParamValue(String param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpFacade.Cookie getCookie(String cookieName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getHeaders(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(boolean buffered) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddr() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setError(AuthenticationError error) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setError(LogoutError error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+20
-33
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OIDC Client Adapter Modules</name>
|
||||
@@ -31,38 +31,25 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>adapter-core</module>
|
||||
<module>as7-eap6</module>
|
||||
<module>installed</module>
|
||||
<module>fuse7</module>
|
||||
<module>kcinit</module>
|
||||
<module>jaxrs-oauth-client</module>
|
||||
<module>jetty</module>
|
||||
<module>js</module>
|
||||
<module>osgi-adapter</module>
|
||||
<module>servlet-filter</module>
|
||||
<module>servlet-oauth-client</module>
|
||||
<module>spring-boot</module>
|
||||
<module>spring-boot2</module>
|
||||
<module>spring-boot-adapter-core</module>
|
||||
<module>spring-boot-container-bundle</module>
|
||||
<module>spring-security</module>
|
||||
<module>tomcat</module>
|
||||
<module>undertow</module>
|
||||
<module>wildfly</module>
|
||||
<module>wildfly-elytron</module>
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>nonServer</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!serverOnly</name>
|
||||
</property>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>adapter-core</module>
|
||||
<module>as7-eap6</module>
|
||||
<module>installed</module>
|
||||
<module>fuse7</module>
|
||||
<module>kcinit</module>
|
||||
<module>jaxrs-oauth-client</module>
|
||||
<module>jetty</module>
|
||||
<module>osgi-adapter</module>
|
||||
<module>servlet-filter</module>
|
||||
<module>servlet-oauth-client</module>
|
||||
<module>spring-boot</module>
|
||||
<module>spring-boot2</module>
|
||||
<module>spring-boot-adapter-core</module>
|
||||
<module>spring-boot-container-bundle</module>
|
||||
<module>spring-security</module>
|
||||
<module>tomcat</module>
|
||||
<module>undertow</module>
|
||||
<module>wildfly</module>
|
||||
<module>wildfly-elytron</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-boot-container-bundle</artifactId>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Tomcat Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ import org.wildfly.security.http.Scope;
|
||||
*/
|
||||
class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticationMechanism {
|
||||
|
||||
static Logger LOGGER = Logger.getLogger(KeycloakHttpServerAuthenticationMechanism.class);
|
||||
static Logger LOGGER = Logger.getLogger(KeycloakHttpServerAuthenticationMechanismFactory.class);
|
||||
static final String NAME = "KEYCLOAK";
|
||||
|
||||
private final Map<String, ?> properties;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak WildFly Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+16
-61
@@ -17,6 +17,21 @@
|
||||
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.security.api.SecurityContext;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.security.NestableGroup;
|
||||
import org.jboss.security.SecurityConstants;
|
||||
import org.jboss.security.SecurityContextAssociation;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
|
||||
import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
import java.util.Collection;
|
||||
@@ -24,33 +39,11 @@ import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.security.NestableGroup;
|
||||
import org.jboss.security.SecurityConstants;
|
||||
import org.jboss.security.SecurityContextAssociation;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.jboss.security.SubjectInfo;
|
||||
import org.jboss.security.identity.RoleGroup;
|
||||
import org.jboss.security.identity.plugins.SimpleRole;
|
||||
import org.jboss.security.identity.plugins.SimpleRoleGroup;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
|
||||
import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
|
||||
|
||||
import io.undertow.security.api.SecurityContext;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyRequestAuthenticator extends ServletRequestAuthenticator
|
||||
{
|
||||
public class WildflyRequestAuthenticator extends ServletRequestAuthenticator {
|
||||
protected static Logger log = Logger.getLogger(WildflyRequestAuthenticator.class);
|
||||
|
||||
public WildflyRequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort,
|
||||
@@ -94,13 +87,6 @@ public class WildflyRequestAuthenticator extends ServletRequestAuthenticator
|
||||
org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
|
||||
Principal userPrincipal = getPrincipal(subject);
|
||||
sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
|
||||
|
||||
// Roles of subjectInfo are null, because is was constructed by
|
||||
// org.jboss.security.identity.extensions.CredentialIdentityFactory
|
||||
// .createIdentity(Principal [=userPrincipal], Object [=account], Role [=null]).
|
||||
// Therefore the roles are only contained in the authenticatedSubject (member of subjectInfo)
|
||||
// and subsequent logics do only access subjectInfo#roles instead of authenticatedSubject#roles.
|
||||
mapGroupMembersOfAuthenticatedSubjectIntoSecurityContext(sc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,35 +150,4 @@ public class WildflyRequestAuthenticator extends ServletRequestAuthenticator
|
||||
return roleSets;
|
||||
}
|
||||
|
||||
private static void mapGroupMembersOfAuthenticatedSubjectIntoSecurityContext(org.jboss.security.SecurityContext sc) {
|
||||
SubjectInfo subjectInfo = sc.getSubjectInfo();
|
||||
if (subjectInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Subject authenticatedSubject = subjectInfo.getAuthenticatedSubject();
|
||||
if (authenticatedSubject == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get role group of security context in order to add roles of authenticatedSubject.
|
||||
RoleGroup scRoles = sc.getUtil().getRoles();
|
||||
if (scRoles == null) {
|
||||
scRoles = new SimpleRoleGroup("Roles");
|
||||
sc.getUtil().setRoles(scRoles);
|
||||
}
|
||||
|
||||
// Get group roles of authenticatedSubject and add each role of the group into security context
|
||||
Iterator<Principal> principalItr = authenticatedSubject.getPrincipals().iterator();
|
||||
while (principalItr.hasNext()) {
|
||||
Principal principal = principalItr.next();
|
||||
if (principal instanceof Group) {
|
||||
Enumeration<? extends Principal> members = ((Group) principal).members();
|
||||
while (members.hasMoreElements()) {
|
||||
Principal role = members.nextElement();
|
||||
scRoles.addRole(new SimpleRole(role.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+3
-16
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Adapters</name>
|
||||
@@ -31,21 +31,8 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>spi</module>
|
||||
<module>saml</module>
|
||||
<module>oidc</module>
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>nonServer</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!serverOnly</name>
|
||||
</property>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>spi</module>
|
||||
<module>saml</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML EAP Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+7
-19
@@ -66,7 +66,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
@@ -120,27 +119,16 @@ public abstract class AbstractSamlAuthenticator extends LoginAuthenticator {
|
||||
tokenStore.logoutAccount();
|
||||
}
|
||||
|
||||
private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*:");
|
||||
|
||||
protected void forwardToLogoutPage(Request request, HttpServletResponse response, SamlDeployment deployment) {
|
||||
final String location = deployment.getLogoutPage();
|
||||
RequestDispatcher disp = request.getRequestDispatcher(deployment.getLogoutPage());
|
||||
//make sure the login page is never cached
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
|
||||
|
||||
try {
|
||||
//make sure the login page is never cached
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
|
||||
if (location == null) {
|
||||
log.warn("Logout page not set.");
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} else if (PROTOCOL_PATTERN.matcher(location).find()) {
|
||||
response.sendRedirect(response.encodeRedirectURL(location));
|
||||
} else {
|
||||
RequestDispatcher disp = request.getRequestDispatcher(location);
|
||||
|
||||
disp.forward(request, response);
|
||||
}
|
||||
disp.forward(request, response);
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Jetty Integration</name>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Client Adapter Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Tomcat Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+8
-19
@@ -44,7 +44,7 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Keycloak authentication valve
|
||||
@@ -189,27 +189,16 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
|
||||
|
||||
protected abstract GenericPrincipalFactory createPrincipalFactory();
|
||||
protected abstract boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException;
|
||||
private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*:");
|
||||
protected void forwardToLogoutPage(Request request, HttpServletResponse response,SamlDeployment deployment) {
|
||||
RequestDispatcher disp = request.getRequestDispatcher(deployment.getLogoutPage());
|
||||
//make sure the login page is never cached
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
|
||||
protected void forwardToLogoutPage(Request request, HttpServletResponse response, SamlDeployment deployment) {
|
||||
final String location = deployment.getLogoutPage();
|
||||
|
||||
try {
|
||||
//make sure the login page is never cached
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
|
||||
if (location == null) {
|
||||
log.warn("Logout page not set.");
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} else if (PROTOCOL_PATTERN.matcher(location).find()) {
|
||||
response.sendRedirect(response.encodeRedirectURL(location));
|
||||
} else {
|
||||
RequestDispatcher disp = request.getRequestDispatcher(location);
|
||||
|
||||
disp.forward(request.getRequest(), response);
|
||||
}
|
||||
disp.forward(request.getRequest(), response);
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+5
-22
@@ -33,9 +33,6 @@ import org.keycloak.adapters.spi.AuthOutcome;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.undertow.UndertowHttpFacade;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Abstract base class for a Keycloak-enabled Undertow AuthenticationMechanism.
|
||||
@@ -43,9 +40,6 @@ import java.util.regex.Pattern;
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
|
||||
*/
|
||||
public abstract class AbstractSamlAuthMech implements AuthenticationMechanism {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(AbstractSamlAuthMech.class.getName());
|
||||
|
||||
public static final AttachmentKey<AuthChallenge> KEYCLOAK_CHALLENGE_ATTACHMENT_KEY = AttachmentKey.create(AuthChallenge.class);
|
||||
protected SamlDeploymentContext deploymentContext;
|
||||
protected UndertowUserSessionManagement sessionManagement;
|
||||
@@ -74,22 +68,11 @@ public abstract class AbstractSamlAuthMech implements AuthenticationMechanism {
|
||||
return StatusCodes.TEMPORARY_REDIRECT;
|
||||
}
|
||||
|
||||
private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*:");
|
||||
|
||||
static void sendRedirect(final HttpServerExchange exchange, final String location) {
|
||||
if (location == null) {
|
||||
LOG.log(Level.WARNING, "Logout page not set.");
|
||||
exchange.setStatusCode(StatusCodes.NOT_FOUND);
|
||||
exchange.endExchange();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PROTOCOL_PATTERN.matcher(location).find()) {
|
||||
exchange.getResponseHeaders().put(Headers.LOCATION, location);
|
||||
} else {
|
||||
String loc = exchange.getRequestScheme() + "://" + exchange.getHostAndPort() + location;
|
||||
exchange.getResponseHeaders().put(Headers.LOCATION, loc);
|
||||
}
|
||||
// TODO - String concatenation to construct URLS is extremely error prone - switch to a URI which will better
|
||||
// handle this.
|
||||
String loc = exchange.getRequestScheme() + "://" + exchange.getHostAndPort() + location;
|
||||
exchange.getResponseHeaders().put(Headers.LOCATION, loc);
|
||||
}
|
||||
|
||||
protected void registerNotifications(final SecurityContext securityContext) {
|
||||
@@ -159,7 +142,7 @@ public abstract class AbstractSamlAuthMech implements AuthenticationMechanism {
|
||||
protected void redirectLogout(SamlDeployment deployment, HttpServerExchange exchange) {
|
||||
String page = deployment.getLogoutPage();
|
||||
sendRedirect(exchange, page);
|
||||
exchange.setStatusCode(StatusCodes.FOUND);
|
||||
exchange.setResponseCode(302);
|
||||
exchange.endExchange();
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -113,11 +113,7 @@ public class ServletSamlAuthMech extends AbstractSamlAuthMech {
|
||||
|
||||
@Override
|
||||
protected void redirectLogout(SamlDeployment deployment, HttpServerExchange exchange) {
|
||||
exchange.getResponseHeaders().add(Headers.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
|
||||
exchange.getResponseHeaders().add(Headers.PRAGMA, "no-cache");
|
||||
exchange.getResponseHeaders().add(Headers.EXPIRES, "0");
|
||||
|
||||
super.redirectLogout(deployment, exchange);
|
||||
servePage(exchange, deployment.getLogoutPage());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+9
-19
@@ -19,7 +19,6 @@ package org.keycloak.adapters.saml.elytron;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
@@ -40,7 +39,7 @@ import org.wildfly.security.http.Scope;
|
||||
*/
|
||||
class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticationMechanism {
|
||||
|
||||
static Logger LOGGER = Logger.getLogger(KeycloakHttpServerAuthenticationMechanism.class);
|
||||
static Logger LOGGER = Logger.getLogger(KeycloakHttpServerAuthenticationMechanismFactory.class);
|
||||
static final String NAME = "KEYCLOAK-SAML";
|
||||
|
||||
private final Map<String, ?> properties;
|
||||
@@ -143,23 +142,14 @@ class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticat
|
||||
exchange.getResponse().setStatus(302);
|
||||
}
|
||||
|
||||
private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*:");
|
||||
|
||||
static void sendRedirect(final ElytronHttpFacade exchange, final String location) {
|
||||
if (location == null) {
|
||||
LOGGER.warn("Logout page not set.");
|
||||
exchange.getResponse().setStatus(302);
|
||||
return;
|
||||
}
|
||||
if (PROTOCOL_PATTERN.matcher(location).find()) {
|
||||
exchange.getResponse().setHeader("Location", location);
|
||||
} else {
|
||||
URI uri = exchange.getURI();
|
||||
String path = uri.getPath();
|
||||
String relativePath = exchange.getRequest().getRelativePath();
|
||||
String contextPath = path.substring(0, path.indexOf(relativePath));
|
||||
String loc = exchange.getURI().getScheme() + "://" + exchange.getURI().getHost() + ":" + exchange.getURI().getPort() + contextPath + location;
|
||||
exchange.getResponse().setHeader("Location", loc);
|
||||
}
|
||||
// TODO - String concatenation to construct URLS is extremely error prone - switch to a URI which will better
|
||||
// handle this.
|
||||
URI uri = exchange.getURI();
|
||||
String path = uri.getPath();
|
||||
String relativePath = exchange.getRequest().getRelativePath();
|
||||
String contextPath = path.substring(0, path.indexOf(relativePath));
|
||||
String loc = exchange.getURI().getScheme() + "://" + exchange.getURI().getHost() + ":" + exchange.getURI().getPort() + contextPath + location;
|
||||
exchange.getResponse().setHeader("Location", loc);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Wildfly Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Client Adapter SPI Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+2
-1
@@ -111,7 +111,8 @@ public class FilterSessionStore implements AdapterSessionStore {
|
||||
if (body == null) return new MultivaluedHashMap<String, String>();
|
||||
|
||||
String contentType = getContentType();
|
||||
if (contentType != null && contentType.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
|
||||
contentType = contentType.toLowerCase();
|
||||
if (contentType.startsWith("application/x-www-form-urlencoded")) {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(body);
|
||||
try {
|
||||
parameters = parseForm(is);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authz-parent</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
-7
@@ -102,9 +102,6 @@ public class ServerConfiguration {
|
||||
|
||||
@JsonProperty("permission_endpoint")
|
||||
private String permissionEndpoint;
|
||||
|
||||
@JsonProperty("policy_endpoint")
|
||||
private String policyEndpoint;
|
||||
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
@@ -209,8 +206,4 @@ public class ServerConfiguration {
|
||||
public String getPermissionEndpoint() {
|
||||
return permissionEndpoint;
|
||||
}
|
||||
|
||||
public String getPolicyEndpoint() {
|
||||
return policyEndpoint;
|
||||
}
|
||||
}
|
||||
-187
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.authorization.client.resource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.keycloak.authorization.client.representation.ServerConfiguration;
|
||||
import org.keycloak.authorization.client.util.Http;
|
||||
import org.keycloak.authorization.client.util.Throwables;
|
||||
import org.keycloak.authorization.client.util.TokenCallable;
|
||||
import org.keycloak.representations.idm.authorization.UmaPermissionRepresentation;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
/**
|
||||
* An entry point for managing user-managed permissions for a particular resource
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class PolicyResource {
|
||||
|
||||
private String resourceId;
|
||||
private final Http http;
|
||||
private final ServerConfiguration serverConfiguration;
|
||||
private final TokenCallable pat;
|
||||
|
||||
public PolicyResource(String resourceId, Http http, ServerConfiguration serverConfiguration, TokenCallable pat) {
|
||||
this.resourceId = resourceId;
|
||||
this.http = http;
|
||||
this.serverConfiguration = serverConfiguration;
|
||||
this.pat = pat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user-managed permission as represented by the given {@code permission}.
|
||||
*
|
||||
* @param permission the permission to create
|
||||
* @return if successful, the permission created
|
||||
*/
|
||||
public UmaPermissionRepresentation create(final UmaPermissionRepresentation permission) {
|
||||
if (permission == null) {
|
||||
throw new IllegalArgumentException("Permission must not be null");
|
||||
}
|
||||
|
||||
Callable<UmaPermissionRepresentation> callable = new Callable<UmaPermissionRepresentation>() {
|
||||
@Override
|
||||
public UmaPermissionRepresentation call() throws Exception {
|
||||
return http.<UmaPermissionRepresentation>post(serverConfiguration.getPolicyEndpoint() + "/" + resourceId)
|
||||
.authorizationBearer(pat.call())
|
||||
.json(JsonSerialization.writeValueAsBytes(permission))
|
||||
.response().json(UmaPermissionRepresentation.class).execute();
|
||||
}
|
||||
};
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception cause) {
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error creating policy for resurce [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing user-managed permission
|
||||
*
|
||||
* @param permission the permission to update
|
||||
*/
|
||||
public void update(final UmaPermissionRepresentation permission) {
|
||||
if (permission == null) {
|
||||
throw new IllegalArgumentException("Permission must not be null");
|
||||
}
|
||||
|
||||
if (permission.getId() == null) {
|
||||
throw new IllegalArgumentException("Permission id must not be null");
|
||||
}
|
||||
|
||||
Callable<Void> callable = new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
http.<Void>put(serverConfiguration.getPolicyEndpoint() + "/"+ permission.getId())
|
||||
.authorizationBearer(pat.call())
|
||||
.json(JsonSerialization.writeValueAsBytes(permission)).execute();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
try {
|
||||
callable.call();
|
||||
} catch (Exception cause) {
|
||||
Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error updating policy for resurce [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing user-managed permission
|
||||
*
|
||||
* @param id the permission id
|
||||
*/
|
||||
public void delete(final String id) {
|
||||
Callable<Void> callable = new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() {
|
||||
http.<UmaPermissionRepresentation>delete(serverConfiguration.getPolicyEndpoint() + "/" + id)
|
||||
.authorizationBearer(pat.call())
|
||||
.response().execute();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
try {
|
||||
callable.call();
|
||||
} catch (Exception cause) {
|
||||
Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error updating policy for resurce [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the server for permission matching the given parameters.
|
||||
*
|
||||
* @param id the permission id
|
||||
* @param name the name of the permission
|
||||
* @param scope the scope associated with the permission
|
||||
* @param firstResult the position of the first resource to retrieve
|
||||
* @param maxResult the maximum number of resources to retrieve
|
||||
* @return the permissions matching the given parameters
|
||||
*/
|
||||
public List<UmaPermissionRepresentation> find(final String name,
|
||||
final String scope,
|
||||
final Integer firstResult,
|
||||
final Integer maxResult) {
|
||||
Callable<List<UmaPermissionRepresentation>> callable = new Callable<List<UmaPermissionRepresentation>>() {
|
||||
@Override
|
||||
public List<UmaPermissionRepresentation> call() {
|
||||
return http.<List<UmaPermissionRepresentation>>get(serverConfiguration.getPolicyEndpoint())
|
||||
.authorizationBearer(pat.call())
|
||||
.param("name", name)
|
||||
.param("resource", resourceId)
|
||||
.param("scope", scope)
|
||||
.param("first", firstResult == null ? null : firstResult.toString())
|
||||
.param("max", maxResult == null ? null : maxResult.toString())
|
||||
.response().json(new TypeReference<List<UmaPermissionRepresentation>>(){}).execute();
|
||||
}
|
||||
};
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception cause) {
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error querying policies for resource [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the server for a permission with the given {@code id}.
|
||||
*
|
||||
* @param id the permission id
|
||||
* @return the permission with the given id
|
||||
*/
|
||||
public UmaPermissionRepresentation findById(final String id) {
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("Permission id must not be null");
|
||||
}
|
||||
|
||||
Callable<UmaPermissionRepresentation> callable = new Callable<UmaPermissionRepresentation>() {
|
||||
@Override
|
||||
public UmaPermissionRepresentation call() {
|
||||
return http.<UmaPermissionRepresentation>get(serverConfiguration.getPolicyEndpoint() + "/" + id)
|
||||
.authorizationBearer(pat.call())
|
||||
.response().json(UmaPermissionRepresentation.class).execute();
|
||||
}
|
||||
};
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception cause) {
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error creating policy for resurce [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
-4
@@ -64,10 +64,6 @@ public class ProtectionResource {
|
||||
return new PermissionResource(http, serverConfiguration, pat);
|
||||
}
|
||||
|
||||
public PolicyResource policy(String resourceId) {
|
||||
return new PolicyResource(resourceId, http, serverConfiguration, pat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Introspects the given <code>rpt</code> using the token introspection endpoint.
|
||||
*
|
||||
|
||||
-1
@@ -83,7 +83,6 @@ public class HttpMethodAuthenticator<R> {
|
||||
method.param("rpt", request.getRpt());
|
||||
method.param("scope", request.getScope());
|
||||
method.param("audience", request.getAudience());
|
||||
method.param("subject_token", request.getSubjectToken());
|
||||
|
||||
if (permissions != null) {
|
||||
for (ResourcePermission permission : permissions.getResources()) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authz-provider-parent</artifactId>
|
||||
<version>4.1.0.Final-SNAPSHOT</version>
|
||||
<version>4.0.0.Beta3</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class AggregatePolicyProviderFactory implements PolicyProviderFactory<Agg
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregatePolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
public AggregatePolicyRepresentation toRepresentation(Policy policy) {
|
||||
return new AggregatePolicyRepresentation();
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
package org.keycloak.authorization.policy.provider.client;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
@@ -13,15 +13,15 @@ import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation
|
||||
|
||||
public class ClientPolicyProvider implements PolicyProvider {
|
||||
|
||||
private final BiFunction<Policy, AuthorizationProvider, ClientPolicyRepresentation> representationFunction;
|
||||
private final Function<Policy, ClientPolicyRepresentation> representationFunction;
|
||||
|
||||
public ClientPolicyProvider(BiFunction<Policy, AuthorizationProvider, ClientPolicyRepresentation> representationFunction) {
|
||||
public ClientPolicyProvider(Function<Policy, ClientPolicyRepresentation> representationFunction) {
|
||||
this.representationFunction = representationFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
ClientPolicyRepresentation representation = representationFunction.apply(evaluation.getPolicy(), evaluation.getAuthorizationProvider());
|
||||
ClientPolicyRepresentation representation = representationFunction.apply(evaluation.getPolicy());
|
||||
AuthorizationProvider authorizationProvider = evaluation.getAuthorizationProvider();
|
||||
RealmModel realm = authorizationProvider.getKeycloakSession().getContext().getRealm();
|
||||
EvaluationContext context = evaluation.getContext();
|
||||
|
||||
+5
-5
@@ -30,7 +30,7 @@ import org.keycloak.util.JsonSerialization;
|
||||
|
||||
public class ClientPolicyProviderFactory implements PolicyProviderFactory<ClientPolicyRepresentation> {
|
||||
|
||||
private ClientPolicyProvider provider = new ClientPolicyProvider(this::toRepresentation);
|
||||
private ClientPolicyProvider provider = new ClientPolicyProvider(policy -> toRepresentation(policy));
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@@ -48,7 +48,7 @@ public class ClientPolicyProviderFactory implements PolicyProviderFactory<Client
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
public ClientPolicyRepresentation toRepresentation(Policy policy) {
|
||||
ClientPolicyRepresentation representation = new ClientPolicyRepresentation();
|
||||
representation.setClients(new HashSet<>(Arrays.asList(getClients(policy))));
|
||||
return representation;
|
||||
@@ -75,12 +75,12 @@ public class ClientPolicyProviderFactory implements PolicyProviderFactory<Client
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||
ClientPolicyRepresentation userRep = toRepresentation(policy, authorization);
|
||||
public void onExport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorizationProvider) {
|
||||
ClientPolicyRepresentation userRep = toRepresentation(policy);
|
||||
Map<String, String> config = new HashMap<>();
|
||||
|
||||
try {
|
||||
RealmModel realm = authorization.getRealm();
|
||||
RealmModel realm = authorizationProvider.getRealm();
|
||||
config.put("clients", JsonSerialization.writeValueAsString(userRep.getClients().stream().map(id -> realm.getClientById(id).getClientId()).collect(Collectors.toList())));
|
||||
} catch (IOException cause) {
|
||||
throw new RuntimeException("Failed to export user policy [" + policy.getName() + "]", cause);
|
||||
|
||||
Loaded 100 of 1093 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user