Compare commits
103
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a035b2c4ed | ||
|
|
812e76c39b | ||
|
|
8761819b24 | ||
|
|
47066e1b89 | ||
|
|
6a0a1031a1 | ||
|
|
33efcc6b93 | ||
|
|
2eddfd3ea8 | ||
|
|
bc8763ccf3 | ||
|
|
9f839f001f | ||
|
|
237318dfd3 | ||
|
|
5fe1905e4b | ||
|
|
f0ba8f6591 | ||
|
|
54b5ec206e | ||
|
|
befee75917 | ||
|
|
5ae126b10e | ||
|
|
c0b5c12dee | ||
|
|
214a8e1fed | ||
|
|
f89637bd8f | ||
|
|
bee3894cdf | ||
|
|
df76afb513 | ||
|
|
c266e90a77 | ||
|
|
b70468341e | ||
|
|
21b71e83dd | ||
|
|
ccba07a5c0 | ||
|
|
42553cdc44 | ||
|
|
8a7a545628 | ||
|
|
d37eb5d10b | ||
|
|
36837ae4b6 | ||
|
|
31270e2f52 | ||
|
|
3ccffdb77e | ||
|
|
56c97407d4 | ||
|
|
bf7a173e1e | ||
|
|
2077975b1c | ||
|
|
e4d05a7852 | ||
|
|
6fc99cd749 | ||
|
|
01b0b6b345 | ||
|
|
59082e0b5f | ||
|
|
9e072cb174 | ||
|
|
c0508aded7 | ||
|
|
9882341ecf | ||
|
|
3c2339ba33 | ||
|
|
457c6a9d80 | ||
|
|
1f840b1fbc | ||
|
|
694966b613 | ||
|
|
0a8fca7ec4 | ||
|
|
3e2e0ac91c | ||
|
|
b21e784826 | ||
|
|
dda365e002 | ||
|
|
653d3f4f5d | ||
|
|
3dcc106c59 | ||
|
|
248654a75e | ||
|
|
fdc9882709 | ||
|
|
b606a25684 | ||
|
|
1b88eaf817 | ||
|
|
dc8268b30c | ||
|
|
b80701589c | ||
|
|
d04791243c | ||
|
|
c5f861a522 | ||
|
|
b6d545b332 | ||
|
|
a35ed671e6 | ||
|
|
f0a2f7a675 | ||
|
|
4cb9944067 | ||
|
|
625f613128 | ||
|
|
e406e8f1f0 | ||
|
|
90bafee5eb | ||
|
|
ab77140454 | ||
|
|
d1ae13c208 | ||
|
|
e9604a49e1 | ||
|
|
645a72482b | ||
|
|
730377a843 | ||
|
|
f36e45cb10 | ||
|
|
ed72097862 | ||
|
|
0b95cdacb8 | ||
|
|
1912a8acf4 | ||
|
|
79774d2f07 | ||
|
|
fa8cb004a1 | ||
|
|
3449401ae2 | ||
|
|
02b2a8aab0 | ||
|
|
575851d45c | ||
|
|
060b3b8d0f | ||
|
|
a8a9631d4f | ||
|
|
2efc7ebb48 | ||
|
|
905fd3ae00 | ||
|
|
ee8c35a48e | ||
|
|
fb58214fcc | ||
|
|
4554798cec | ||
|
|
80e5227bcd | ||
|
|
65f51b7b83 | ||
|
|
72750b9882 | ||
|
|
27719565ae | ||
|
|
65030e2c73 | ||
|
|
b5d56e2f3b | ||
|
|
a63676ce93 | ||
|
|
01af40413e | ||
|
|
f6a4ba98de | ||
|
|
263792a4ab | ||
|
|
3380fdc119 | ||
|
|
959cd035ba | ||
|
|
e7e15652cf | ||
|
|
f57cc3a9c0 | ||
|
|
29da7d3d90 | ||
|
|
f99299ee39 | ||
|
|
ae47b7fa80 |
No files matched your search
+4
-1
@@ -8,6 +8,9 @@
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
||||
bin/
|
||||
.factorypath
|
||||
|
||||
|
||||
# NetBeans #
|
||||
############
|
||||
@@ -54,4 +57,4 @@ target
|
||||
##########
|
||||
# KEYCLOAK-5391: We will re-exclude node_modules when node_modules handling is worked out.
|
||||
# For now, we keep our js libraries checked into GitHub, so we don't ignore.
|
||||
#node_modules
|
||||
#node_modules
|
||||
+4
-1
@@ -1,5 +1,4 @@
|
||||
language: java
|
||||
dist: precise
|
||||
|
||||
cache:
|
||||
cache: false
|
||||
@@ -17,6 +16,7 @@ env:
|
||||
- TESTS=old
|
||||
- TESTS=crossdc-server
|
||||
- TESTS=crossdc-adapter
|
||||
- TESTS=ssl
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
@@ -36,4 +36,7 @@ before_install:
|
||||
script:
|
||||
- ./travis-run-tests.sh $TESTS
|
||||
|
||||
after_success:
|
||||
- .travis/docker-hub-master-trigger.sh
|
||||
|
||||
sudo: false
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$DOCKER_HUB_TOKEN" != "" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_REPO_SLUG" == "keycloak/keycloak" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
|
||||
curl -H "Content-Type: application/json" --data '{"docker_tag": "master"}' -X POST https://registry.hub.docker.com/u/jboss/keycloak/trigger/$DOCKER_HUB_TOKEN/
|
||||
echo "Triggered Docker hub build"
|
||||
elif [ "$DOCKER_HUB_TOKEN" != "" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_REPO_SLUG" == "keycloak/keycloak" ] && [ "$TRAVIS_BRANCH" == "openshift-integration2" ]; then
|
||||
curl -H "Content-Type: application/json" --data '{"docker_tag": "nightly-openshift-integration2"}' -X POST https://registry.hub.docker.com/u/jboss/keycloak/trigger/$DOCKER_HUB_TOKEN/
|
||||
echo "Triggered Docker hub build"
|
||||
fi
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class BasicAuthRequestAuthenticator extends BearerTokenRequestAuthenticat
|
||||
return authenticateToken(exchange, atr.getToken());
|
||||
}
|
||||
|
||||
private AccessTokenResponse getToken(String username, String password) throws Exception {
|
||||
protected AccessTokenResponse getToken(String username, String password) throws Exception {
|
||||
AccessTokenResponse tokenResponse=null;
|
||||
HttpClient client = deployment.getClient();
|
||||
|
||||
|
||||
+7
-2
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.keycloak.adapters.authorization;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -69,7 +70,11 @@ public abstract class AbstractPolicyEnforcer {
|
||||
if (securityContext == null) {
|
||||
if (!isDefaultAccessDeniedUri(request)) {
|
||||
if (pathConfig != null) {
|
||||
challenge(pathConfig, getRequiredScopes(pathConfig, request), httpFacade);
|
||||
if (EnforcementMode.DISABLED.equals(pathConfig.getEnforcementMode())) {
|
||||
return createEmptyAuthorizationContext(true);
|
||||
} else {
|
||||
challenge(pathConfig, getRequiredScopes(pathConfig, request), httpFacade);
|
||||
}
|
||||
} else {
|
||||
handleAccessDenied(httpFacade);
|
||||
}
|
||||
@@ -151,7 +156,7 @@ public abstract class AbstractPolicyEnforcer {
|
||||
}
|
||||
|
||||
boolean hasPermission = false;
|
||||
List<Permission> grantedPermissions = authorization.getPermissions();
|
||||
Collection<Permission> grantedPermissions = authorization.getPermissions();
|
||||
|
||||
for (Permission permission : grantedPermissions) {
|
||||
if (permission.getResourceId() != null) {
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@
|
||||
package org.keycloak.adapters.authorization;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -78,8 +78,8 @@ public class KeycloakAdapterPolicyEnforcer extends AbstractPolicyEnforcer {
|
||||
AccessToken.Authorization newAuthorization = accessToken.getAuthorization();
|
||||
|
||||
if (newAuthorization != null) {
|
||||
List<Permission> grantedPermissions = authorization.getPermissions();
|
||||
List<Permission> newPermissions = newAuthorization.getPermissions();
|
||||
Collection<Permission> grantedPermissions = authorization.getPermissions();
|
||||
Collection<Permission> newPermissions = newAuthorization.getPermissions();
|
||||
|
||||
for (Permission newPermission : newPermissions) {
|
||||
if (!grantedPermissions.contains(newPermission)) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -38,8 +38,21 @@
|
||||
|
||||
<modules>
|
||||
<module>camel-undertow</module>
|
||||
<module>jetty94</module>
|
||||
<module>tomcat8</module>
|
||||
<module>undertow</module>
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>community</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!product</name>
|
||||
</property>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>jetty94</module>
|
||||
<module>tomcat8</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-fuse7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -69,7 +69,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.ws.rs</groupId>
|
||||
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
|
||||
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -33,7 +33,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.ws.rs</groupId>
|
||||
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
|
||||
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+13
-11
@@ -216,6 +216,16 @@ declare namespace Keycloak {
|
||||
createdTimestamp?: number;
|
||||
}
|
||||
|
||||
interface KeycloakTokenParsed {
|
||||
exp?: number;
|
||||
iat?: number;
|
||||
nonce?: string;
|
||||
sub?: string;
|
||||
session_state?: string;
|
||||
realm_access?: { roles: string[] };
|
||||
resource_access?: string[];
|
||||
}
|
||||
|
||||
// export interface KeycloakUserInfo {}
|
||||
|
||||
/**
|
||||
@@ -269,15 +279,7 @@ declare namespace Keycloak {
|
||||
/**
|
||||
* The parsed token as a JavaScript object.
|
||||
*/
|
||||
tokenParsed?: {
|
||||
exp?: number;
|
||||
iat?: number;
|
||||
nonce?: string;
|
||||
sub?: string;
|
||||
session_state?: string;
|
||||
realm_access?: { roles: string[] };
|
||||
resource_access?: string[];
|
||||
};
|
||||
tokenParsed?: KeycloakTokenParsed;
|
||||
|
||||
/**
|
||||
* The base64 encoded refresh token that can be used to retrieve a new token.
|
||||
@@ -287,7 +289,7 @@ declare namespace Keycloak {
|
||||
/**
|
||||
* The parsed refresh token as a JavaScript object.
|
||||
*/
|
||||
refreshTokenParsed?: { nonce?: string };
|
||||
refreshTokenParsed?: KeycloakTokenParsed;
|
||||
|
||||
/**
|
||||
* The base64 encoded ID token.
|
||||
@@ -297,7 +299,7 @@ declare namespace Keycloak {
|
||||
/**
|
||||
* The parsed id token as a JavaScript object.
|
||||
*/
|
||||
idTokenParsed?: { nonce?: string };
|
||||
idTokenParsed?: KeycloakTokenParsed;
|
||||
|
||||
/**
|
||||
* The estimated time difference between the browser time and the Keycloak
|
||||
|
||||
@@ -910,7 +910,7 @@
|
||||
supportedParams = ['code', 'state', 'session_state'];
|
||||
break;
|
||||
case 'implicit':
|
||||
supportedParams = ['access_token', 'id_token', 'state', 'session_state'];
|
||||
supportedParams = ['access_token', 'token_type', 'id_token', 'state', 'session_state', 'expires_in'];
|
||||
break;
|
||||
case 'hybrid':
|
||||
supportedParams = ['access_token', 'id_token', 'code', 'state', 'session_state'];
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
@@ -87,6 +87,7 @@ public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
|
||||
if (!cacheConfiguration(pathFragment, configuration)) {
|
||||
throw new IllegalStateException("Not able to read the file " + configuration);
|
||||
}
|
||||
deployment = getCachedDeployment(pathFragment);
|
||||
}
|
||||
|
||||
return deployment;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OIDC Client Adapter Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -30,6 +30,17 @@
|
||||
<name>Keycloak Servlet Filter Adapter Integration</name>
|
||||
<description/>
|
||||
|
||||
<properties>
|
||||
<keycloak.osgi.export>
|
||||
org.keycloak.adapters.servlet.*
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
javax.servlet.*;version="[2.5,4)";resolution:=optional,
|
||||
org.keycloak.*;version="${project.version}",
|
||||
*;resolution:=optional
|
||||
</keycloak.osgi.import>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
@@ -94,6 +105,39 @@
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-ClassPath>.</Bundle-ClassPath>
|
||||
<Bundle-Name>${project.name}</Bundle-Name>
|
||||
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
||||
<Import-Package>${keycloak.osgi.import}</Import-Package>
|
||||
<Export-Package>${keycloak.osgi.export}</Export-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+20
-16
@@ -25,27 +25,16 @@ import org.apache.tomcat.util.descriptor.web.SecurityCollection;
|
||||
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
|
||||
import org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve;
|
||||
import org.keycloak.adapters.undertow.KeycloakServletExtension;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -187,7 +176,7 @@ public class KeycloakBaseSpringBootConfiguration {
|
||||
WebAppContext webAppContext = server.getBean(WebAppContext.class);
|
||||
//if not found as registered bean let's try the handler
|
||||
if(webAppContext==null){
|
||||
webAppContext = (WebAppContext) server.getHandler();
|
||||
webAppContext = getWebAppContext(server.getHandlers());
|
||||
}
|
||||
|
||||
ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
|
||||
@@ -196,6 +185,21 @@ public class KeycloakBaseSpringBootConfiguration {
|
||||
|
||||
webAppContext.setSecurityHandler(securityHandler);
|
||||
}
|
||||
|
||||
private WebAppContext getWebAppContext(Handler... handlers) {
|
||||
for (Handler handler : handlers) {
|
||||
if (handler instanceof WebAppContext) {
|
||||
return (WebAppContext) handler;
|
||||
} else if (handler instanceof HandlerList) {
|
||||
return getWebAppContext(((HandlerList) handler).getHandlers());
|
||||
} else if (handler instanceof HandlerCollection) {
|
||||
return getWebAppContext(((HandlerCollection) handler).getHandlers());
|
||||
} else if (handler instanceof HandlerWrapper) {
|
||||
return getWebAppContext(((HandlerWrapper) handler).getHandlers());
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No WebAppContext found in Jetty server handlers");
|
||||
}
|
||||
}
|
||||
|
||||
static class KeycloakBaseTomcatContextCustomizer {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package org.keycloak.adapters.springsecurity.authentication;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.RequestAuthenticator;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
|
||||
/**
|
||||
* Creates {@link RequestAuthenticator}s.
|
||||
*/
|
||||
public interface RequestAuthenticatorFactory {
|
||||
/**
|
||||
* Creates new {@link RequestAuthenticator} instances on a per-request basis.
|
||||
*/
|
||||
RequestAuthenticator createRequestAuthenticator(HttpFacade facade, HttpServletRequest request,
|
||||
KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort);
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package org.keycloak.adapters.springsecurity.authentication;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.RequestAuthenticator;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
|
||||
public class SpringSecurityRequestAuthenticatorFactory implements RequestAuthenticatorFactory {
|
||||
|
||||
@Override
|
||||
public RequestAuthenticator createRequestAuthenticator(HttpFacade facade,
|
||||
HttpServletRequest request, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort) {
|
||||
return new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, sslRedirectPort);
|
||||
}
|
||||
}
|
||||
+15
-5
@@ -27,16 +27,15 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.AuthenticatedActionsHandler;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.OIDCHttpFacade;
|
||||
import org.keycloak.adapters.RequestAuthenticator;
|
||||
import org.keycloak.adapters.spi.AuthChallenge;
|
||||
import org.keycloak.adapters.spi.AuthOutcome;
|
||||
import org.keycloak.adapters.spi.HttpFacade;
|
||||
import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException;
|
||||
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationFailureHandler;
|
||||
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticator;
|
||||
import org.keycloak.adapters.springsecurity.authentication.RequestAuthenticatorFactory;
|
||||
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticatorFactory;
|
||||
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||
import org.keycloak.adapters.springsecurity.token.AdapterTokenStoreFactory;
|
||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||
@@ -85,6 +84,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
|
||||
private AdapterDeploymentContext adapterDeploymentContext;
|
||||
private AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory();
|
||||
private AuthenticationManager authenticationManager;
|
||||
private RequestAuthenticatorFactory requestAuthenticatorFactory = new SpringSecurityRequestAuthenticatorFactory();
|
||||
|
||||
/**
|
||||
* Creates a new Keycloak authentication processing filter with given {@link AuthenticationManager} and the
|
||||
@@ -144,7 +144,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
|
||||
|
||||
AdapterTokenStore tokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, request);
|
||||
RequestAuthenticator authenticator
|
||||
= new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, -1);
|
||||
= requestAuthenticatorFactory.createRequestAuthenticator(facade, request, deployment, tokenStore, -1);
|
||||
|
||||
AuthOutcome result = authenticator.authenticate();
|
||||
log.debug("Auth outcome: {}", result);
|
||||
@@ -251,4 +251,14 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
|
||||
public final void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
|
||||
throw new UnsupportedOperationException("This filter does not support explicitly setting a continue chain before success policy");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request authenticator factory to use when creating per-request authenticators.
|
||||
*
|
||||
* @param requestAuthenticatorFactory the <code>RequestAuthenticatorFactory</code> to use
|
||||
*/
|
||||
public void setRequestAuthenticatorFactory(RequestAuthenticatorFactory requestAuthenticatorFactory) {
|
||||
Assert.notNull(requestAuthenticatorFactory, "RequestAuthenticatorFactory cannot be null");
|
||||
this.requestAuthenticatorFactory = requestAuthenticatorFactory;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Adapters</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+16
-1
@@ -42,6 +42,11 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.keycloak.adapters.cloned.HttpClientBuilder;
|
||||
import java.net.URI;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
@@ -205,8 +210,13 @@ public class DeploymentBuilder {
|
||||
Certificate cert = null;
|
||||
try {
|
||||
cert = keyStore.getCertificate(key.getKeystore().getCertificateAlias());
|
||||
if (cert instanceof X509Certificate) {
|
||||
((X509Certificate) cert).checkValidity();
|
||||
}
|
||||
} catch (KeyStoreException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (CertificateException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
publicKey = cert.getPublicKey();
|
||||
} else {
|
||||
@@ -224,7 +234,12 @@ public class DeploymentBuilder {
|
||||
if (key.getPublicKeyPem() != null) {
|
||||
publicKey = PemUtils.decodePublicKey(key.getPublicKeyPem().trim());
|
||||
} else {
|
||||
Certificate cert = PemUtils.decodeCertificate(key.getCertificatePem().trim());
|
||||
X509Certificate cert = PemUtils.decodeCertificate(key.getCertificatePem().trim());
|
||||
try {
|
||||
cert.checkValidity();
|
||||
} catch (CertificateException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
publicKey = cert.getPublicKey();
|
||||
}
|
||||
return publicKey;
|
||||
|
||||
+4
-2
@@ -84,6 +84,7 @@ import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
|
||||
import org.keycloak.rotation.KeyLocator;
|
||||
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
||||
import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
|
||||
import org.keycloak.saml.validators.DestinationValidator;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -97,6 +98,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
||||
protected final SamlSessionStore sessionStore;
|
||||
protected final SamlDeployment deployment;
|
||||
protected AuthChallenge challenge;
|
||||
private final DestinationValidator destinationValidator = DestinationValidator.forProtocolMap(null);
|
||||
|
||||
public AbstractSamlAuthenticationHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
|
||||
this.facade = facade;
|
||||
@@ -145,7 +147,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
||||
holder = SAMLRequestParser.parseRequestPostBinding(samlRequest);
|
||||
}
|
||||
RequestAbstractType requestAbstractType = (RequestAbstractType) holder.getSamlObject();
|
||||
if (!requestUri.equals(requestAbstractType.getDestination().toString())) {
|
||||
if (! destinationValidator.validate(requestUri, requestAbstractType.getDestination())) {
|
||||
log.error("expected destination '" + requestUri + "' got '" + requestAbstractType.getDestination() + "'");
|
||||
return AuthOutcome.FAILED;
|
||||
}
|
||||
@@ -186,7 +188,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
|
||||
}
|
||||
final StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject();
|
||||
// validate destination
|
||||
if (!requestUri.equals(statusResponse.getDestination())) {
|
||||
if (! destinationValidator.validate(requestUri, statusResponse.getDestination())) {
|
||||
log.error("Request URI '" + requestUri + "' does not match SAML request destination '" + statusResponse.getDestination() + "'");
|
||||
return AuthOutcome.FAILED;
|
||||
}
|
||||
|
||||
+6
@@ -36,6 +36,7 @@ import org.keycloak.common.util.Time;
|
||||
import org.keycloak.dom.saml.v2.metadata.KeyTypes;
|
||||
import org.keycloak.rotation.KeyLocator;
|
||||
import org.keycloak.saml.processing.api.util.KeyInfoTools;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
/**
|
||||
* This class defines a {@link KeyLocator} that looks up public keys and certificates in IdP's
|
||||
@@ -147,6 +148,11 @@ public class SamlDescriptorPublicKeyLocator implements KeyLocator, Iterable<Publ
|
||||
for (KeyInfo ki : signingCerts) {
|
||||
KeyName keyName = KeyInfoTools.getKeyName(ki);
|
||||
X509Certificate x509certificate = KeyInfoTools.getX509Certificate(ki);
|
||||
try {
|
||||
x509certificate.checkValidity();
|
||||
} catch (CertificateException ex) {
|
||||
x509certificate = null;
|
||||
}
|
||||
if (x509certificate != null && keyName != null) {
|
||||
LOG.tracef("Registering signing certificate %s", keyName.getName());
|
||||
this.publicKeyCache.put(keyName.getName(), x509certificate.getPublicKey());
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -30,6 +30,16 @@
|
||||
<name>Keycloak Servlet Integration</name>
|
||||
<description/>
|
||||
|
||||
<properties>
|
||||
<keycloak.osgi.export>
|
||||
org.keycloak.adapters.servlet.*
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
*;resolution:=optional
|
||||
</keycloak.osgi.import>
|
||||
<keycloak.osgi.fragment>${project.groupId}.keycloak-servlet-filter-adapter</keycloak.osgi.fragment>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
@@ -64,6 +74,40 @@
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-ClassPath>.</Bundle-ClassPath>
|
||||
<Bundle-Name>${project.name}</Bundle-Name>
|
||||
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
||||
<Import-Package>${keycloak.osgi.import}</Import-Package>
|
||||
<Export-Package>${keycloak.osgi.export}</Export-Package>
|
||||
<Fragment-Host>${keycloak.osgi.fragment}</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</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.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class AuthzClient {
|
||||
/**
|
||||
* <p>Creates a {@link ProtectionResource} instance which can be used to access the Protection API.
|
||||
*
|
||||
* @param the PAT (the access token with the uma_protection scope)
|
||||
* @param accessToken the PAT (the access token with the uma_protection scope)
|
||||
* @return a {@link ProtectionResource}
|
||||
*/
|
||||
public ProtectionResource protection(final String accessToken) {
|
||||
|
||||
+4
-4
@@ -69,7 +69,7 @@ public class PolicyResource {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception cause) {
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error creating policy for resurce [" + resourceId + "]", cause);
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error creating policy for resource [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class PolicyResource {
|
||||
try {
|
||||
callable.call();
|
||||
} catch (Exception cause) {
|
||||
Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error updating policy for resurce [" + resourceId + "]", cause);
|
||||
Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error updating policy for resource [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ public class PolicyResource {
|
||||
try {
|
||||
callable.call();
|
||||
} catch (Exception cause) {
|
||||
Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error updating policy for resurce [" + resourceId + "]", cause);
|
||||
Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error updating policy for resource [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ public class PolicyResource {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception cause) {
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error creating policy for resurce [" + resourceId + "]", cause);
|
||||
return Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Error creating policy for resource [" + resourceId + "]", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-46
@@ -17,14 +17,14 @@
|
||||
*/
|
||||
package org.keycloak.authorization.client.resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.keycloak.authorization.client.Configuration;
|
||||
import org.keycloak.authorization.client.representation.ServerConfiguration;
|
||||
import org.keycloak.authorization.client.util.Http;
|
||||
import org.keycloak.authorization.client.util.HttpMethod;
|
||||
import org.keycloak.authorization.client.util.Throwables;
|
||||
import org.keycloak.authorization.client.util.TokenCallable;
|
||||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
@@ -128,13 +128,13 @@ public class ProtectedResource {
|
||||
* @return a {@link ResourceRepresentation}
|
||||
*/
|
||||
public ResourceRepresentation findByName(String name) {
|
||||
String[] representations = find(null, name, null, configuration.getResource(), null, null, false, null, null);
|
||||
List<ResourceRepresentation> representations = find(null, name, null, configuration.getResource(), null, null, false, true, null, null);
|
||||
|
||||
if (representations.length == 0) {
|
||||
if (representations.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findById(representations[0]);
|
||||
return representations.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,13 +145,13 @@ public class ProtectedResource {
|
||||
* @return a {@link ResourceRepresentation}
|
||||
*/
|
||||
public ResourceRepresentation findByName(String name, String ownerId) {
|
||||
String[] representations = find(null, name, null, ownerId, null, null, false, null, null);
|
||||
List<ResourceRepresentation> representations = find(null, name, null, ownerId, null, null, false, true,null, null);
|
||||
|
||||
if (representations.length == 0) {
|
||||
if (representations.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findById(representations[0]);
|
||||
return representations.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,19 +172,7 @@ public class ProtectedResource {
|
||||
Callable<String[]> callable = new Callable<String[]>() {
|
||||
@Override
|
||||
public String[] call() throws Exception {
|
||||
return http.<String[]>get(serverConfiguration.getResourceRegistrationEndpoint())
|
||||
.authorizationBearer(pat.call())
|
||||
.param("_id", id)
|
||||
.param("name", name)
|
||||
.param("uri", uri)
|
||||
.param("owner", owner)
|
||||
.param("type", type)
|
||||
.param("scope", scope)
|
||||
.param("matchingUri", Boolean.valueOf(matchingUri).toString())
|
||||
.param("deep", Boolean.FALSE.toString())
|
||||
.param("first", firstResult != null ? firstResult.toString() : null)
|
||||
.param("max", maxResult != null ? maxResult.toString() : null)
|
||||
.response().json(String[].class).execute();
|
||||
return (String[]) createFindRequest(id, name, uri, owner, type, scope, matchingUri, false, firstResult, maxResult).response().json(String[].class).execute();
|
||||
}
|
||||
};
|
||||
try {
|
||||
@@ -194,6 +182,40 @@ public class ProtectedResource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the server for any resource with the matching arguments.
|
||||
*
|
||||
* @param id the resource id
|
||||
* @param name the resource name
|
||||
* @param uri the resource uri
|
||||
* @param owner the resource owner
|
||||
* @param type the resource type
|
||||
* @param scope the resource scope
|
||||
* @param matchingUri the resource uri. Use this parameter to lookup a resource that best match the given uri
|
||||
* @param deep if the result should be a list of resource representations with details about the resource. If false, only ids are returned
|
||||
* @param firstResult the position of the first resource to retrieve
|
||||
* @param maxResult the maximum number of resources to retrieve
|
||||
* @return a list of resource representations or an array of strings representing resource ids, depending on the generic type
|
||||
*/
|
||||
public <R> R find(final String id, final String name, final String uri, final String owner, final String type, final String scope, final boolean matchingUri, final boolean deep, final Integer firstResult, final Integer maxResult) {
|
||||
if (deep) {
|
||||
Callable<List<ResourceRepresentation>> callable = new Callable<List<ResourceRepresentation>>() {
|
||||
@Override
|
||||
public List<ResourceRepresentation> call() {
|
||||
return (List<ResourceRepresentation>) createFindRequest(id, name, uri, owner, type, scope, matchingUri, deep, firstResult, maxResult).response().json(new TypeReference<List<ResourceRepresentation>>() {
|
||||
}).execute();
|
||||
}
|
||||
};
|
||||
try {
|
||||
return (R) callable.call();
|
||||
} catch (Exception cause) {
|
||||
return (R) Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Could not find resource", cause);
|
||||
}
|
||||
}
|
||||
|
||||
return (R) find(id, name, uri, owner, type, scope, matchingUri, firstResult, maxResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the server for all resources.
|
||||
*
|
||||
@@ -235,19 +257,7 @@ public class ProtectedResource {
|
||||
* @param uri the resource uri
|
||||
*/
|
||||
public List<ResourceRepresentation> findByUri(String uri) {
|
||||
String[] ids = find(null, null, uri, null, null, null, false, null, null);
|
||||
|
||||
if (ids.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<ResourceRepresentation> representations = new ArrayList<>();
|
||||
|
||||
for (String id : ids) {
|
||||
representations.add(findById(id));
|
||||
}
|
||||
|
||||
return representations;
|
||||
return find(null, null, uri, null, null, null, false, true, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,18 +268,21 @@ public class ProtectedResource {
|
||||
* @return a list of resources
|
||||
*/
|
||||
public List<ResourceRepresentation> findByMatchingUri(String uri) {
|
||||
String[] ids = find(null, null, uri, null, null, null, true, null, null);
|
||||
return find(null, null, uri, null, null, null, true, true,null, null);
|
||||
}
|
||||
|
||||
if (ids.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<ResourceRepresentation> representations = new ArrayList<>();
|
||||
|
||||
for (String id : ids) {
|
||||
representations.add(findById(id));
|
||||
}
|
||||
|
||||
return representations;
|
||||
private HttpMethod createFindRequest(String id, String name, String uri, String owner, String type, String scope, boolean matchingUri, boolean deep, Integer firstResult, Integer maxResult) {
|
||||
return http.get(serverConfiguration.getResourceRegistrationEndpoint())
|
||||
.authorizationBearer(pat.call())
|
||||
.param("_id", id)
|
||||
.param("name", name)
|
||||
.param("uri", uri)
|
||||
.param("owner", owner)
|
||||
.param("type", type)
|
||||
.param("scope", scope)
|
||||
.param("matchingUri", Boolean.valueOf(matchingUri).toString())
|
||||
.param("deep", Boolean.toString(deep))
|
||||
.param("first", firstResult != null ? firstResult.toString() : null)
|
||||
.param("max", maxResult != null ? maxResult.toString() : null);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authz-provider-parent</artifactId>
|
||||
<version>4.2.0.Final-SNAPSHOT</version>
|
||||
<version>4.4.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+31
-17
@@ -17,10 +17,15 @@
|
||||
*/
|
||||
package org.keycloak.authorization.policy.provider.aggregated;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DecisionResultCollector;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
@@ -34,31 +39,40 @@ public class AggregatePolicyProvider implements PolicyProvider {
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
//TODO: need to detect deep recursions
|
||||
DecisionResultCollector decision = new DecisionResultCollector() {
|
||||
@Override
|
||||
protected void onComplete(List<Result> results) {
|
||||
if (results.isEmpty()) {
|
||||
evaluation.deny();
|
||||
protected void onComplete(Result result) {
|
||||
if (isGranted(result.getResults().iterator().next())) {
|
||||
evaluation.grant();
|
||||
} else {
|
||||
Result result = results.iterator().next();
|
||||
|
||||
if (Effect.PERMIT.equals(result.getEffect())) {
|
||||
evaluation.grant();
|
||||
}
|
||||
evaluation.deny();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Policy policy = evaluation.getPolicy();
|
||||
AuthorizationProvider authorization = evaluation.getAuthorizationProvider();
|
||||
Policy policy = evaluation.getPolicy();
|
||||
DefaultEvaluation defaultEvaluation = DefaultEvaluation.class.cast(evaluation);
|
||||
Map<Policy, Map<Object, Decision.Effect>> decisionCache = defaultEvaluation.getDecisionCache();
|
||||
ResourcePermission permission = evaluation.getPermission();
|
||||
|
||||
policy.getAssociatedPolicies().forEach(associatedPolicy -> {
|
||||
PolicyProvider policyProvider = authorization.getProvider(associatedPolicy.getType());
|
||||
policyProvider.evaluate(new DefaultEvaluation(evaluation.getPermission(), evaluation.getContext(), policy, associatedPolicy, decision, authorization));
|
||||
});
|
||||
for (Policy associatedPolicy : policy.getAssociatedPolicies()) {
|
||||
Map<Object, Decision.Effect> decisions = decisionCache.computeIfAbsent(associatedPolicy, p -> new HashMap<>());
|
||||
Decision.Effect effect = decisions.get(permission);
|
||||
DefaultEvaluation eval = new DefaultEvaluation(evaluation.getPermission(), evaluation.getContext(), policy, associatedPolicy, decision, authorization, decisionCache);
|
||||
|
||||
decision.onComplete();
|
||||
if (effect == null) {
|
||||
PolicyProvider policyProvider = authorization.getProvider(associatedPolicy.getType());
|
||||
|
||||
policyProvider.evaluate(eval);
|
||||
|
||||
eval.denyIfNoEffect();
|
||||
decisions.put(permission, eval.getEffect());
|
||||
} else {
|
||||
eval.setEffect(effect);
|
||||
}
|
||||
}
|
||||
|
||||
decision.onComplete(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-6
@@ -19,6 +19,9 @@ package org.keycloak.authorization.policy.provider.js;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.SimpleScriptContext;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
@@ -40,14 +43,14 @@ class JSPolicyProvider implements PolicyProvider {
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
Policy policy = evaluation.getPolicy();
|
||||
AuthorizationProvider authorization = evaluation.getAuthorizationProvider();
|
||||
final EvaluatableScriptAdapter adapter = evaluatableScript.apply(authorization, policy);
|
||||
EvaluatableScriptAdapter adapter = evaluatableScript.apply(authorization, policy);
|
||||
|
||||
try {
|
||||
//how to deal with long running scripts -> timeout?
|
||||
adapter.eval(bindings -> {
|
||||
bindings.put("script", adapter.getScriptModel());
|
||||
bindings.put("$evaluation", evaluation);
|
||||
});
|
||||
SimpleScriptContext context = new SimpleScriptContext();
|
||||
|
||||
context.setAttribute("$evaluation", evaluation, ScriptContext.ENGINE_SCOPE);
|
||||
|
||||
adapter.eval(context);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("Error evaluating JS Policy [" + policy.getName() + "].", e);
|
||||
|
||||
+6
-24
@@ -67,6 +67,12 @@ public class ScriptCache {
|
||||
|
||||
public EvaluatableScriptAdapter computeIfAbsent(String id, Function<String, EvaluatableScriptAdapter> function) {
|
||||
try {
|
||||
EvaluatableScriptAdapter adapter = removeIfExpired(cache.get(id));
|
||||
|
||||
if (adapter != null) {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
if (parkForWriteAndCheckInterrupt()) {
|
||||
return null;
|
||||
}
|
||||
@@ -83,20 +89,6 @@ public class ScriptCache {
|
||||
}
|
||||
}
|
||||
|
||||
public EvaluatableScriptAdapter get(String uri) {
|
||||
if (parkForReadAndCheckInterrupt()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CacheEntry cached = cache.get(uri);
|
||||
|
||||
if (cached != null) {
|
||||
return removeIfExpired(cached);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void remove(String key) {
|
||||
try {
|
||||
if (parkForWriteAndCheckInterrupt()) {
|
||||
@@ -132,16 +124,6 @@ public class ScriptCache {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean parkForReadAndCheckInterrupt() {
|
||||
while (writing.get()) {
|
||||
LockSupport.parkNanos(1L);
|
||||
if (Thread.interrupted()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final class CacheEntry {
|
||||
|
||||
final String key;
|
||||
|
||||
+23
-14
@@ -17,34 +17,43 @@
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class AbstractPermissionProvider implements PolicyProvider {
|
||||
|
||||
public AbstractPermissionProvider() {
|
||||
|
||||
}
|
||||
public abstract class AbstractPermissionProvider implements PolicyProvider {
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
if (!(evaluation instanceof DefaultEvaluation)) {
|
||||
throw new IllegalArgumentException("Unexpected evaluation instance type [" + evaluation.getClass() + "]");
|
||||
}
|
||||
|
||||
Policy policy = evaluation.getPolicy();
|
||||
AuthorizationProvider authorization = evaluation.getAuthorizationProvider();
|
||||
DefaultEvaluation defaultEvaluation = DefaultEvaluation.class.cast(evaluation);
|
||||
Map<Policy, Map<Object, Decision.Effect>> decisionCache = defaultEvaluation.getDecisionCache();
|
||||
Policy policy = evaluation.getPolicy();
|
||||
ResourcePermission permission = evaluation.getPermission();
|
||||
|
||||
policy.getAssociatedPolicies().forEach(associatedPolicy -> {
|
||||
PolicyProvider policyProvider = authorization.getProvider(associatedPolicy.getType());
|
||||
DefaultEvaluation.class.cast(evaluation).setPolicy(associatedPolicy);
|
||||
policyProvider.evaluate(evaluation);
|
||||
evaluation.denyIfNoEffect();
|
||||
Map<Object, Decision.Effect> decisions = decisionCache.computeIfAbsent(associatedPolicy, p -> new HashMap<>());
|
||||
Decision.Effect effect = decisions.get(permission);
|
||||
|
||||
defaultEvaluation.setPolicy(associatedPolicy);
|
||||
|
||||
if (effect == null) {
|
||||
PolicyProvider policyProvider = authorization.getProvider(associatedPolicy.getType());
|
||||
policyProvider.evaluate(defaultEvaluation);
|
||||
evaluation.denyIfNoEffect();
|
||||
decisions.put(permission, defaultEvaluation.getEffect());
|
||||
} else {
|
||||
defaultEvaluation.setEffect(effect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+27
@@ -16,9 +16,36 @@
|
||||
*/
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class ResourcePolicyProvider extends AbstractPermissionProvider {
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
DefaultEvaluation defaultEvaluation = DefaultEvaluation.class.cast(evaluation);
|
||||
Map<Policy, Map<Object, Decision.Effect>> decisionCache = defaultEvaluation.getDecisionCache();
|
||||
Policy policy = defaultEvaluation.getParentPolicy();
|
||||
Map<Object, Decision.Effect> decisions = decisionCache.computeIfAbsent(policy, p -> new HashMap<>());
|
||||
ResourcePermission permission = evaluation.getPermission();
|
||||
Decision.Effect effect = decisions.get(permission.getResource());
|
||||
|
||||
if (effect != null) {
|
||||
defaultEvaluation.setEffect(effect);
|
||||
return;
|
||||
}
|
||||
|
||||
super.evaluate(evaluation);
|
||||
|
||||
decisions.put(permission.getResource(), defaultEvaluation.getEffect());
|
||||
}
|
||||
}
|
||||
+33
@@ -16,9 +16,42 @@
|
||||
*/
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class ScopePolicyProvider extends AbstractPermissionProvider {
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
DefaultEvaluation defaultEvaluation = DefaultEvaluation.class.cast(evaluation);
|
||||
Map<Policy, Map<Object, Decision.Effect>> decisionCache = defaultEvaluation.getDecisionCache();
|
||||
Policy policy = defaultEvaluation.getParentPolicy();
|
||||
Map<Object, Decision.Effect> decisions = decisionCache.computeIfAbsent(policy, p -> new HashMap<>());
|
||||
ResourcePermission permission = evaluation.getPermission();
|
||||
|
||||
Decision.Effect effect = decisions.get(permission);
|
||||
|
||||
if (effect != null) {
|
||||
defaultEvaluation.setEffect(effect);
|
||||
return;
|
||||
}
|
||||
|
||||
Decision.Effect decision = defaultEvaluation.getEffect();
|
||||
|
||||
if (decision == null) {
|
||||
super.evaluate(evaluation);
|
||||
|
||||
decisions.put(permission, defaultEvaluation.getEffect());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 1071 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user