creds = new HashMap<>();
+ creds.put("secret", secret);
+ config.setCredentials(creds);
+ } else {
+ config.setPublicClient(true);
+ }
+ return config;
+ }
+
+ public boolean checkToken() throws Exception {
+ String token = getTokenResponse();
+ if (token == null) return false;
+
+
+ if (token != null) {
+ Matcher m = Pattern.compile("\\{.*\\}\\z").matcher(token);
+ if (m.find()) {
+ String json = m.group(0);
+ try {
+ AccessTokenResponse tokenResponse = JsonSerialization.readValue(json, AccessTokenResponse.class);
+ if (Time.currentTime() < tokenResponse.getExpiresIn()) {
+ return true;
+ }
+ AdapterConfig config = getConfig();
+ KeycloakInstalled installed = new KeycloakInstalled(KeycloakDeploymentBuilder.build(config));
+ installed.refreshToken(tokenResponse.getRefreshToken());
+ processResponse(installed);
+ return true;
+ } catch (Exception e) {
+ System.err.println("Error processing existing token");
+ e.printStackTrace();
+ }
+
+ }
+ }
+ return false;
+
+ }
+
+ private String getTokenResponse() throws IOException {
+ String token = null;
+ File tokenFile = getTokenFilePath();
+ if (tokenFile.exists()) {
+ FileInputStream fis = new FileInputStream(tokenFile);
+ byte[] data = new byte[(int) tokenFile.length()];
+ fis.read(data);
+ fis.close();
+ token = new String(data, "UTF-8");
+ }
+ return token;
+ }
+
+ public void token() throws Exception {
+ String token = getTokenResponse();
+ if (token == null) {
+ System.err.println("There is no token for client");
+ System.exit(1);
+ } else {
+ Matcher m = Pattern.compile("\\{.*\\}\\z").matcher(token);
+ if (m.find()) {
+ String json = m.group(0);
+ try {
+ AccessTokenResponse tokenResponse = JsonSerialization.readValue(json, AccessTokenResponse.class);
+ if (Time.currentTime() < tokenResponse.getExpiresIn()) {
+ System.out.println(tokenResponse.getToken());
+ return;
+ } else {
+ System.err.println("token in response file is expired");
+ System.exit(1);
+ }
+ } catch (Exception e) {
+ System.err.println("Failure processing token response file");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ } else {
+ System.err.println("Could not find json within token response file");
+ System.exit(1);
+ }
+ }
+ }
+
+ public void login() throws Exception {
+ if (checkToken()) return;
+ AdapterConfig config = getConfig();
+ KeycloakInstalled installed = new KeycloakInstalled(KeycloakDeploymentBuilder.build(config));
+ installed.login();
+ processResponse(installed);
+ }
+
+ public String getHome() {
+ String home = System.getenv("HOME");
+ if (home == null) {
+ home = System.getProperty("HOME");
+ if (home == null) {
+ home = Paths.get("").toAbsolutePath().normalize().toString();
+ }
+ }
+ return home;
+ }
+
+ public File getTokenDirectory() {
+ return Paths.get(getHome(), System.getProperty("basepath", ".keycloak-sso"), System.getProperty("KEYCLOAK_REALM")).toFile();
+ }
+
+ public File getTokenFilePath() {
+ return Paths.get(getHome(), System.getProperty("basepath", ".keycloak-sso"), System.getProperty("KEYCLOAK_REALM"), System.getProperty("KEYCLOAK_CLIENT") + ".json").toFile();
+ }
+
+ private void processResponse(KeycloakInstalled installed) throws IOException {
+ AccessTokenResponse tokenResponse = installed.getTokenResponse();
+ tokenResponse.setExpiresIn(Time.currentTime() + tokenResponse.getExpiresIn());
+ tokenResponse.setIdToken(null);
+ String output = JsonSerialization.writeValueAsString(tokenResponse);
+ getTokenDirectory().mkdirs();
+ FileOutputStream fos = new FileOutputStream(getTokenFilePath());
+ fos.write(output.getBytes("UTF-8"));
+ fos.flush();
+ fos.close();
+ System.out.println(tokenResponse.getToken());
+ }
+
+ public void loginManual() throws Exception {
+ if (checkToken()) return;
+ AdapterConfig config = getConfig();
+ KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(config);
+ KeycloakInstalled installed = new KeycloakInstalled(deployment);
+ installed.loginManual();
+ processResponse(installed);
+ }
+
+ public void logout() throws Exception {
+ String token = getTokenResponse();
+ if (token != null) {
+ Matcher m = Pattern.compile("\\{.*\\}\\z").matcher(token);
+ if (m.find()) {
+ String json = m.group(0);
+ try {
+ AccessTokenResponse tokenResponse = JsonSerialization.readValue(json, AccessTokenResponse.class);
+ if (Time.currentTime() > tokenResponse.getExpiresIn()) {
+ System.err.println("Login is expired");
+ System.exit(1);
+ }
+ AdapterConfig config = getConfig();
+ KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(config);
+ ServerRequest.invokeLogout(deployment, tokenResponse.getRefreshToken());
+ for (File fp : getTokenDirectory().listFiles()) fp.delete();
+ System.out.println("logout complete");
+ } catch (Exception e) {
+ System.err.println("Failure processing token response file");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ } else {
+ System.err.println("Could not find json within token response file");
+ System.exit(1);
+ }
+ } else {
+ System.err.println("Not logged in");
+ System.exit(1);
+ }
+ }
+}
diff --git a/adapters/oidc/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java b/adapters/oidc/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
index 9834fe24de..61ca06e520 100644
--- a/adapters/oidc/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
+++ b/adapters/oidc/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
@@ -17,6 +17,7 @@
package org.keycloak.adapters.installed;
+import org.apache.commons.codec.Charsets;
import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException;
import org.keycloak.adapters.KeycloakDeployment;
@@ -24,6 +25,7 @@ import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.ServerRequest;
import org.keycloak.adapters.rotation.AdapterRSATokenVerifier;
import org.keycloak.common.VerificationException;
+import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.representations.AccessToken;
@@ -43,6 +45,7 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -51,6 +54,11 @@ import java.util.concurrent.TimeUnit;
*/
public class KeycloakInstalled {
+ public interface HttpResponseWriter {
+ void success(PrintWriter pw, KeycloakInstalled ki);
+ void failure(PrintWriter pw, KeycloakInstalled ki);
+ }
+
private static final String KEYCLOAK_JSON = "META-INF/keycloak.json";
private KeycloakDeployment deployment;
@@ -59,12 +67,18 @@ public class KeycloakInstalled {
LOGGED_MANUAL, LOGGED_DESKTOP
}
+ private AccessTokenResponse tokenResponse;
private String tokenString;
private String idTokenString;
private IDToken idToken;
private AccessToken token;
private String refreshToken;
private Status status;
+ private Locale locale;
+ private HttpResponseWriter loginResponseWriter;
+ private HttpResponseWriter logoutResponseWriter;
+
+
public KeycloakInstalled() {
InputStream config = Thread.currentThread().getContextClassLoader().getResourceAsStream(KEYCLOAK_JSON);
@@ -75,6 +89,92 @@ public class KeycloakInstalled {
deployment = KeycloakDeploymentBuilder.build(config);
}
+ public KeycloakInstalled(KeycloakDeployment deployment) {
+ this.deployment = deployment;
+ }
+
+ private static HttpResponseWriter defaultLoginWriter = new HttpResponseWriter() {
+ @Override
+ public void success(PrintWriter pw, KeycloakInstalled ki) {
+ pw.println("HTTP/1.1 200 OK");
+ pw.println("Content-Type: text/html");
+ pw.println();
+ pw.println("Login completed.
");
+ pw.println("This browser will remain logged in until you close it, logout, or the session expires.");
+ pw.println("
");
+ pw.flush();
+
+ }
+
+ @Override
+ public void failure(PrintWriter pw, KeycloakInstalled ki) {
+ pw.println("HTTP/1.1 200 OK");
+ pw.println("Content-Type: text/html");
+ pw.println();
+ pw.println("Login attempt failed.
");
+ pw.println("
");
+ pw.flush();
+
+ }
+ };
+ private static HttpResponseWriter defaultLogoutWriter = new HttpResponseWriter() {
+ @Override
+ public void success(PrintWriter pw, KeycloakInstalled ki) {
+ pw.println("HTTP/1.1 200 OK");
+ pw.println("Content-Type: text/html");
+ pw.println();
+ pw.println("Logout completed.
");
+ pw.println("You may close this browser tab.");
+ pw.println("
");
+ pw.flush();
+
+ }
+
+ @Override
+ public void failure(PrintWriter pw, KeycloakInstalled ki) {
+ pw.println("HTTP/1.1 200 OK");
+ pw.println("Content-Type: text/html");
+ pw.println();
+ pw.println("Logout failed.
");
+ pw.println("You may close this browser tab.");
+ pw.println("
");
+ pw.flush();
+
+ }
+ };
+
+ public HttpResponseWriter getLoginResponseWriter() {
+ if (loginResponseWriter == null) {
+ return defaultLoginWriter;
+ } else {
+ return loginResponseWriter;
+ }
+ }
+
+ public HttpResponseWriter getLogoutResponseWriter() {
+ if (logoutResponseWriter == null) {
+ return defaultLogoutWriter;
+ } else {
+ return logoutResponseWriter;
+ }
+ }
+
+ public void setLoginResponseWriter(HttpResponseWriter loginResponseWriter) {
+ this.loginResponseWriter = loginResponseWriter;
+ }
+
+ public void setLogoutResponseWriter(HttpResponseWriter logoutResponseWriter) {
+ this.logoutResponseWriter = logoutResponseWriter;
+ }
+
+ public Locale getLocale() {
+ return locale;
+ }
+
+ public void setLocale(Locale locale) {
+ this.locale = locale;
+ }
+
public void login() throws IOException, ServerRequest.HttpFailure, VerificationException, InterruptedException, OAuthErrorException, URISyntaxException {
if (isDesktopSupported()) {
loginDesktop();
@@ -108,19 +208,22 @@ public class KeycloakInstalled {
}
public void loginDesktop() throws IOException, VerificationException, OAuthErrorException, URISyntaxException, ServerRequest.HttpFailure, InterruptedException {
- CallbackListener callback = new CallbackListener();
+ CallbackListener callback = new CallbackListener(getLoginResponseWriter());
callback.start();
String redirectUri = "http://localhost:" + callback.server.getLocalPort();
String state = UUID.randomUUID().toString();
- String authUrl = deployment.getAuthUrl().clone()
+ KeycloakUriBuilder builder = deployment.getAuthUrl().clone()
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
.queryParam(OAuth2Constants.STATE, state)
- .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
- .build().toString();
+ .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID);
+ if (locale != null) {
+ builder.queryParam(OAuth2Constants.UI_LOCALES_PARAM, locale.getLanguage());
+ }
+ String authUrl = builder.build().toString();
Desktop.getDesktop().browse(new URI(authUrl));
@@ -144,7 +247,7 @@ public class KeycloakInstalled {
}
private void logoutDesktop() throws IOException, URISyntaxException, InterruptedException {
- CallbackListener callback = new CallbackListener();
+ CallbackListener callback = new CallbackListener(getLogoutResponseWriter());
callback.start();
String redirectUri = "http://localhost:" + callback.server.getLocalPort();
@@ -167,9 +270,6 @@ public class KeycloakInstalled {
}
public void loginManual(PrintStream printer, Reader reader) throws IOException, ServerRequest.HttpFailure, VerificationException {
- CallbackListener callback = new CallbackListener();
- callback.start();
-
String redirectUri = "urn:ietf:wg:oauth:2.0:oob";
String authUrl = deployment.getAuthUrl().clone()
@@ -208,7 +308,14 @@ public class KeycloakInstalled {
parseAccessToken(tokenResponse);
}
+ public void refreshToken(String refreshToken) throws IOException, ServerRequest.HttpFailure, VerificationException {
+ AccessTokenResponse tokenResponse = ServerRequest.invokeRefresh(deployment, refreshToken);
+ parseAccessToken(tokenResponse);
+
+ }
+
private void parseAccessToken(AccessTokenResponse tokenResponse) throws VerificationException {
+ this.tokenResponse = tokenResponse;
tokenString = tokenResponse.getToken();
refreshToken = tokenResponse.getRefreshToken();
idTokenString = tokenResponse.getIdToken();
@@ -240,6 +347,10 @@ public class KeycloakInstalled {
return refreshToken;
}
+ public AccessTokenResponse getTokenResponse() {
+ return tokenResponse;
+ }
+
public boolean isDesktopSupported() {
return Desktop.isDesktopSupported();
}
@@ -248,6 +359,8 @@ public class KeycloakInstalled {
return deployment;
}
+
+
private void processCode(String code, String redirectUri) throws IOException, ServerRequest.HttpFailure, VerificationException {
AccessTokenResponse tokenResponse = ServerRequest.invokeAccessCodeToToken(deployment, code, redirectUri, null);
parseAccessToken(tokenResponse);
@@ -269,6 +382,7 @@ public class KeycloakInstalled {
return sb.toString();
}
+
public class CallbackListener extends Thread {
private ServerSocket server;
@@ -283,14 +397,19 @@ public class KeycloakInstalled {
private String state;
- public CallbackListener() throws IOException {
+ private Socket socket;
+
+ private HttpResponseWriter writer;
+
+ public CallbackListener(HttpResponseWriter writer) throws IOException {
+ this.writer = writer;
server = new ServerSocket(0);
}
@Override
public void run() {
try {
- Socket socket = server.accept();
+ socket = server.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String request = br.readLine();
@@ -314,10 +433,15 @@ public class KeycloakInstalled {
}
}
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
- pw.println("Please close window and return to application");
- pw.flush();
+ OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
+ PrintWriter pw = new PrintWriter(out);
+ if (error == null) {
+ writer.success(pw, KeycloakInstalled.this);
+ } else {
+ writer.failure(pw, KeycloakInstalled.this);
+ }
+ pw.flush();
socket.close();
} catch (IOException e) {
errorException = e;
@@ -328,6 +452,8 @@ public class KeycloakInstalled {
} catch (IOException e) {
}
}
+
}
+
}
diff --git a/adapters/oidc/jaxrs-oauth-client/pom.xml b/adapters/oidc/jaxrs-oauth-client/pom.xml
index bcd585f5c7..6f46e7c9cc 100755
--- a/adapters/oidc/jaxrs-oauth-client/pom.xml
+++ b/adapters/oidc/jaxrs-oauth-client/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/jetty-core/pom.xml b/adapters/oidc/jetty/jetty-core/pom.xml
index 2f0ad16a41..3ee1c5e155 100755
--- a/adapters/oidc/jetty/jetty-core/pom.xml
+++ b/adapters/oidc/jetty/jetty-core/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/jetty8.1/pom.xml b/adapters/oidc/jetty/jetty8.1/pom.xml
index 7a3fa0cd61..312475509b 100755
--- a/adapters/oidc/jetty/jetty8.1/pom.xml
+++ b/adapters/oidc/jetty/jetty8.1/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/jetty9.1/pom.xml b/adapters/oidc/jetty/jetty9.1/pom.xml
index 1c3edd09c1..c5a4784711 100755
--- a/adapters/oidc/jetty/jetty9.1/pom.xml
+++ b/adapters/oidc/jetty/jetty9.1/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/jetty9.2/pom.xml b/adapters/oidc/jetty/jetty9.2/pom.xml
index 6d34e8bf89..f8b6335404 100755
--- a/adapters/oidc/jetty/jetty9.2/pom.xml
+++ b/adapters/oidc/jetty/jetty9.2/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/jetty9.3/pom.xml b/adapters/oidc/jetty/jetty9.3/pom.xml
index 0077b8dc0a..c4cb37489a 100644
--- a/adapters/oidc/jetty/jetty9.3/pom.xml
+++ b/adapters/oidc/jetty/jetty9.3/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/jetty9.4/pom.xml b/adapters/oidc/jetty/jetty9.4/pom.xml
index 377ddc06d3..acb36c6bcc 100644
--- a/adapters/oidc/jetty/jetty9.4/pom.xml
+++ b/adapters/oidc/jetty/jetty9.4/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/jetty/pom.xml b/adapters/oidc/jetty/pom.xml
index ede26fc29b..5ec0c168b1 100755
--- a/adapters/oidc/jetty/pom.xml
+++ b/adapters/oidc/jetty/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak Jetty Integration
diff --git a/adapters/oidc/js/pom.xml b/adapters/oidc/js/pom.xml
index 7d939c7a8d..8b4cc6789c 100755
--- a/adapters/oidc/js/pom.xml
+++ b/adapters/oidc/js/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/js/src/main/resources/keycloak.js b/adapters/oidc/js/src/main/resources/keycloak.js
index 89b15b8a52..a784936c78 100755
--- a/adapters/oidc/js/src/main/resources/keycloak.js
+++ b/adapters/oidc/js/src/main/resources/keycloak.js
@@ -33,6 +33,13 @@
interval: 5
};
+ var scripts = document.getElementsByTagName('script');
+ for (var i = 0; i < scripts.length; i++) {
+ if ((scripts[i].src.indexOf('keycloak.js') !== -1 || scripts[i].src.indexOf('keycloak.min.js') !== -1) && scripts[i].src.indexOf('version=') !== -1) {
+ kc.iframeVersion = scripts[i].src.substring(scripts[i].src.indexOf('version=') + 8).split('&')[0];
+ }
+ }
+
kc.init = function (initOptions) {
kc.authenticated = false;
@@ -831,6 +838,10 @@
}
var src = getRealmUrl() + '/protocol/openid-connect/login-status-iframe.html';
+ if (kc.iframeVersion) {
+ src = src + '?version=' + kc.iframeVersion;
+ }
+
iframe.setAttribute('src', src );
iframe.style.display = 'none';
document.body.appendChild(iframe);
diff --git a/adapters/oidc/js/src/main/resources/login-status-iframe.html b/adapters/oidc/js/src/main/resources/login-status-iframe.html
index b1012f7694..f58f76abca 100755
--- a/adapters/oidc/js/src/main/resources/login-status-iframe.html
+++ b/adapters/oidc/js/src/main/resources/login-status-iframe.html
@@ -28,7 +28,7 @@
} else if (!init) {
var req = new XMLHttpRequest();
- var url = location.href + "/init";
+ var url = location.href.split("?")[0] + "/init";
url += "?client_id=" + encodeURIComponent(clientId);
url += "&origin=" + encodeURIComponent(origin);
diff --git a/adapters/oidc/osgi-adapter/pom.xml b/adapters/oidc/osgi-adapter/pom.xml
index 7bb5004f7d..26a90ec487 100755
--- a/adapters/oidc/osgi-adapter/pom.xml
+++ b/adapters/oidc/osgi-adapter/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/pom.xml b/adapters/oidc/pom.xml
index d68f3598b9..9207401a1c 100755
--- a/adapters/oidc/pom.xml
+++ b/adapters/oidc/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
Keycloak OIDC Client Adapter Modules
@@ -34,6 +34,7 @@
adapter-core
as7-eap6
installed
+ cli-sso
jaxrs-oauth-client
jetty
js
diff --git a/adapters/oidc/servlet-filter/pom.xml b/adapters/oidc/servlet-filter/pom.xml
index 053710b8c0..3d81dc7322 100755
--- a/adapters/oidc/servlet-filter/pom.xml
+++ b/adapters/oidc/servlet-filter/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java
index 2763ff1a9d..c51b9db4f7 100755
--- a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java
+++ b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java
@@ -54,72 +54,96 @@ import java.util.regex.Pattern;
*/
public class KeycloakOIDCFilter implements Filter {
+ private final static Logger log = Logger.getLogger("" + KeycloakOIDCFilter.class);
+
public static final String SKIP_PATTERN_PARAM = "keycloak.config.skipPattern";
+ public static final String CONFIG_RESOLVER_PARAM = "keycloak.config.resolver";
+
+ public static final String CONFIG_FILE_PARAM = "keycloak.config.file";
+
+ public static final String CONFIG_PATH_PARAM = "keycloak.config.path";
+
protected AdapterDeploymentContext deploymentContext;
+
protected SessionIdMapper idMapper = new InMemorySessionIdMapper();
+
protected NodesRegistrationManagement nodesRegistrationManagement;
+
protected Pattern skipPattern;
- private final static Logger log = Logger.getLogger(""+KeycloakOIDCFilter.class);
+ private final KeycloakConfigResolver definedconfigResolver;
+
+ /**
+ * Constructor that can be used to define a {@code KeycloakConfigResolver} that will be used at initialization to
+ * provide the {@code KeycloakDeployment}.
+ * @param definedconfigResolver the resolver
+ */
+ public KeycloakOIDCFilter(KeycloakConfigResolver definedconfigResolver) {
+ this.definedconfigResolver = definedconfigResolver;
+ }
+
+ public KeycloakOIDCFilter() {
+ this(null);
+ }
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
-
String skipPatternDefinition = filterConfig.getInitParameter(SKIP_PATTERN_PARAM);
if (skipPatternDefinition != null) {
skipPattern = Pattern.compile(skipPatternDefinition, Pattern.DOTALL);
}
- String configResolverClass = filterConfig.getInitParameter("keycloak.config.resolver");
- if (configResolverClass != null) {
- try {
- KeycloakConfigResolver configResolver = (KeycloakConfigResolver) getClass().getClassLoader().loadClass(configResolverClass).newInstance();
- deploymentContext = new AdapterDeploymentContext(configResolver);
- log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass);
- } catch (Exception ex) {
- log.log(Level.FINE, "The specified resolver {0} could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: {1}", new Object[]{configResolverClass, ex.getMessage()});
- deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
- }
+ if (definedconfigResolver != null) {
+ deploymentContext = new AdapterDeploymentContext(definedconfigResolver);
+ log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", definedconfigResolver.getClass());
} else {
- String fp = filterConfig.getInitParameter("keycloak.config.file");
- InputStream is = null;
- if (fp != null) {
+ String configResolverClass = filterConfig.getInitParameter(CONFIG_RESOLVER_PARAM);
+ if (configResolverClass != null) {
try {
- is = new FileInputStream(fp);
- } catch (FileNotFoundException e) {
- throw new RuntimeException(e);
+ KeycloakConfigResolver configResolver = (KeycloakConfigResolver) getClass().getClassLoader().loadClass(configResolverClass).newInstance();
+ deploymentContext = new AdapterDeploymentContext(configResolver);
+ log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass);
+ } catch (Exception ex) {
+ log.log(Level.FINE, "The specified resolver {0} could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: {1}", new Object[]{configResolverClass, ex.getMessage()});
+ deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
}
} else {
- String path = "/WEB-INF/keycloak.json";
- String pathParam = filterConfig.getInitParameter("keycloak.config.path");
- if (pathParam != null) path = pathParam;
- is = filterConfig.getServletContext().getResourceAsStream(path);
+ String fp = filterConfig.getInitParameter(CONFIG_FILE_PARAM);
+ InputStream is = null;
+ if (fp != null) {
+ try {
+ is = new FileInputStream(fp);
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ String path = "/WEB-INF/keycloak.json";
+ String pathParam = filterConfig.getInitParameter(CONFIG_PATH_PARAM);
+ if (pathParam != null) path = pathParam;
+ is = filterConfig.getServletContext().getResourceAsStream(path);
+ }
+ KeycloakDeployment kd = createKeycloakDeploymentFrom(is);
+ deploymentContext = new AdapterDeploymentContext(kd);
+ log.fine("Keycloak is using a per-deployment configuration.");
}
- KeycloakDeployment kd = createKeycloakDeploymentFrom(is);
- deploymentContext = new AdapterDeploymentContext(kd);
- log.fine("Keycloak is using a per-deployment configuration.");
}
filterConfig.getServletContext().setAttribute(AdapterDeploymentContext.class.getName(), deploymentContext);
nodesRegistrationManagement = new NodesRegistrationManagement();
}
private KeycloakDeployment createKeycloakDeploymentFrom(InputStream is) {
-
if (is == null) {
log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
return new KeycloakDeployment();
}
-
return KeycloakDeploymentBuilder.build(is);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
-
log.fine("Keycloak OIDC Filter");
- //System.err.println("Keycloak OIDC Filter: " + ((HttpServletRequest)req).getRequestURL().toString());
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
@@ -201,7 +225,7 @@ public class KeycloakOIDCFilter implements Filter {
*
* @param request the request to check
* @return {@code true} if the request should not be handled,
- * {@code false} otherwise.
+ * {@code false} otherwise.
*/
private boolean shouldSkip(HttpServletRequest request) {
diff --git a/adapters/oidc/servlet-oauth-client/pom.xml b/adapters/oidc/servlet-oauth-client/pom.xml
index 836186fc7f..bb709f1dc2 100755
--- a/adapters/oidc/servlet-oauth-client/pom.xml
+++ b/adapters/oidc/servlet-oauth-client/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/spring-boot-container-bundle/pom.xml b/adapters/oidc/spring-boot-container-bundle/pom.xml
index 4f68494d38..49cab4ebe0 100644
--- a/adapters/oidc/spring-boot-container-bundle/pom.xml
+++ b/adapters/oidc/spring-boot-container-bundle/pom.xml
@@ -4,7 +4,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
spring-boot-container-bundle
diff --git a/adapters/oidc/spring-boot/pom.xml b/adapters/oidc/spring-boot/pom.xml
index abd1512b02..6a720f65a5 100755
--- a/adapters/oidc/spring-boot/pom.xml
+++ b/adapters/oidc/spring-boot/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/spring-security/pom.xml b/adapters/oidc/spring-security/pom.xml
index d1a975ac9f..b304cd5b0d 100755
--- a/adapters/oidc/spring-security/pom.xml
+++ b/adapters/oidc/spring-security/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java
index cb9ddcd064..2c9876eace 100755
--- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java
+++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacade.java
@@ -19,6 +19,9 @@ package org.keycloak.adapters.springsecurity.facade;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.OIDCHttpFacade;
+import org.keycloak.adapters.spi.KeycloakAccount;
+import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
+import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.Assert;
@@ -57,7 +60,8 @@ public class SimpleHttpFacade implements OIDCHttpFacade {
SecurityContext context = SecurityContextHolder.getContext();
if (context != null && context.getAuthentication() != null) {
- return (KeycloakSecurityContext) context.getAuthentication().getDetails();
+ KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) context.getAuthentication();
+ return authentication.getAccount().getKeycloakSecurityContext();
}
return null;
diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacadeTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacadeTest.java
new file mode 100644
index 0000000000..28c6ce8eaf
--- /dev/null
+++ b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/SimpleHttpFacadeTest.java
@@ -0,0 +1,41 @@
+package org.keycloak.adapters.springsecurity.facade;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
+import org.keycloak.adapters.spi.KeycloakAccount;
+import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
+import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
+import org.mockito.internal.util.collections.Sets;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.security.Principal;
+import java.util.Set;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+
+public class SimpleHttpFacadeTest {
+
+ @Before
+ public void setup() {
+ SecurityContext springSecurityContext = SecurityContextHolder.createEmptyContext();
+ SecurityContextHolder.setContext(springSecurityContext);
+ Set roles = Sets.newSet("user");
+ Principal principal = mock(Principal.class);
+ RefreshableKeycloakSecurityContext keycloakSecurityContext = mock(RefreshableKeycloakSecurityContext.class);
+ KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, keycloakSecurityContext);
+ KeycloakAuthenticationToken token = new KeycloakAuthenticationToken(account);
+ springSecurityContext.setAuthentication(token);
+ }
+
+ @Test
+ public void shouldRetrieveKeycloakSecurityContext() {
+ SimpleHttpFacade facade = new SimpleHttpFacade(new MockHttpServletRequest(), new MockHttpServletResponse());
+
+ assertNotNull(facade.getSecurityContext());
+ }
+}
diff --git a/adapters/oidc/tomcat/pom.xml b/adapters/oidc/tomcat/pom.xml
index d691c1d7fe..d733dbd699 100755
--- a/adapters/oidc/tomcat/pom.xml
+++ b/adapters/oidc/tomcat/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak Tomcat Integration
diff --git a/adapters/oidc/tomcat/tomcat-core/pom.xml b/adapters/oidc/tomcat/tomcat-core/pom.xml
index 397f6226d2..c47cc4dde9 100755
--- a/adapters/oidc/tomcat/tomcat-core/pom.xml
+++ b/adapters/oidc/tomcat/tomcat-core/pom.xml
@@ -21,7 +21,7 @@
keycloak-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/oidc/tomcat/tomcat6/pom.xml b/adapters/oidc/tomcat/tomcat6/pom.xml
index 47972ac2a7..d0b7059351 100755
--- a/adapters/oidc/tomcat/tomcat6/pom.xml
+++ b/adapters/oidc/tomcat/tomcat6/pom.xml
@@ -21,7 +21,7 @@
keycloak-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/oidc/tomcat/tomcat7/pom.xml b/adapters/oidc/tomcat/tomcat7/pom.xml
index 01f12ef28d..d42530557a 100755
--- a/adapters/oidc/tomcat/tomcat7/pom.xml
+++ b/adapters/oidc/tomcat/tomcat7/pom.xml
@@ -21,7 +21,7 @@
keycloak-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/oidc/tomcat/tomcat8/pom.xml b/adapters/oidc/tomcat/tomcat8/pom.xml
index ef6ea29801..8bf86063b0 100755
--- a/adapters/oidc/tomcat/tomcat8/pom.xml
+++ b/adapters/oidc/tomcat/tomcat8/pom.xml
@@ -21,7 +21,7 @@
keycloak-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/oidc/undertow/pom.xml b/adapters/oidc/undertow/pom.xml
index 048e249406..ccdc34e60e 100755
--- a/adapters/oidc/undertow/pom.xml
+++ b/adapters/oidc/undertow/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/wildfly-elytron/pom.xml b/adapters/oidc/wildfly-elytron/pom.xml
index edfd4aa325..71d5681818 100755
--- a/adapters/oidc/wildfly-elytron/pom.xml
+++ b/adapters/oidc/wildfly-elytron/pom.xml
@@ -22,7 +22,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java
index bc2e9039ca..4472af75f9 100644
--- a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java
+++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java
@@ -90,6 +90,11 @@ class ElytronHttpFacade implements OIDCHttpFacade {
void authenticationComplete() {
if (securityIdentity != null) {
+ HttpScope requestScope = request.getScope(Scope.EXCHANGE);
+ RefreshableKeycloakSecurityContext keycloakSecurityContext = account.getKeycloakSecurityContext();
+
+ requestScope.setAttachment(KeycloakSecurityContext.class.getName(), keycloakSecurityContext);
+
this.request.authenticationComplete(response -> {
if (!restored) {
responseConsumer.accept(response);
diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java
index 3fcf9bf484..8d0cd1d538 100644
--- a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java
+++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java
@@ -71,7 +71,7 @@ class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticat
AdapterDeploymentContext deploymentContext = getDeploymentContext(request);
if (deploymentContext == null) {
- LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI());
+ LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI(), getMechanismName());
request.noAuthenticationInProgress();
return;
}
diff --git a/adapters/oidc/wildfly/pom.xml b/adapters/oidc/wildfly/pom.xml
index d6a2184284..e93be16c2b 100755
--- a/adapters/oidc/wildfly/pom.xml
+++ b/adapters/oidc/wildfly/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak WildFly Integration
diff --git a/adapters/oidc/wildfly/wf8-subsystem/pom.xml b/adapters/oidc/wildfly/wf8-subsystem/pom.xml
index e3e2c34ecb..2afcf14cdf 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/pom.xml
+++ b/adapters/oidc/wildfly/wf8-subsystem/pom.xml
@@ -21,7 +21,7 @@
org.keycloak
keycloak-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/adapters/oidc/wildfly/wildfly-adapter/pom.xml b/adapters/oidc/wildfly/wildfly-adapter/pom.xml
index 89d38703fb..686661d8cf 100644
--- a/adapters/oidc/wildfly/wildfly-adapter/pom.xml
+++ b/adapters/oidc/wildfly/wildfly-adapter/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/pom.xml b/adapters/oidc/wildfly/wildfly-subsystem/pom.xml
index 596f00f3ec..1d8e6cf916 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/pom.xml
+++ b/adapters/oidc/wildfly/wildfly-subsystem/pom.xml
@@ -21,7 +21,7 @@
org.keycloak
keycloak-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
index e96a5e51f8..5a71e615a8 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakAdapterConfigService.java
@@ -37,6 +37,8 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD
public final class KeycloakAdapterConfigService {
private static final String CREDENTIALS_JSON_NAME = "credentials";
+
+ private static final String REDIRECT_REWRITE_RULE_JSON_NAME = "redirect-rewrite-rule";
private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
@@ -129,6 +131,56 @@ public final class KeycloakAdapterConfigService {
ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
return deployment.get(CREDENTIALS_JSON_NAME);
}
+
+ public void addRedirectRewriteRule(ModelNode operation, ModelNode model) {
+ ModelNode redirectRewritesRules = redirectRewriteRuleFromOp(operation);
+ if (!redirectRewritesRules.isDefined()) {
+ redirectRewritesRules = new ModelNode();
+ }
+
+ String redirectRewriteRuleName = redirectRewriteRule(operation);
+ if (!redirectRewriteRuleName.contains(".")) {
+ redirectRewritesRules.get(redirectRewriteRuleName).set(model.get("value").asString());
+ } else {
+ String[] parts = redirectRewriteRuleName.split("\\.");
+ String provider = parts[0];
+ String property = parts[1];
+ ModelNode redirectRewriteRule = redirectRewritesRules.get(provider);
+ if (!redirectRewriteRule.isDefined()) {
+ redirectRewriteRule = new ModelNode();
+ }
+ redirectRewriteRule.get(property).set(model.get("value").asString());
+ redirectRewritesRules.set(provider, redirectRewriteRule);
+ }
+
+ ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
+ deployment.get(REDIRECT_REWRITE_RULE_JSON_NAME).set(redirectRewritesRules);
+ }
+
+ public void removeRedirectRewriteRule(ModelNode operation) {
+ ModelNode redirectRewritesRules = redirectRewriteRuleFromOp(operation);
+ if (!redirectRewritesRules.isDefined()) {
+ throw new RuntimeException("Can not remove redirect rewrite rule. No rules defined for deployment in op " + operation.toString());
+ }
+
+ String ruleName = credentialNameFromOp(operation);
+ redirectRewritesRules.remove(ruleName);
+ }
+
+ public void updateRedirectRewriteRule(ModelNode operation, String attrName, ModelNode resolvedValue) {
+ ModelNode redirectRewritesRules = redirectRewriteRuleFromOp(operation);
+ if (!redirectRewritesRules.isDefined()) {
+ throw new RuntimeException("Can not update redirect rewrite rule. No rules defined for deployment in op " + operation.toString());
+ }
+
+ String ruleName = credentialNameFromOp(operation);
+ redirectRewritesRules.get(ruleName).set(resolvedValue);
+ }
+
+ private ModelNode redirectRewriteRuleFromOp(ModelNode operation) {
+ ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
+ return deployment.get(REDIRECT_REWRITE_RULE_JSON_NAME);
+ }
private String realmNameFromOp(ModelNode operation) {
return valueFromOpAddress(RealmDefinition.TAG_NAME, operation);
@@ -141,6 +193,10 @@ public final class KeycloakAdapterConfigService {
private String credentialNameFromOp(ModelNode operation) {
return valueFromOpAddress(CredentialDefinition.TAG_NAME, operation);
}
+
+ private String redirectRewriteRule(ModelNode operation) {
+ return valueFromOpAddress(RedirecRewritetRuleDefinition.TAG_NAME, operation);
+ }
private String valueFromOpAddress(String addrElement, ModelNode operation) {
String deploymentName = getValueOfAddrElement(operation.get(ADDRESS), addrElement);
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java
index 541454a37d..d04e72d403 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakExtension.java
@@ -48,6 +48,7 @@ public class KeycloakExtension implements Extension {
static final RealmDefinition REALM_DEFINITION = new RealmDefinition();
static final SecureDeploymentDefinition SECURE_DEPLOYMENT_DEFINITION = new SecureDeploymentDefinition();
static final CredentialDefinition CREDENTIAL_DEFINITION = new CredentialDefinition();
+ static final RedirecRewritetRuleDefinition REDIRECT_RULE_DEFINITON = new RedirecRewritetRuleDefinition();
public static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
@@ -77,6 +78,7 @@ public class KeycloakExtension implements Extension {
registration.registerSubModel(REALM_DEFINITION);
ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
secureDeploymentRegistration.registerSubModel(CREDENTIAL_DEFINITION);
+ secureDeploymentRegistration.registerSubModel(REDIRECT_RULE_DEFINITON);
subsystem.registerXMLElementWriter(PARSER);
}
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java
index d4ddc02e3d..79555e3b7b 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/KeycloakSubsystemParser.java
@@ -96,12 +96,17 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader credentialsToAdd = new ArrayList();
+ List redirectRulesToAdd = new ArrayList();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (tagName.equals(CredentialDefinition.TAG_NAME)) {
readCredential(reader, addr, credentialsToAdd);
continue;
}
+ if (tagName.equals(RedirecRewritetRuleDefinition.TAG_NAME)) {
+ readRewriteRule(reader, addr, redirectRulesToAdd);
+ continue;
+ }
SimpleAttributeDefinition def = SecureDeploymentDefinition.lookup(tagName);
if (def == null) throw new XMLStreamException("Unknown secure-deployment tag " + tagName);
@@ -111,6 +116,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader credentialsToAdd) throws XMLStreamException {
@@ -149,6 +155,43 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader rewriteRuleToToAdd) throws XMLStreamException {
+ String name = readNameAttribute(reader);
+
+ Map values = new HashMap<>();
+ String textValue = null;
+ while (reader.hasNext()) {
+ int next = reader.next();
+ if (next == CHARACTERS) {
+ // text value of redirect rule element
+ String text = reader.getText();
+ if (text == null || text.trim().isEmpty()) {
+ continue;
+ }
+ textValue = text;
+ } else if (next == START_ELEMENT) {
+ String key = reader.getLocalName();
+ reader.next();
+ String value = reader.getText();
+ reader.next();
+
+ values.put(key, value);
+ } else if (next == END_ELEMENT) {
+ break;
+ }
+ }
+
+ if (textValue != null) {
+ ModelNode addRedirectRule = getRedirectRuleToAdd(parent, name, textValue);
+ rewriteRuleToToAdd.add(addRedirectRule);
+ } else {
+ for (Map.Entry entry : values.entrySet()) {
+ ModelNode addRedirectRule = getRedirectRuleToAdd(parent, name + "." + entry.getKey(), entry.getValue());
+ rewriteRuleToToAdd.add(addRedirectRule);
+ }
+ }
+ }
private ModelNode getCredentialToAdd(PathAddress parent, String name, String value) {
ModelNode addCredential = new ModelNode();
@@ -158,6 +201,15 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader parsed = new LinkedHashMap<>();
+ for (Property redirectRule : redirectRules.asPropertyList()) {
+ String ruleName = redirectRule.getName();
+ String ruleValue = redirectRule.getValue().get(RedirecRewritetRuleDefinition.VALUE.getName()).asString();
+ parsed.put(ruleName, ruleValue);
+ }
+
+ for (Map.Entry entry : parsed.entrySet()) {
+ writer.writeStartElement(RedirecRewritetRuleDefinition.TAG_NAME);
+ writer.writeAttribute("name", entry.getKey());
+
+ Object value = entry.getValue();
+ if (value instanceof String) {
+ writeCharacters(writer, (String) value);
+ } else {
+ Map redirectRulesProps = (Map) value;
+ for (Map.Entry prop : redirectRulesProps.entrySet()) {
+ writer.writeStartElement(prop.getKey());
+ writeCharacters(writer, prop.getValue());
+ writer.writeEndElement();
+ }
+ }
+
+ writer.writeEndElement();
+ }
+ }
// code taken from org.jboss.as.controller.AttributeMarshaller
private void writeCharacters(XMLExtendedStreamWriter writer, String content) throws XMLStreamException {
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirecRewritetRuleDefinition.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirecRewritetRuleDefinition.java
new file mode 100644
index 0000000000..a9095c7d8e
--- /dev/null
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirecRewritetRuleDefinition.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 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.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.operations.validation.StringLengthValidator;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.jboss.dmr.ModelType;
+
+/**
+ *
+ * @author sblanc
+ */
+public class RedirecRewritetRuleDefinition extends SimpleResourceDefinition {
+
+ public static final String TAG_NAME = "redirect-rewrite-rule";
+
+ protected static final AttributeDefinition VALUE =
+ new SimpleAttributeDefinitionBuilder("value", ModelType.STRING, false)
+ .setAllowExpression(true)
+ .setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
+ .build();
+
+ public RedirecRewritetRuleDefinition() {
+ super(PathElement.pathElement(TAG_NAME),
+ KeycloakExtension.getResourceDescriptionResolver(TAG_NAME),
+ new RedirectRewriteRuleAddHandler(VALUE),
+ RedirectRewriteRuleRemoveHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerOperations(ManagementResourceRegistration resourceRegistration) {
+ super.registerOperations(resourceRegistration);
+ resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
+ super.registerAttributes(resourceRegistration);
+ resourceRegistration.registerReadWriteAttribute(VALUE, null, new RedirectRewriteRuleReadWriteAttributeHandler());
+ }
+}
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleAddHandler.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleAddHandler.java
new file mode 100644
index 0000000000..2fc25f7df7
--- /dev/null
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleAddHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 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.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractAddStepHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+public class RedirectRewriteRuleAddHandler extends AbstractAddStepHandler {
+
+ public RedirectRewriteRuleAddHandler(AttributeDefinition... attributes) {
+ super(attributes);
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.addRedirectRewriteRule(operation, context.resolveExpressions(model));
+ }
+
+}
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleReadWriteAttributeHandler.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleReadWriteAttributeHandler.java
new file mode 100644
index 0000000000..171e7555bc
--- /dev/null
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleReadWriteAttributeHandler.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 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.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractWriteAttributeHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+public class RedirectRewriteRuleReadWriteAttributeHandler extends AbstractWriteAttributeHandler {
+
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode resolvedValue, ModelNode currentValue, AbstractWriteAttributeHandler.HandbackHolder hh) throws OperationFailedException {
+
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.updateRedirectRewriteRule(operation, attributeName, resolvedValue);
+
+ hh.setHandback(ckService);
+
+ return false;
+ }
+
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
+ ckService.updateRedirectRewriteRule(operation, attributeName, valueToRestore);
+ }
+
+}
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleRemoveHandler.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleRemoveHandler.java
new file mode 100644
index 0000000000..de17c9666e
--- /dev/null
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/RedirectRewriteRuleRemoveHandler.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 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.subsystem.adapter.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+
+public class RedirectRewriteRuleRemoveHandler extends AbstractRemoveStepHandler {
+
+ public static RedirectRewriteRuleRemoveHandler INSTANCE = new RedirectRewriteRuleRemoveHandler();
+
+ private RedirectRewriteRuleRemoveHandler() {}
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
+ ckService.removeRedirectRewriteRule(operation);
+ }
+
+}
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
index 1df59796a2..c9cea77787 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
@@ -65,6 +65,7 @@ keycloak.secure-deployment.connection-pool-size=Connection pool size for the cli
keycloak.secure-deployment.resource=Application name
keycloak.secure-deployment.use-resource-role-mappings=Use resource level permissions from token
keycloak.secure-deployment.credentials=Adapter credentials
+keycloak.secure-deployment.redirect-rewrite-rule=Apply a rewrite rule for the redirect URI
keycloak.secure-deployment.bearer-only=Bearer Token Auth only
keycloak.secure-deployment.enable-basic-auth=Enable Basic Authentication
keycloak.secure-deployment.public-client=Public client
@@ -94,4 +95,9 @@ keycloak.secure-deployment.credential=Credential value
keycloak.credential=Credential
keycloak.credential.value=Credential value
keycloak.credential.add=Credential add
-keycloak.credential.remove=Credential remove
\ No newline at end of file
+keycloak.credential.remove=Credential remove
+
+keycloak.redirect-rewrite-rule=redirect-rewrite-rule
+keycloak.redirect-rewrite-rule.value=redirect-rewrite-rule value
+keycloak.redirect-rewrite-rule.add=redirect-rewrite-rule add
+keycloak.redirect-rewrite-rule.remove=redirect-rewrite-rule remove
\ No newline at end of file
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
index 604e6ac62d..d8f5bc3d74 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
@@ -101,6 +101,7 @@
+
@@ -127,4 +128,10 @@
+
+
+
+
+
+
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml b/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
index 3dcb61d4f0..246d76855f 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
@@ -53,6 +53,7 @@
http://localhost:8080/auth
EXTERNAL
0aa31d98-e0aa-404c-b6e0-e771dba1e798
+ api/$1/
master
@@ -66,5 +67,6 @@
/tmp/keystore.jks
+ /api/$1/
\ No newline at end of file
diff --git a/adapters/pom.xml b/adapters/pom.xml
index 847b84eaff..21e23b987a 100755
--- a/adapters/pom.xml
+++ b/adapters/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
Keycloak Adapters
diff --git a/adapters/saml/as7-eap6/adapter/pom.xml b/adapters/saml/as7-eap6/adapter/pom.xml
index 43cfcb1816..dd8aff5317 100755
--- a/adapters/saml/as7-eap6/adapter/pom.xml
+++ b/adapters/saml/as7-eap6/adapter/pom.xml
@@ -21,7 +21,7 @@
keycloak-saml-eap-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/saml/as7-eap6/pom.xml b/adapters/saml/as7-eap6/pom.xml
index 7233dfb383..66bdf0d5ad 100755
--- a/adapters/saml/as7-eap6/pom.xml
+++ b/adapters/saml/as7-eap6/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak SAML EAP Integration
diff --git a/adapters/saml/as7-eap6/subsystem/pom.xml b/adapters/saml/as7-eap6/subsystem/pom.xml
index e89cbd7753..d3c2a5d9a4 100755
--- a/adapters/saml/as7-eap6/subsystem/pom.xml
+++ b/adapters/saml/as7-eap6/subsystem/pom.xml
@@ -21,7 +21,7 @@
org.keycloak
keycloak-saml-eap-integration-pom
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/xml/FormattingXMLStreamWriter.java b/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/xml/FormattingXMLStreamWriter.java
index 0d566597b3..2334a63ad7 100644
--- a/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/xml/FormattingXMLStreamWriter.java
+++ b/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/xml/FormattingXMLStreamWriter.java
@@ -81,7 +81,7 @@ public final class FormattingXMLStreamWriter implements XMLExtendedStreamWriter,
public void writeStartElement(final String localName) throws XMLStreamException {
ArrayDeque namespaces = unspecifiedNamespaces;
String namespace = namespaces.getFirst();
- if (namespace != NO_NAMESPACE) {
+ if (namespace == null ? NO_NAMESPACE != null : ! namespace.equals(NO_NAMESPACE)) {
writeStartElement(namespace, localName);
return;
}
@@ -140,9 +140,9 @@ public final class FormattingXMLStreamWriter implements XMLExtendedStreamWriter,
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
if (arg == 0) {
- delegate.writeStartElement(prefix, namespaceURI, localName);
+ delegate.writeStartElement(prefix, localName, namespaceURI);
} else {
- delegate.writeEmptyElement(prefix, namespaceURI, localName);
+ delegate.writeEmptyElement(prefix, localName, namespaceURI);
}
}
});
@@ -165,14 +165,14 @@ public final class FormattingXMLStreamWriter implements XMLExtendedStreamWriter,
runAttrQueue();
nl();
indent();
- delegate.writeEmptyElement(prefix, namespaceURI, localName);
+ delegate.writeEmptyElement(prefix, localName, namespaceURI);
state = END_ELEMENT;
}
@Override
public void writeEmptyElement(final String localName) throws XMLStreamException {
String namespace = unspecifiedNamespaces.getFirst();
- if (namespace != NO_NAMESPACE) {
+ if (namespace == null ? NO_NAMESPACE != null : ! namespace.equals(NO_NAMESPACE)) {
writeEmptyElement(namespace, localName);
return;
}
diff --git a/adapters/saml/core-public/pom.xml b/adapters/saml/core-public/pom.xml
index e56da0ec07..29e35a9761 100755
--- a/adapters/saml/core-public/pom.xml
+++ b/adapters/saml/core-public/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java b/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java
index 29bbbfa566..f44534d542 100755
--- a/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java
+++ b/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java
@@ -18,7 +18,10 @@
package org.keycloak.adapters.saml;
import org.keycloak.adapters.spi.AuthenticationError;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import java.util.Objects;
/**
* Object that describes the SAML error that happened.
@@ -27,6 +30,7 @@ import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
* @version $Revision: 1 $
*/
public class SamlAuthenticationError implements AuthenticationError {
+
public static enum Reason {
EXTRACTION_FAILURE,
INVALID_SIGNATURE,
@@ -59,7 +63,18 @@ public class SamlAuthenticationError implements AuthenticationError {
@Override
public String toString() {
- return "SamlAuthenticationError [reason=" + reason + ", status=" + status + "]";
+ return "SamlAuthenticationError [reason=" + reason + ", status="
+ + ((status == null || status.getStatus() == null) ? "UNKNOWN" : extractStatusCode(status.getStatus().getStatusCode()))
+ + "]";
}
+ private String extractStatusCode(StatusCodeType statusCode) {
+ if (statusCode == null || statusCode.getValue() == null) {
+ return "UNKNOWN";
+ }
+ if (Objects.equals(JBossSAMLURIConstants.STATUS_RESPONDER.get(), statusCode.getValue().toString())) {
+ return extractStatusCode(statusCode.getStatusCode());
+ }
+ return statusCode.getValue().toString();
+ }
}
diff --git a/adapters/saml/core/pom.xml b/adapters/saml/core/pom.xml
index 244e69ed13..be1e686dc0 100755
--- a/adapters/saml/core/pom.xml
+++ b/adapters/saml/core/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/descriptor/parsers/SamlDescriptorIDPKeysExtractor.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/descriptor/parsers/SamlDescriptorIDPKeysExtractor.java
index 0858675c50..b8d5d6658a 100644
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/descriptor/parsers/SamlDescriptorIDPKeysExtractor.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/descriptor/parsers/SamlDescriptorIDPKeysExtractor.java
@@ -34,6 +34,7 @@ import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.saml.common.constants.JBossSAMLConstants;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.DocumentUtil;
import org.keycloak.saml.processing.core.util.NamespaceContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -65,9 +66,7 @@ public class SamlDescriptorIDPKeysExtractor {
MultivaluedHashMap res = new MultivaluedHashMap<>();
try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- DocumentBuilder builder = factory.newDocumentBuilder();
+ DocumentBuilder builder = DocumentUtil.getDocumentBuilder();
Document doc = builder.parse(stream);
XPathExpression expr = xpath.compile("/m:EntitiesDescriptor/m:EntityDescriptor/m:IDPSSODescriptor/m:KeyDescriptor");
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
index 08ce4a988b..2b40a424e8 100644
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
@@ -407,8 +407,8 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
SubjectType subject = assertion.getSubject();
SubjectType.STSubType subType = subject.getSubType();
- NameIDType subjectNameID = (NameIDType) subType.getBaseID();
- String principalName = subjectNameID.getValue();
+ NameIDType subjectNameID = subType == null ? null : (NameIDType) subType.getBaseID();
+ String principalName = subjectNameID == null ? null : subjectNameID.getValue();
final Set roles = new HashSet<>();
MultivaluedHashMap attributes = new MultivaluedHashMap<>();
@@ -473,7 +473,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
}
- URI nameFormat = subjectNameID.getFormat();
+ URI nameFormat = subjectNameID == null ? null : subjectNameID.getFormat();
String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString();
final SamlPrincipal principal = new SamlPrincipal(assertion, principalName, principalName, nameFormatString, attributes, friendlyAttributes);
String index = authn == null ? null : authn.getSessionIndex();
diff --git a/adapters/saml/jetty/jetty-core/pom.xml b/adapters/saml/jetty/jetty-core/pom.xml
index c6a7cc0c7d..316cb7e6b1 100755
--- a/adapters/saml/jetty/jetty-core/pom.xml
+++ b/adapters/saml/jetty/jetty-core/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/jetty/jetty8.1/pom.xml b/adapters/saml/jetty/jetty8.1/pom.xml
index 62ac8f399e..ca569821b3 100755
--- a/adapters/saml/jetty/jetty8.1/pom.xml
+++ b/adapters/saml/jetty/jetty8.1/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/jetty/jetty9.1/pom.xml b/adapters/saml/jetty/jetty9.1/pom.xml
index f613b6b218..c01af403a2 100755
--- a/adapters/saml/jetty/jetty9.1/pom.xml
+++ b/adapters/saml/jetty/jetty9.1/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/jetty/jetty9.2/pom.xml b/adapters/saml/jetty/jetty9.2/pom.xml
index d66b670571..88bf685595 100755
--- a/adapters/saml/jetty/jetty9.2/pom.xml
+++ b/adapters/saml/jetty/jetty9.2/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/jetty/jetty9.3/pom.xml b/adapters/saml/jetty/jetty9.3/pom.xml
index 8104214f98..d34f83e0ed 100644
--- a/adapters/saml/jetty/jetty9.3/pom.xml
+++ b/adapters/saml/jetty/jetty9.3/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/jetty/jetty9.4/pom.xml b/adapters/saml/jetty/jetty9.4/pom.xml
index 23b05d08c3..cee8d453d9 100644
--- a/adapters/saml/jetty/jetty9.4/pom.xml
+++ b/adapters/saml/jetty/jetty9.4/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/jetty/pom.xml b/adapters/saml/jetty/pom.xml
index 621ae3c2f9..2f53996d71 100755
--- a/adapters/saml/jetty/pom.xml
+++ b/adapters/saml/jetty/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak SAML Jetty Integration
diff --git a/adapters/saml/pom.xml b/adapters/saml/pom.xml
index 18e32cf0a2..4ae655c4e9 100755
--- a/adapters/saml/pom.xml
+++ b/adapters/saml/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
Keycloak SAML Client Adapter Modules
diff --git a/adapters/saml/servlet-filter/pom.xml b/adapters/saml/servlet-filter/pom.xml
index c7688b61b7..fd7f9393ba 100755
--- a/adapters/saml/servlet-filter/pom.xml
+++ b/adapters/saml/servlet-filter/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/saml/tomcat/pom.xml b/adapters/saml/tomcat/pom.xml
index 3f76eba91e..0911796e01 100755
--- a/adapters/saml/tomcat/pom.xml
+++ b/adapters/saml/tomcat/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak SAML Tomcat Integration
diff --git a/adapters/saml/tomcat/tomcat-core/pom.xml b/adapters/saml/tomcat/tomcat-core/pom.xml
index 466b6b5aee..e493969a3f 100755
--- a/adapters/saml/tomcat/tomcat-core/pom.xml
+++ b/adapters/saml/tomcat/tomcat-core/pom.xml
@@ -21,7 +21,7 @@
keycloak-saml-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/saml/tomcat/tomcat6/pom.xml b/adapters/saml/tomcat/tomcat6/pom.xml
index fb55eccc66..12ad22bb0a 100755
--- a/adapters/saml/tomcat/tomcat6/pom.xml
+++ b/adapters/saml/tomcat/tomcat6/pom.xml
@@ -21,7 +21,7 @@
keycloak-saml-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/saml/tomcat/tomcat7/pom.xml b/adapters/saml/tomcat/tomcat7/pom.xml
index ef00d9b6dd..ff59bfc0ef 100755
--- a/adapters/saml/tomcat/tomcat7/pom.xml
+++ b/adapters/saml/tomcat/tomcat7/pom.xml
@@ -21,7 +21,7 @@
keycloak-saml-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/saml/tomcat/tomcat8/pom.xml b/adapters/saml/tomcat/tomcat8/pom.xml
index b87505f9d6..835e4d52d2 100755
--- a/adapters/saml/tomcat/tomcat8/pom.xml
+++ b/adapters/saml/tomcat/tomcat8/pom.xml
@@ -21,7 +21,7 @@
keycloak-saml-tomcat-integration-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java b/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
index eef8c6a0ba..caf1bf98a7 100755
--- a/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
+++ b/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
@@ -41,10 +41,20 @@ import java.util.List;
* @version $Revision: 1 $
*/
public class SamlAuthenticatorValve extends AbstractSamlAuthenticatorValve {
+ /**
+ * Method called by Tomcat < 8.5.5
+ */
public boolean authenticate(Request request, HttpServletResponse response) throws IOException {
return authenticateInternal(request, response, request.getContext().getLoginConfig());
}
+ /**
+ * Method called by Tomcat >= 8.5.5
+ */
+ protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException {
+ return this.authenticate(request, response);
+ }
+
@Override
protected boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
if (loginConfig == null) return false;
diff --git a/adapters/saml/undertow/pom.xml b/adapters/saml/undertow/pom.xml
index 40757160f7..b314f7efaf 100755
--- a/adapters/saml/undertow/pom.xml
+++ b/adapters/saml/undertow/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/saml/wildfly-elytron/pom.xml b/adapters/saml/wildfly-elytron/pom.xml
index 8d6df2e636..4161b092e9 100755
--- a/adapters/saml/wildfly-elytron/pom.xml
+++ b/adapters/saml/wildfly-elytron/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java
index 88e96f8bd3..68c6922fae 100644
--- a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java
+++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java
@@ -47,10 +47,8 @@ import org.wildfly.security.auth.callback.AnonymousAuthorizationCallback;
import org.wildfly.security.auth.callback.AuthenticationCompleteCallback;
import org.wildfly.security.auth.callback.SecurityIdentityCallback;
import org.wildfly.security.auth.server.SecurityIdentity;
-import org.wildfly.security.http.HttpAuthenticationException;
import org.wildfly.security.http.HttpScope;
import org.wildfly.security.http.HttpServerCookie;
-import org.wildfly.security.http.HttpServerMechanismsResponder;
import org.wildfly.security.http.HttpServerRequest;
import org.wildfly.security.http.HttpServerResponse;
import org.wildfly.security.http.Scope;
@@ -87,11 +85,14 @@ class ElytronHttpFacade implements HttpFacade {
void authenticationComplete() {
this.securityIdentity = SecurityIdentityUtil.authorize(this.callbackHandler, samlSession.getPrincipal());
- this.request.authenticationComplete(response -> {
- if (!restored) {
- responseConsumer.accept(response);
- }
- }, () -> ((ElytronTokeStore) sessionStore).logout(true));
+
+ if (this.securityIdentity != null) {
+ this.request.authenticationComplete(response -> {
+ if (!restored) {
+ responseConsumer.accept(response);
+ }
+ }, () -> ((ElytronTokeStore) sessionStore).logout(true));
+ }
}
void authenticationCompleteAnonymous() {
diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java
index 9fce501d93..1f71bae329 100644
--- a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java
+++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java
@@ -65,7 +65,7 @@ class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticat
SamlDeploymentContext deploymentContext = getDeploymentContext(request);
if (deploymentContext == null) {
- LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI());
+ LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI(), getMechanismName());
request.noAuthenticationInProgress();
return;
}
diff --git a/adapters/saml/wildfly/pom.xml b/adapters/saml/wildfly/pom.xml
index 430696008d..43108bb00f 100755
--- a/adapters/saml/wildfly/pom.xml
+++ b/adapters/saml/wildfly/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak SAML Wildfly Integration
diff --git a/adapters/saml/wildfly/wildfly-adapter/pom.xml b/adapters/saml/wildfly/wildfly-adapter/pom.xml
index 1ba105731a..3be5e7e4c0 100755
--- a/adapters/saml/wildfly/wildfly-adapter/pom.xml
+++ b/adapters/saml/wildfly/wildfly-adapter/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
4.0.0
diff --git a/adapters/saml/wildfly/wildfly-subsystem/pom.xml b/adapters/saml/wildfly/wildfly-subsystem/pom.xml
index 7195cf4ba4..acaf7f160f 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/pom.xml
+++ b/adapters/saml/wildfly/wildfly-subsystem/pom.xml
@@ -21,7 +21,7 @@
org.keycloak
keycloak-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/adapters/spi/adapter-spi/pom.xml b/adapters/spi/adapter-spi/pom.xml
index 23963fe544..0145009a5f 100755
--- a/adapters/spi/adapter-spi/pom.xml
+++ b/adapters/spi/adapter-spi/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/spi/jboss-adapter-core/pom.xml b/adapters/spi/jboss-adapter-core/pom.xml
index ccd687d4b9..41be1d3d19 100755
--- a/adapters/spi/jboss-adapter-core/pom.xml
+++ b/adapters/spi/jboss-adapter-core/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/spi/jetty-adapter-spi/pom.xml b/adapters/spi/jetty-adapter-spi/pom.xml
index 0841616fe6..03adfdf126 100755
--- a/adapters/spi/jetty-adapter-spi/pom.xml
+++ b/adapters/spi/jetty-adapter-spi/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/spi/pom.xml b/adapters/spi/pom.xml
index ce656153d0..45805179b1 100755
--- a/adapters/spi/pom.xml
+++ b/adapters/spi/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
Keycloak Client Adapter SPI Modules
diff --git a/adapters/spi/servlet-adapter-spi/pom.xml b/adapters/spi/servlet-adapter-spi/pom.xml
index b54d2665a1..c9228b6e7f 100755
--- a/adapters/spi/servlet-adapter-spi/pom.xml
+++ b/adapters/spi/servlet-adapter-spi/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/spi/tomcat-adapter-spi/pom.xml b/adapters/spi/tomcat-adapter-spi/pom.xml
index ba39fa0b78..dcf55e5f50 100755
--- a/adapters/spi/tomcat-adapter-spi/pom.xml
+++ b/adapters/spi/tomcat-adapter-spi/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/adapters/spi/undertow-adapter-spi/pom.xml b/adapters/spi/undertow-adapter-spi/pom.xml
index 9256187d82..0f04bdb14d 100755
--- a/adapters/spi/undertow-adapter-spi/pom.xml
+++ b/adapters/spi/undertow-adapter-spi/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
4.0.0
diff --git a/authz/client/pom.xml b/authz/client/pom.xml
index c1c063103c..c45476a6e0 100644
--- a/authz/client/pom.xml
+++ b/authz/client/pom.xml
@@ -7,7 +7,7 @@
org.keycloak
keycloak-authz-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/authz/policy/common/pom.xml b/authz/policy/common/pom.xml
index 7e309a5b63..193dcf49af 100644
--- a/authz/policy/common/pom.xml
+++ b/authz/policy/common/pom.xml
@@ -25,7 +25,7 @@
org.keycloak
keycloak-authz-provider-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/authz/policy/drools/pom.xml b/authz/policy/drools/pom.xml
index 54fdfe9343..eb6674110d 100644
--- a/authz/policy/drools/pom.xml
+++ b/authz/policy/drools/pom.xml
@@ -7,7 +7,7 @@
org.keycloak
keycloak-authz-provider-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/authz/policy/pom.xml b/authz/policy/pom.xml
index 3c064d4432..f119652c85 100644
--- a/authz/policy/pom.xml
+++ b/authz/policy/pom.xml
@@ -7,7 +7,7 @@
org.keycloak
keycloak-authz-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/authz/pom.xml b/authz/pom.xml
index 6121b2386d..36c54baf5e 100644
--- a/authz/pom.xml
+++ b/authz/pom.xml
@@ -7,7 +7,7 @@
org.keycloak
keycloak-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/boms/adapter/pom.xml b/boms/adapter/pom.xml
index 46c6272e08..47333617df 100644
--- a/boms/adapter/pom.xml
+++ b/boms/adapter/pom.xml
@@ -22,7 +22,7 @@
org.keycloak.bom
keycloak-bom-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak.bom
@@ -37,97 +37,97 @@
org.keycloak
keycloak-core
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-adapter-core
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-adapter-spi
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-wildfly-adapter-dist
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-saml-adapter-core
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-saml-adapter-api-public
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-tomcat8-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-tomcat7-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-tomcat6-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-jetty81-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-jetty91-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-jetty92-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-jetty93-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-undertow-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-spring-boot-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
spring-boot-container-bundle
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-spring-security-adapter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-spring-boot-starter
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-authz-client
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
diff --git a/boms/pom.xml b/boms/pom.xml
index a5f75a8a4a..bbbc0dbaf5 100644
--- a/boms/pom.xml
+++ b/boms/pom.xml
@@ -26,7 +26,7 @@
org.keycloak.bom
keycloak-bom-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
pom
diff --git a/boms/spi/pom.xml b/boms/spi/pom.xml
index 555ca375b7..9d970d1df0 100644
--- a/boms/spi/pom.xml
+++ b/boms/spi/pom.xml
@@ -23,7 +23,7 @@
org.keycloak.bom
keycloak-bom-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak.bom
@@ -38,12 +38,12 @@
org.keycloak
keycloak-core
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-server-spi
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
diff --git a/common/pom.xml b/common/pom.xml
index 1039ff884f..70476b6743 100755
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/common/src/main/java/org/keycloak/common/Profile.java b/common/src/main/java/org/keycloak/common/Profile.java
index 91b0a806cc..7f97e55b8a 100755
--- a/common/src/main/java/org/keycloak/common/Profile.java
+++ b/common/src/main/java/org/keycloak/common/Profile.java
@@ -35,13 +35,13 @@ import java.util.Set;
public class Profile {
public enum Feature {
- AUTHORIZATION, IMPERSONATION, SCRIPTS
+ AUTHORIZATION, IMPERSONATION, SCRIPTS, DOCKER
}
private enum ProfileValue {
- PRODUCT(Feature.AUTHORIZATION, Feature.SCRIPTS),
+ PRODUCT(Feature.AUTHORIZATION, Feature.SCRIPTS, Feature.DOCKER),
PREVIEW,
- COMMUNITY;
+ COMMUNITY(Feature.DOCKER);
private List disabled;
diff --git a/common/src/main/java/org/keycloak/common/Version.java b/common/src/main/java/org/keycloak/common/Version.java
index 862ccd2def..75fbe92ec9 100755
--- a/common/src/main/java/org/keycloak/common/Version.java
+++ b/common/src/main/java/org/keycloak/common/Version.java
@@ -45,6 +45,10 @@ public class Version {
Version.VERSION = props.getProperty("version");
Version.BUILD_TIME = props.getProperty("build-time");
Version.RESOURCES_VERSION = Version.VERSION.toLowerCase();
+
+ if (Version.RESOURCES_VERSION.endsWith("-snapshot")) {
+ Version.RESOURCES_VERSION = Version.RESOURCES_VERSION.replace("-snapshot", "-" + Version.BUILD_TIME.replace(" ", "").replace(":", "").replace("-", ""));
+ }
} catch (IOException e) {
Version.VERSION = Version.UNKNOWN;
Version.BUILD_TIME = Version.UNKNOWN;
diff --git a/common/src/main/java/org/keycloak/common/util/Encode.java b/common/src/main/java/org/keycloak/common/util/Encode.java
index 63b8f3653f..b19536240f 100755
--- a/common/src/main/java/org/keycloak/common/util/Encode.java
+++ b/common/src/main/java/org/keycloak/common/util/Encode.java
@@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -36,7 +37,7 @@ import java.util.regex.Pattern;
*/
public class Encode
{
- private static final String UTF_8 = "UTF-8";
+ private static final String UTF_8 = StandardCharsets.UTF_8.name();
private static final Pattern PARAM_REPLACEMENT = Pattern.compile("_resteasy_uri_parameter");
@@ -84,9 +85,7 @@ public class Encode
case '@':
continue;
}
- StringBuffer sb = new StringBuffer();
- sb.append((char) i);
- pathEncoding[i] = URLEncoder.encode(sb.toString());
+ pathEncoding[i] = URLEncoder.encode(String.valueOf((char) i));
}
pathEncoding[' '] = "%20";
System.arraycopy(pathEncoding, 0, matrixParameterEncoding, 0, pathEncoding.length);
@@ -119,9 +118,7 @@ public class Encode
queryNameValueEncoding[i] = "+";
continue;
}
- StringBuffer sb = new StringBuffer();
- sb.append((char) i);
- queryNameValueEncoding[i] = URLEncoder.encode(sb.toString());
+ queryNameValueEncoding[i] = URLEncoder.encode(String.valueOf((char) i));
}
/*
@@ -159,9 +156,7 @@ public class Encode
queryStringEncoding[i] = "%20";
continue;
}
- StringBuffer sb = new StringBuffer();
- sb.append((char) i);
- queryStringEncoding[i] = URLEncoder.encode(sb.toString());
+ queryStringEncoding[i] = URLEncoder.encode(String.valueOf((char) i));
}
}
@@ -194,7 +189,7 @@ public class Encode
*/
public static String encodeFragment(String value)
{
- return encodeValue(value, queryNameValueEncoding);
+ return encodeValue(value, queryStringEncoding);
}
/**
@@ -221,18 +216,19 @@ public class Encode
public static String decodePath(String path)
{
Matcher matcher = encodedCharsMulti.matcher(path);
- StringBuffer buf = new StringBuffer();
+ int start=0;
+ StringBuilder builder = new StringBuilder();
CharsetDecoder decoder = Charset.forName(UTF_8).newDecoder();
while (matcher.find())
{
+ builder.append(path, start, matcher.start());
decoder.reset();
String decoded = decodeBytes(matcher.group(1), decoder);
- decoded = decoded.replace("\\", "\\\\");
- decoded = decoded.replace("$", "\\$");
- matcher.appendReplacement(buf, decoded);
+ builder.append(decoded);
+ start = matcher.end();
}
- matcher.appendTail(buf);
- return buf.toString();
+ builder.append(path, start, path.length());
+ return builder.toString();
}
private static String decodeBytes(String enc, CharsetDecoder decoder)
@@ -264,7 +260,7 @@ public class Encode
public static String encodeNonCodes(String string)
{
Matcher matcher = nonCodes.matcher(string);
- StringBuffer buf = new StringBuffer();
+ StringBuilder builder = new StringBuilder();
// FYI: we do not use the no-arg matcher.find()
@@ -276,29 +272,32 @@ public class Encode
while (matcher.find(idx))
{
int start = matcher.start();
- buf.append(string.substring(idx, start));
- buf.append("%25");
+ builder.append(string.substring(idx, start));
+ builder.append("%25");
idx = start + 1;
}
- buf.append(string.substring(idx));
- return buf.toString();
+ builder.append(string.substring(idx));
+ return builder.toString();
}
- private static boolean savePathParams(String segment, StringBuffer newSegment, List params)
+ public static boolean savePathParams(String segment, StringBuilder newSegment, List params)
{
boolean foundParam = false;
// Regular expressions can have '{' and '}' characters. Replace them to do match
segment = PathHelper.replaceEnclosedCurlyBraces(segment);
Matcher matcher = PathHelper.URI_TEMPLATE_PATTERN.matcher(segment);
+ int start = 0;
while (matcher.find())
{
+ newSegment.append(segment, start, matcher.start());
foundParam = true;
String group = matcher.group();
// Regular expressions can have '{' and '}' characters. Recover earlier replacement
params.add(PathHelper.recoverEnclosedCurlyBraces(group));
- matcher.appendReplacement(newSegment, "_resteasy_uri_parameter");
+ newSegment.append("_resteasy_uri_parameter");
+ start = matcher.end();
}
- matcher.appendTail(newSegment);
+ newSegment.append(segment, start, segment.length());
return foundParam;
}
@@ -309,11 +308,11 @@ public class Encode
* @param encoding
* @return
*/
- private static String encodeValue(String segment, String[] encoding)
+ public static String encodeValue(String segment, String[] encoding)
{
ArrayList params = new ArrayList();
boolean foundParam = false;
- StringBuffer newSegment = new StringBuffer();
+ StringBuilder newSegment = new StringBuilder();
if (savePathParams(segment, newSegment, params))
{
foundParam = true;
@@ -411,21 +410,21 @@ public class Encode
return encodeFromArray(nameOrValue, queryNameValueEncoding, true);
}
- private static String encodeFromArray(String segment, String[] encodingMap, boolean encodePercent)
+ protected static String encodeFromArray(String segment, String[] encodingMap, boolean encodePercent)
{
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
for (int i = 0; i < segment.length(); i++)
{
- if (!encodePercent && segment.charAt(i) == '%')
+ char currentChar = segment.charAt(i);
+ if (!encodePercent && currentChar == '%')
{
- result.append(segment.charAt(i));
+ result.append(currentChar);
continue;
}
- int idx = segment.charAt(i);
- String encoding = encode(idx, encodingMap);
+ String encoding = encode(currentChar, encodingMap);
if (encoding == null)
{
- result.append(segment.charAt(i));
+ result.append(currentChar);
}
else
{
@@ -461,20 +460,20 @@ public class Encode
return encoded;
}
- private static String pathParamReplacement(String segment, List params)
+ public static String pathParamReplacement(String segment, List params)
{
- StringBuffer newSegment = new StringBuffer();
+ StringBuilder newSegment = new StringBuilder();
Matcher matcher = PARAM_REPLACEMENT.matcher(segment);
int i = 0;
+ int start = 0;
while (matcher.find())
{
+ newSegment.append(segment, start, matcher.start());
String replacement = params.get(i++);
- // double encode slashes, so that slashes stay where they are
- replacement = replacement.replace("\\", "\\\\");
- replacement = replacement.replace("$", "\\$");
- matcher.appendReplacement(newSegment, replacement);
+ newSegment.append(replacement);
+ start = matcher.end();
}
- matcher.appendTail(newSegment);
+ newSegment.append(segment, start, segment.length());
segment = newSegment.toString();
return segment;
}
@@ -505,6 +504,38 @@ public class Encode
}
return decoded;
}
+
+ /**
+ * decode an encoded map
+ *
+ * @param map
+ * @param charset
+ * @return
+ */
+ public static MultivaluedHashMap decode(MultivaluedHashMap map, String charset)
+ {
+ if (charset == null)
+ {
+ charset = UTF_8;
+ }
+ MultivaluedHashMap decoded = new MultivaluedHashMap();
+ for (Map.Entry> entry : map.entrySet())
+ {
+ List values = entry.getValue();
+ for (String value : values)
+ {
+ try
+ {
+ decoded.add(URLDecoder.decode(entry.getKey(), charset), URLDecoder.decode(value, charset));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return decoded;
+ }
public static MultivaluedHashMap encode(MultivaluedHashMap map)
{
diff --git a/common/src/main/java/org/keycloak/common/util/KeycloakUriBuilder.java b/common/src/main/java/org/keycloak/common/util/KeycloakUriBuilder.java
index f064163cd2..a03c53cbe8 100755
--- a/common/src/main/java/org/keycloak/common/util/KeycloakUriBuilder.java
+++ b/common/src/main/java/org/keycloak/common/util/KeycloakUriBuilder.java
@@ -614,7 +614,7 @@ public class KeycloakUriBuilder {
if (value == null) throw new IllegalArgumentException("A passed in value was null");
if (query == null) query = "";
else query += "&";
- query += Encode.encodeQueryParam(name) + "=" + Encode.encodeQueryParam(value.toString());
+ query += Encode.encodeQueryParamAsIs(name) + "=" + Encode.encodeQueryParamAsIs(value.toString());
}
return this;
}
diff --git a/core/pom.xml b/core/pom.xml
index 77fd3b7e72..c759a8a8ff 100755
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core/src/main/java/org/keycloak/OAuth2Constants.java b/core/src/main/java/org/keycloak/OAuth2Constants.java
index 234b632b04..2e585c3278 100644
--- a/core/src/main/java/org/keycloak/OAuth2Constants.java
+++ b/core/src/main/java/org/keycloak/OAuth2Constants.java
@@ -50,6 +50,7 @@ public interface OAuth2Constants {
String AUTHORIZATION_CODE = "authorization_code";
+
String IMPLICIT = "implicit";
String PASSWORD = "password";
@@ -92,6 +93,16 @@ public interface OAuth2Constants {
String PKCE_METHOD_PLAIN = "plain";
String PKCE_METHOD_S256 = "S256";
+ String TOKEN_EXCHANGE_GRANT_TYPE="urn:ietf:params:oauth:grant-type:token-exchange";
+ String AUDIENCE="audience";
+ String SUBJECT_TOKEN="subject_token";
+ String SUBJECT_TOKEN_TYPE="subject_token_type";
+ String ACCESS_TOKEN_TYPE="urn:ietf:params:oauth:token-type:access_token";
+ String REFRESH_TOKEN_TYPE="urn:ietf:params:oauth:token-type:refresh_token";
+ String JWT_TOKEN_TYPE="urn:ietf:params:oauth:token-type:jwt";
+ String ID_TOKEN_TYPE="urn:ietf:params:oauth:token-type:id_token";
+
+
}
diff --git a/core/src/main/java/org/keycloak/representations/adapters/config/BaseAdapterConfig.java b/core/src/main/java/org/keycloak/representations/adapters/config/BaseAdapterConfig.java
index 4a2b7e288f..ebd49ab9dc 100755
--- a/core/src/main/java/org/keycloak/representations/adapters/config/BaseAdapterConfig.java
+++ b/core/src/main/java/org/keycloak/representations/adapters/config/BaseAdapterConfig.java
@@ -62,7 +62,8 @@ public class BaseAdapterConfig extends BaseRealmConfig {
protected boolean publicClient;
@JsonProperty("credentials")
protected Map credentials = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
+ @JsonProperty("redirect-rewrite-rules")
+ protected Map redirectRewriteRules;
public boolean isUseResourceRoleMappings() {
return useResourceRoleMappings;
@@ -167,4 +168,14 @@ public class BaseAdapterConfig extends BaseRealmConfig {
public void setPublicClient(boolean publicClient) {
this.publicClient = publicClient;
}
+
+ public Map getRedirectRewriteRules() {
+ return redirectRewriteRules;
+ }
+
+ public void setRedirectRewriteRules(Map redirectRewriteRules) {
+ this.redirectRewriteRules = redirectRewriteRules;
+ }
+
+
}
diff --git a/core/src/main/java/org/keycloak/representations/docker/DockerAccess.java b/core/src/main/java/org/keycloak/representations/docker/DockerAccess.java
new file mode 100644
index 0000000000..969bcb03ab
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/docker/DockerAccess.java
@@ -0,0 +1,119 @@
+package org.keycloak.representations.docker;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Per the docker auth v2 spec, access is defined like this:
+ *
+ * {
+ * "type": "repository",
+ * "name": "samalba/my-app",
+ * "actions": [
+ * "push",
+ * "pull"
+ * ]
+ * }
+ *
+ */
+public class DockerAccess {
+
+ public static final int ACCESS_TYPE = 0;
+ public static final int REPOSITORY_NAME = 1;
+ public static final int PERMISSIONS = 2;
+ public static final String DECODE_ENCODING = "UTF-8";
+
+ @JsonProperty("type")
+ protected String type;
+ @JsonProperty("name")
+ protected String name;
+ @JsonProperty("actions")
+ protected List actions;
+
+ public DockerAccess() {
+ }
+
+ public DockerAccess(final String scopeParam) {
+ if (scopeParam != null) {
+ try {
+ final String unencoded = URLDecoder.decode(scopeParam, DECODE_ENCODING);
+ final String[] parts = unencoded.split(":");
+ if (parts.length != 3) {
+ throw new IllegalArgumentException(String.format("Expecting input string to have %d parts delineated by a ':' character. " +
+ "Found %d parts: %s", 3, parts.length, unencoded));
+ }
+
+ type = parts[ACCESS_TYPE];
+ name = parts[REPOSITORY_NAME];
+ if (parts[PERMISSIONS] != null) {
+ actions = Arrays.asList(parts[PERMISSIONS].split(","));
+ }
+ } catch (final UnsupportedEncodingException e) {
+ throw new IllegalStateException("Error attempting to decode scope parameter using encoding: " + DECODE_ENCODING);
+ }
+ }
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public DockerAccess setType(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public DockerAccess setName(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public List getActions() {
+ return actions;
+ }
+
+ public DockerAccess setActions(final List actions) {
+ this.actions = actions;
+ return this;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DockerAccess)) return false;
+
+ final DockerAccess that = (DockerAccess) o;
+
+ if (type != null ? !type.equals(that.type) : that.type != null) return false;
+ if (name != null ? !name.equals(that.name) : that.name != null) return false;
+ return actions != null ? actions.equals(that.actions) : that.actions == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (actions != null ? actions.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "DockerAccess{" +
+ "type='" + type + '\'' +
+ ", name='" + name + '\'' +
+ ", actions=" + actions +
+ '}';
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/docker/DockerError.java b/core/src/main/java/org/keycloak/representations/docker/DockerError.java
new file mode 100644
index 0000000000..b33bb58749
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/docker/DockerError.java
@@ -0,0 +1,84 @@
+package org.keycloak.representations.docker;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+
+/**
+ * JSON Representation of a Docker Error in the following format:
+ *
+ *
+ * {
+ * "code": "UNAUTHORIZED",
+ * "message": "access to the requested resource is not authorized",
+ * "detail": [
+ * {
+ * "Type": "repository",
+ * "Name": "samalba/my-app",
+ * "Action": "pull"
+ * },
+ * {
+ * "Type": "repository",
+ * "Name": "samalba/my-app",
+ * "Action": "push"
+ * }
+ * ]
+ * }
+ */
+public class DockerError {
+
+
+ @JsonProperty("code")
+ private final String errorCode;
+ @JsonProperty("message")
+ private final String message;
+ @JsonProperty("detail")
+ private final List dockerErrorDetails;
+
+ public DockerError(final String errorCode, final String message, final List dockerErrorDetails) {
+ this.errorCode = errorCode;
+ this.message = message;
+ this.dockerErrorDetails = dockerErrorDetails;
+ }
+
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public List getDockerErrorDetails() {
+ return dockerErrorDetails;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DockerError)) return false;
+
+ final DockerError that = (DockerError) o;
+
+ if (errorCode != that.errorCode) return false;
+ if (message != null ? !message.equals(that.message) : that.message != null) return false;
+ return dockerErrorDetails != null ? dockerErrorDetails.equals(that.dockerErrorDetails) : that.dockerErrorDetails == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = errorCode != null ? errorCode.hashCode() : 0;
+ result = 31 * result + (message != null ? message.hashCode() : 0);
+ result = 31 * result + (dockerErrorDetails != null ? dockerErrorDetails.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "DockerError{" +
+ "errorCode=" + errorCode +
+ ", message='" + message + '\'' +
+ ", dockerErrorDetails=" + dockerErrorDetails +
+ '}';
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/docker/DockerErrorResponseToken.java b/core/src/main/java/org/keycloak/representations/docker/DockerErrorResponseToken.java
new file mode 100644
index 0000000000..3d961ce946
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/docker/DockerErrorResponseToken.java
@@ -0,0 +1,38 @@
+package org.keycloak.representations.docker;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+
+public class DockerErrorResponseToken {
+
+
+ @JsonProperty("errors")
+ private final List errorList;
+
+ public DockerErrorResponseToken(final List errorList) {
+ this.errorList = errorList;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DockerErrorResponseToken)) return false;
+
+ final DockerErrorResponseToken that = (DockerErrorResponseToken) o;
+
+ return errorList != null ? errorList.equals(that.errorList) : that.errorList == null;
+ }
+
+ @Override
+ public int hashCode() {
+ return errorList != null ? errorList.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return "DockerErrorResponseToken{" +
+ "errorList=" + errorList +
+ '}';
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/docker/DockerResponse.java b/core/src/main/java/org/keycloak/representations/docker/DockerResponse.java
new file mode 100644
index 0000000000..98074fa689
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/docker/DockerResponse.java
@@ -0,0 +1,88 @@
+package org.keycloak.representations.docker;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Creates a response understandable by the docker client in the form:
+ *
+ {
+ "token" : "eyJh...nSQ",
+ "expires_in" : 300,
+ "issued_at" : "2016-09-02T10:56:33Z"
+ }
+ */
+public class DockerResponse {
+
+ @JsonProperty("token")
+ private String token;
+ @JsonProperty("expires_in")
+ private Integer expires_in;
+ @JsonProperty("issued_at")
+ private String issued_at;
+
+ public DockerResponse() {
+ }
+
+ public DockerResponse(final String token, final Integer expires_in, final String issued_at) {
+ this.token = token;
+ this.expires_in = expires_in;
+ this.issued_at = issued_at;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public DockerResponse setToken(final String token) {
+ this.token = token;
+ return this;
+ }
+
+ public Integer getExpires_in() {
+ return expires_in;
+ }
+
+ public DockerResponse setExpires_in(final Integer expires_in) {
+ this.expires_in = expires_in;
+ return this;
+ }
+
+ public String getIssued_at() {
+ return issued_at;
+ }
+
+ public DockerResponse setIssued_at(final String issued_at) {
+ this.issued_at = issued_at;
+ return this;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DockerResponse)) return false;
+
+ final DockerResponse that = (DockerResponse) o;
+
+ if (token != null ? !token.equals(that.token) : that.token != null) return false;
+ if (expires_in != null ? !expires_in.equals(that.expires_in) : that.expires_in != null) return false;
+ return issued_at != null ? issued_at.equals(that.issued_at) : that.issued_at == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = token != null ? token.hashCode() : 0;
+ result = 31 * result + (expires_in != null ? expires_in.hashCode() : 0);
+ result = 31 * result + (issued_at != null ? issued_at.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "DockerResponse{" +
+ "token='" + token + '\'' +
+ ", expires_in='" + expires_in + '\'' +
+ ", issued_at='" + issued_at + '\'' +
+ '}';
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/docker/DockerResponseToken.java b/core/src/main/java/org/keycloak/representations/docker/DockerResponseToken.java
new file mode 100644
index 0000000000..faee452c5b
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/docker/DockerResponseToken.java
@@ -0,0 +1,97 @@
+package org.keycloak.representations.docker;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.keycloak.representations.JsonWebToken;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * * {
+ * "iss": "auth.docker.com",
+ * "sub": "jlhawn",
+ * "aud": "registry.docker.com",
+ * "exp": 1415387315,
+ * "nbf": 1415387015,
+ * "iat": 1415387015,
+ * "jti": "tYJCO1c6cnyy7kAn0c7rKPgbV1H1bFws",
+ * "access": [
+ * {
+ * "type": "repository",
+ * "name": "samalba/my-app",
+ * "actions": [
+ * "push"
+ * ]
+ * }
+ * ]
+ * }
+ */
+public class DockerResponseToken extends JsonWebToken {
+
+ @JsonProperty("access")
+ protected List accessItems = new ArrayList<>();
+
+ public List getAccessItems() {
+ return accessItems;
+ }
+
+ @Override
+ public DockerResponseToken id(final String id) {
+ super.id(id);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken expiration(final int expiration) {
+ super.expiration(expiration);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken notBefore(final int notBefore) {
+ super.notBefore(notBefore);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken issuedNow() {
+ super.issuedNow();
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken issuedAt(final int issuedAt) {
+ super.issuedAt(issuedAt);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken issuer(final String issuer) {
+ super.issuer(issuer);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken audience(final String... audience) {
+ super.audience(audience);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken subject(final String subject) {
+ super.subject(subject);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken type(final String type) {
+ super.type(type);
+ return this;
+ }
+
+ @Override
+ public DockerResponseToken issuedFor(final String issuedFor) {
+ super.issuedFor(issuedFor);
+ return this;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
index d597cf32aa..95c7ca3d1a 100755
--- a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
@@ -155,4 +155,101 @@ public class CredentialRepresentation {
public void setConfig(MultivaluedHashMap config) {
this.config = config;
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((algorithm == null) ? 0 : algorithm.hashCode());
+ result = prime * result + ((config == null) ? 0 : config.hashCode());
+ result = prime * result + ((counter == null) ? 0 : counter.hashCode());
+ result = prime * result + ((createdDate == null) ? 0 : createdDate.hashCode());
+ result = prime * result + ((device == null) ? 0 : device.hashCode());
+ result = prime * result + ((digits == null) ? 0 : digits.hashCode());
+ result = prime * result + ((hashIterations == null) ? 0 : hashIterations.hashCode());
+ result = prime * result + ((hashedSaltedValue == null) ? 0 : hashedSaltedValue.hashCode());
+ result = prime * result + ((period == null) ? 0 : period.hashCode());
+ result = prime * result + ((salt == null) ? 0 : salt.hashCode());
+ result = prime * result + ((temporary == null) ? 0 : temporary.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ CredentialRepresentation other = (CredentialRepresentation) obj;
+ if (algorithm == null) {
+ if (other.algorithm != null)
+ return false;
+ } else if (!algorithm.equals(other.algorithm))
+ return false;
+ if (config == null) {
+ if (other.config != null)
+ return false;
+ } else if (!config.equals(other.config))
+ return false;
+ if (counter == null) {
+ if (other.counter != null)
+ return false;
+ } else if (!counter.equals(other.counter))
+ return false;
+ if (createdDate == null) {
+ if (other.createdDate != null)
+ return false;
+ } else if (!createdDate.equals(other.createdDate))
+ return false;
+ if (device == null) {
+ if (other.device != null)
+ return false;
+ } else if (!device.equals(other.device))
+ return false;
+ if (digits == null) {
+ if (other.digits != null)
+ return false;
+ } else if (!digits.equals(other.digits))
+ return false;
+ if (hashIterations == null) {
+ if (other.hashIterations != null)
+ return false;
+ } else if (!hashIterations.equals(other.hashIterations))
+ return false;
+ if (hashedSaltedValue == null) {
+ if (other.hashedSaltedValue != null)
+ return false;
+ } else if (!hashedSaltedValue.equals(other.hashedSaltedValue))
+ return false;
+ if (period == null) {
+ if (other.period != null)
+ return false;
+ } else if (!period.equals(other.period))
+ return false;
+ if (salt == null) {
+ if (other.salt != null)
+ return false;
+ } else if (!salt.equals(other.salt))
+ return false;
+ if (temporary == null) {
+ if (other.temporary != null)
+ return false;
+ } else if (!temporary.equals(other.temporary))
+ return false;
+ if (type == null) {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 670e1d8bde..c3dd733262 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -137,6 +137,7 @@ public class RealmRepresentation {
protected String directGrantFlow;
protected String resetCredentialsFlow;
protected String clientAuthenticationFlow;
+ protected String dockerAuthenticationFlow;
protected Map attributes;
@@ -884,6 +885,15 @@ public class RealmRepresentation {
this.clientAuthenticationFlow = clientAuthenticationFlow;
}
+ public String getDockerAuthenticationFlow() {
+ return dockerAuthenticationFlow;
+ }
+
+ public RealmRepresentation setDockerAuthenticationFlow(final String dockerAuthenticationFlow) {
+ this.dockerAuthenticationFlow = dockerAuthenticationFlow;
+ return this;
+ }
+
public String getKeycloakVersion() {
return keycloakVersion;
}
diff --git a/core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java b/core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java
index e1b704e206..8dcf00631f 100644
--- a/core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java
@@ -21,8 +21,18 @@ import java.util.Map;
public class ProviderRepresentation {
+ private int order;
+
private Map operationalInfo;
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int priorityUI) {
+ this.order = priorityUI;
+ }
+
public Map getOperationalInfo() {
return operationalInfo;
}
diff --git a/dependencies/pom.xml b/dependencies/pom.xml
index e98ce5ac39..f0b973029d 100755
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml
index 4bf1baa5d2..4061b97a97 100755
--- a/dependencies/server-all/pom.xml
+++ b/dependencies/server-all/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
4.0.0
diff --git a/dependencies/server-min/pom.xml b/dependencies/server-min/pom.xml
index f4938b011b..216bbad7e2 100755
--- a/dependencies/server-min/pom.xml
+++ b/dependencies/server-min/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
4.0.0
diff --git a/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
index bd92f052fc..f10d11a7eb 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
index 004e6c1342..2529bc45db 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
@@ -25,7 +25,7 @@
keycloak-as7-eap6-adapter-dist-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
index 670fcd45f1..f2c5dac490 100755
--- a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-as7-eap6-adapter-dist-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/distribution/adapters/as7-eap6-adapter/pom.xml b/distribution/adapters/as7-eap6-adapter/pom.xml
index 6096915bca..e94db3a959 100644
--- a/distribution/adapters/as7-eap6-adapter/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak AS7 / JBoss EAP 6 Adapter Distros
diff --git a/distribution/adapters/fuse-adapter-zip/pom.xml b/distribution/adapters/fuse-adapter-zip/pom.xml
index 7bfd0d2b89..03db2b4868 100644
--- a/distribution/adapters/fuse-adapter-zip/pom.xml
+++ b/distribution/adapters/fuse-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/jetty81-adapter-zip/pom.xml b/distribution/adapters/jetty81-adapter-zip/pom.xml
index 76713f4002..5cfa1988a1 100755
--- a/distribution/adapters/jetty81-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty81-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/jetty91-adapter-zip/pom.xml b/distribution/adapters/jetty91-adapter-zip/pom.xml
index e83caa8c8a..506bf22f29 100755
--- a/distribution/adapters/jetty91-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty91-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/jetty92-adapter-zip/pom.xml b/distribution/adapters/jetty92-adapter-zip/pom.xml
index eb247cbe1c..62c81b80a8 100755
--- a/distribution/adapters/jetty92-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty92-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/jetty93-adapter-zip/pom.xml b/distribution/adapters/jetty93-adapter-zip/pom.xml
index c7ec2de517..f42fcd9283 100644
--- a/distribution/adapters/jetty93-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty93-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/jetty94-adapter-zip/pom.xml b/distribution/adapters/jetty94-adapter-zip/pom.xml
index d776cb0a4a..bd199c9f5e 100644
--- a/distribution/adapters/jetty94-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty94-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/js-adapter-zip/pom.xml b/distribution/adapters/js-adapter-zip/pom.xml
index 1a93bb4648..be37dc8729 100755
--- a/distribution/adapters/js-adapter-zip/pom.xml
+++ b/distribution/adapters/js-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/osgi/features/pom.xml b/distribution/adapters/osgi/features/pom.xml
index 8cef75b8f0..36ef9f35af 100755
--- a/distribution/adapters/osgi/features/pom.xml
+++ b/distribution/adapters/osgi/features/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
Keycloak OSGI Features
diff --git a/distribution/adapters/osgi/jaas/pom.xml b/distribution/adapters/osgi/jaas/pom.xml
index 1c7182c8ce..2994b3cea2 100755
--- a/distribution/adapters/osgi/jaas/pom.xml
+++ b/distribution/adapters/osgi/jaas/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
Keycloak OSGI JAAS Realm Configuration
diff --git a/distribution/adapters/osgi/pom.xml b/distribution/adapters/osgi/pom.xml
index 523e714035..61b801af46 100755
--- a/distribution/adapters/osgi/pom.xml
+++ b/distribution/adapters/osgi/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak OSGI Integration
diff --git a/distribution/adapters/osgi/thirdparty/pom.xml b/distribution/adapters/osgi/thirdparty/pom.xml
index db047062fc..bf42fa8ca3 100755
--- a/distribution/adapters/osgi/thirdparty/pom.xml
+++ b/distribution/adapters/osgi/thirdparty/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/adapters/pom.xml b/distribution/adapters/pom.xml
index 2fc0f9c12b..6e4193fe2f 100755
--- a/distribution/adapters/pom.xml
+++ b/distribution/adapters/pom.xml
@@ -20,7 +20,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Adapters Distribution Parent
diff --git a/distribution/adapters/tomcat6-adapter-zip/pom.xml b/distribution/adapters/tomcat6-adapter-zip/pom.xml
index 77dd6bc555..1ba65022c0 100755
--- a/distribution/adapters/tomcat6-adapter-zip/pom.xml
+++ b/distribution/adapters/tomcat6-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/tomcat7-adapter-zip/pom.xml b/distribution/adapters/tomcat7-adapter-zip/pom.xml
index 5ccad77d37..391c642dc8 100755
--- a/distribution/adapters/tomcat7-adapter-zip/pom.xml
+++ b/distribution/adapters/tomcat7-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/tomcat8-adapter-zip/pom.xml b/distribution/adapters/tomcat8-adapter-zip/pom.xml
index e02660f0b2..d87f87b67b 100755
--- a/distribution/adapters/tomcat8-adapter-zip/pom.xml
+++ b/distribution/adapters/tomcat8-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/adapters/wf8-adapter/pom.xml b/distribution/adapters/wf8-adapter/pom.xml
index f975da8aab..05b72b5ef1 100644
--- a/distribution/adapters/wf8-adapter/pom.xml
+++ b/distribution/adapters/wf8-adapter/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak Wildfly 8 Adapter
diff --git a/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml b/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml
index fdb1c3fa1a..a88f373c91 100755
--- a/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml
+++ b/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/adapters/wf8-adapter/wf8-modules/pom.xml b/distribution/adapters/wf8-adapter/wf8-modules/pom.xml
index b7cd80720c..88f191bffb 100755
--- a/distribution/adapters/wf8-adapter/wf8-modules/pom.xml
+++ b/distribution/adapters/wf8-adapter/wf8-modules/pom.xml
@@ -25,7 +25,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/adapters/wildfly-adapter/pom.xml b/distribution/adapters/wildfly-adapter/pom.xml
index 6090e9cb1e..d116ab1a5f 100644
--- a/distribution/adapters/wildfly-adapter/pom.xml
+++ b/distribution/adapters/wildfly-adapter/pom.xml
@@ -21,7 +21,7 @@
keycloak-adapters-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-wildfly-adapter-dist
diff --git a/distribution/api-docs-dist/pom.xml b/distribution/api-docs-dist/pom.xml
index a50916abfc..a13c521235 100755
--- a/distribution/api-docs-dist/pom.xml
+++ b/distribution/api-docs-dist/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-api-docs-dist
@@ -62,13 +62,6 @@
-
- org.apache.maven.plugins
- maven-deploy-plugin
-
- true
-
-
maven-assembly-plugin
@@ -96,4 +89,27 @@
+
+
+
+ community
+
+
+ !product
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/distribution/demo-dist/pom.xml b/distribution/demo-dist/pom.xml
index c1668f3f9a..95ae460f83 100755
--- a/distribution/demo-dist/pom.xml
+++ b/distribution/demo-dist/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-demo-dist
diff --git a/distribution/downloads/pom.xml b/distribution/downloads/pom.xml
index eb22c9b557..4c9211911e 100755
--- a/distribution/downloads/pom.xml
+++ b/distribution/downloads/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-dist-downloads
diff --git a/distribution/examples-dist/pom.xml b/distribution/examples-dist/pom.xml
index ac57760d33..5db83ef6a8 100755
--- a/distribution/examples-dist/pom.xml
+++ b/distribution/examples-dist/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-examples-dist
diff --git a/distribution/feature-packs/adapter-feature-pack/pom.xml b/distribution/feature-packs/adapter-feature-pack/pom.xml
index 0dbb9fc74e..6f4b77b49c 100755
--- a/distribution/feature-packs/adapter-feature-pack/pom.xml
+++ b/distribution/feature-packs/adapter-feature-pack/pom.xml
@@ -19,7 +19,7 @@
org.keycloak
feature-packs-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/distribution/feature-packs/pom.xml b/distribution/feature-packs/pom.xml
index bf31d507dc..b32593d23e 100644
--- a/distribution/feature-packs/pom.xml
+++ b/distribution/feature-packs/pom.xml
@@ -20,7 +20,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Feature Pack Builds
diff --git a/distribution/feature-packs/server-feature-pack/pom.xml b/distribution/feature-packs/server-feature-pack/pom.xml
index 2d39ad1063..e2f1f4144b 100644
--- a/distribution/feature-packs/server-feature-pack/pom.xml
+++ b/distribution/feature-packs/server-feature-pack/pom.xml
@@ -19,7 +19,7 @@
org.keycloak
feature-packs-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/distribution/pom.xml b/distribution/pom.xml
index f8c0d2dcb3..165323ddc8 100755
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/distribution/proxy-dist/pom.xml b/distribution/proxy-dist/pom.xml
index ee89fa7252..79d4468de6 100755
--- a/distribution/proxy-dist/pom.xml
+++ b/distribution/proxy-dist/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-proxy-dist
diff --git a/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
index 935c85f9be..4165230f30 100755
--- a/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml
index 98ee15f2a9..f2650dfd1d 100755
--- a/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml
+++ b/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml
@@ -25,7 +25,7 @@
keycloak-saml-as7-eap6-adapter-dist-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/distribution/saml-adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml b/distribution/saml-adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml
index 4973aa1a4f..ba66c82775 100755
--- a/distribution/saml-adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml
+++ b/distribution/saml-adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml
@@ -28,6 +28,7 @@
+
diff --git a/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
index d0da2e4926..54c249d8ff 100755
--- a/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-saml-as7-eap6-adapter-dist-pom
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/distribution/saml-adapters/as7-eap6-adapter/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/pom.xml
index 0a4d2ccafb..e1c378c220 100755
--- a/distribution/saml-adapters/as7-eap6-adapter/pom.xml
+++ b/distribution/saml-adapters/as7-eap6-adapter/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak SAML AS7 / JBoss EAP 6 Adapter Distros
diff --git a/distribution/saml-adapters/jetty81-adapter-zip/pom.xml b/distribution/saml-adapters/jetty81-adapter-zip/pom.xml
index e74e1266c5..8c8f99f986 100755
--- a/distribution/saml-adapters/jetty81-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/jetty81-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/jetty92-adapter-zip/pom.xml b/distribution/saml-adapters/jetty92-adapter-zip/pom.xml
index c1250825e5..f5c3481c22 100755
--- a/distribution/saml-adapters/jetty92-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/jetty92-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/jetty93-adapter-zip/pom.xml b/distribution/saml-adapters/jetty93-adapter-zip/pom.xml
index 6fe0cb5797..e6ef28e651 100644
--- a/distribution/saml-adapters/jetty93-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/jetty93-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/jetty94-adapter-zip/pom.xml b/distribution/saml-adapters/jetty94-adapter-zip/pom.xml
index 5e66e8f763..8b86d43d74 100644
--- a/distribution/saml-adapters/jetty94-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/jetty94-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/pom.xml b/distribution/saml-adapters/pom.xml
index 4949548b46..81828d285e 100755
--- a/distribution/saml-adapters/pom.xml
+++ b/distribution/saml-adapters/pom.xml
@@ -20,7 +20,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
SAML Adapters Distribution Parent
diff --git a/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml b/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml
index 62ef4ce7cd..01cdab6a52 100755
--- a/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml b/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml
index d9eef4e114..f4a5a2d125 100755
--- a/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml b/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml
index be42ceee4a..da7c2187d6 100755
--- a/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
diff --git a/distribution/saml-adapters/wildfly-adapter/pom.xml b/distribution/saml-adapters/wildfly-adapter/pom.xml
index 6bec45308a..6d2a6e2c2e 100755
--- a/distribution/saml-adapters/wildfly-adapter/pom.xml
+++ b/distribution/saml-adapters/wildfly-adapter/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../pom.xml
Keycloak Wildfly SAML Adapter
diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml
index a30ecef034..1b80a59d54 100755
--- a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml
+++ b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml
index ec9659522e..e398bbbe5f 100755
--- a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml
+++ b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml
@@ -25,7 +25,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../../../pom.xml
diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml
index e19e0f026d..ef44695f72 100755
--- a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml
+++ b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-adapter-core/main/module.xml
@@ -28,6 +28,7 @@
+
diff --git a/distribution/server-dist/pom.xml b/distribution/server-dist/pom.xml
index fd216303ff..6b425c0a13 100755
--- a/distribution/server-dist/pom.xml
+++ b/distribution/server-dist/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-server-dist
@@ -34,11 +34,23 @@
org.keycloak
keycloak-server-feature-pack
zip
+
+
+ *
+ *
+
+
org.keycloak
keycloak-client-cli-dist
zip
+
+
+ *
+ *
+
+
diff --git a/distribution/server-overlay/pom.xml b/distribution/server-overlay/pom.xml
index d3310bbe26..f8a0c538ba 100755
--- a/distribution/server-overlay/pom.xml
+++ b/distribution/server-overlay/pom.xml
@@ -21,7 +21,7 @@
keycloak-distribution-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-server-overlay
diff --git a/examples/admin-client/pom.xml b/examples/admin-client/pom.xml
index e7339f7de0..c5ac43eafb 100755
--- a/examples/admin-client/pom.xml
+++ b/examples/admin-client/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples - Admin Client
diff --git a/examples/authz/hello-world-authz-service/pom.xml b/examples/authz/hello-world-authz-service/pom.xml
index 2067d82f58..26c1777330 100755
--- a/examples/authz/hello-world-authz-service/pom.xml
+++ b/examples/authz/hello-world-authz-service/pom.xml
@@ -24,7 +24,7 @@
org.keycloak
keycloak-authz-example-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/hello-world/pom.xml b/examples/authz/hello-world/pom.xml
index 50e51993e6..afdc3fb879 100755
--- a/examples/authz/hello-world/pom.xml
+++ b/examples/authz/hello-world/pom.xml
@@ -24,7 +24,7 @@
org.keycloak
keycloak-authz-example-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/photoz/photoz-authz-policy/pom.xml b/examples/authz/photoz/photoz-authz-policy/pom.xml
index 8115179975..08267aa479 100755
--- a/examples/authz/photoz/photoz-authz-policy/pom.xml
+++ b/examples/authz/photoz/photoz-authz-policy/pom.xml
@@ -6,7 +6,7 @@
org.keycloak
keycloak-authz-photoz-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/photoz/photoz-html5-client/pom.xml b/examples/authz/photoz/photoz-html5-client/pom.xml
index 09db1e5aca..5ff5fdb136 100755
--- a/examples/authz/photoz/photoz-html5-client/pom.xml
+++ b/examples/authz/photoz/photoz-html5-client/pom.xml
@@ -5,7 +5,7 @@
org.keycloak
keycloak-authz-photoz-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/photoz/photoz-restful-api/pom.xml b/examples/authz/photoz/photoz-restful-api/pom.xml
index 918c2584fc..94b73dc07b 100755
--- a/examples/authz/photoz/photoz-restful-api/pom.xml
+++ b/examples/authz/photoz/photoz-restful-api/pom.xml
@@ -6,7 +6,7 @@
org.keycloak
keycloak-authz-photoz-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java b/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
index 129a11a080..1fe66757b5 100644
--- a/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
+++ b/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
@@ -83,14 +83,14 @@ public class AlbumService {
@GET
@Produces("application/json")
public Response findAll() {
- return Response.ok(this.entityManager.createQuery("from Album where userId = '" + request.getUserPrincipal().getName() + "'").getResultList()).build();
+ return Response.ok(this.entityManager.createQuery("from Album where userId = :id").setParameter("id", request.getUserPrincipal().getName()).getResultList()).build();
}
@GET
@Path("{id}")
@Produces("application/json")
public Response findById(@PathParam("id") String id) {
- List result = this.entityManager.createQuery("from Album where id = " + id).getResultList();
+ List result = this.entityManager.createQuery("from Album where id = :id").setParameter("id", id).getResultList();
if (result.isEmpty()) {
return Response.status(Status.NOT_FOUND).build();
diff --git a/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java b/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java
index 92e300dec5..62591227d7 100644
--- a/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java
+++ b/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/ProfileService.java
@@ -43,7 +43,7 @@ public class ProfileService {
@Produces("application/json")
public Response view(@Context HttpServletRequest request) {
Principal userPrincipal = request.getUserPrincipal();
- List albums = this.entityManager.createQuery("from Album where userId = '" + userPrincipal.getName() + "'").getResultList();
+ List albums = this.entityManager.createQuery("from Album where userId = :id").setParameter("id", userPrincipal.getName()).getResultList();
return Response.ok(new Profile(userPrincipal.getName(), albums.size())).build();
}
diff --git a/examples/authz/photoz/pom.xml b/examples/authz/photoz/pom.xml
index a863cd21d7..cbaeb243ec 100755
--- a/examples/authz/photoz/pom.xml
+++ b/examples/authz/photoz/pom.xml
@@ -6,7 +6,7 @@
org.keycloak
keycloak-authz-example-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/pom.xml b/examples/authz/pom.xml
index 03012e716c..06adb3ca98 100755
--- a/examples/authz/pom.xml
+++ b/examples/authz/pom.xml
@@ -6,7 +6,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/authz/servlet-authz/pom.xml b/examples/authz/servlet-authz/pom.xml
index 68e672cb1a..ffcf7f2085 100755
--- a/examples/authz/servlet-authz/pom.xml
+++ b/examples/authz/servlet-authz/pom.xml
@@ -6,7 +6,7 @@
org.keycloak
keycloak-authz-example-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
diff --git a/examples/basic-auth/pom.xml b/examples/basic-auth/pom.xml
index 0c12d2ba92..af19e13ef0 100755
--- a/examples/basic-auth/pom.xml
+++ b/examples/basic-auth/pom.xml
@@ -23,7 +23,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples - Basic Auth
diff --git a/examples/broker/facebook-authentication/pom.xml b/examples/broker/facebook-authentication/pom.xml
index c0ef110d74..0fb71b4a4e 100755
--- a/examples/broker/facebook-authentication/pom.xml
+++ b/examples/broker/facebook-authentication/pom.xml
@@ -23,7 +23,7 @@
keycloak-examples-broker-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Broker Examples - Facebook Authentication
diff --git a/examples/broker/google-authentication/pom.xml b/examples/broker/google-authentication/pom.xml
index d29e41fddb..e89fbc560f 100755
--- a/examples/broker/google-authentication/pom.xml
+++ b/examples/broker/google-authentication/pom.xml
@@ -23,7 +23,7 @@
keycloak-examples-broker-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Broker Examples - Google Authentication
diff --git a/examples/broker/pom.xml b/examples/broker/pom.xml
index aed134df5d..5797474cc6 100755
--- a/examples/broker/pom.xml
+++ b/examples/broker/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Broker Examples
diff --git a/examples/broker/saml-broker-authentication/pom.xml b/examples/broker/saml-broker-authentication/pom.xml
index eda4dd75c0..3226fbc353 100755
--- a/examples/broker/saml-broker-authentication/pom.xml
+++ b/examples/broker/saml-broker-authentication/pom.xml
@@ -23,7 +23,7 @@
keycloak-examples-broker-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Broker Examples - SAML Identity Provider Brokering
diff --git a/examples/broker/twitter-authentication/pom.xml b/examples/broker/twitter-authentication/pom.xml
index aa54475306..188035d0e8 100755
--- a/examples/broker/twitter-authentication/pom.xml
+++ b/examples/broker/twitter-authentication/pom.xml
@@ -23,7 +23,7 @@
keycloak-examples-broker-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Broker Examples - Twitter Authentication
diff --git a/examples/cors/angular-product-app/pom.xml b/examples/cors/angular-product-app/pom.xml
index 1a2a669b83..28e65fcf6b 100755
--- a/examples/cors/angular-product-app/pom.xml
+++ b/examples/cors/angular-product-app/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-cors-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/cors/database-service/pom.xml b/examples/cors/database-service/pom.xml
index 8e9298708c..80ccf115b2 100755
--- a/examples/cors/database-service/pom.xml
+++ b/examples/cors/database-service/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-cors-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/cors/pom.xml b/examples/cors/pom.xml
index 40b2ac83e0..3e4d71ad6d 100755
--- a/examples/cors/pom.xml
+++ b/examples/cors/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples - CORS
diff --git a/examples/demo-template/admin-access-app/pom.xml b/examples/demo-template/admin-access-app/pom.xml
index 7e1f543c01..fd2565f340 100755
--- a/examples/demo-template/admin-access-app/pom.xml
+++ b/examples/demo-template/admin-access-app/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/angular-product-app/pom.xml b/examples/demo-template/angular-product-app/pom.xml
index b02bddfddc..06c4b2ed08 100755
--- a/examples/demo-template/angular-product-app/pom.xml
+++ b/examples/demo-template/angular-product-app/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/customer-app-cli/pom.xml b/examples/demo-template/customer-app-cli/pom.xml
index eeebf5b8c0..f58edd5749 100755
--- a/examples/demo-template/customer-app-cli/pom.xml
+++ b/examples/demo-template/customer-app-cli/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/customer-app-filter/pom.xml b/examples/demo-template/customer-app-filter/pom.xml
index 444395a687..3b8146fe15 100755
--- a/examples/demo-template/customer-app-filter/pom.xml
+++ b/examples/demo-template/customer-app-filter/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/customer-app-js/pom.xml b/examples/demo-template/customer-app-js/pom.xml
index 7e252c810a..e5e6ca9af5 100755
--- a/examples/demo-template/customer-app-js/pom.xml
+++ b/examples/demo-template/customer-app-js/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/customer-app/pom.xml b/examples/demo-template/customer-app/pom.xml
index 51cf448e3c..7c59225647 100755
--- a/examples/demo-template/customer-app/pom.xml
+++ b/examples/demo-template/customer-app/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/database-service/pom.xml b/examples/demo-template/database-service/pom.xml
index 862041b0c0..e4252a4049 100755
--- a/examples/demo-template/database-service/pom.xml
+++ b/examples/demo-template/database-service/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/example-ear/pom.xml b/examples/demo-template/example-ear/pom.xml
index 8a3d4566eb..3c4d3a0f95 100755
--- a/examples/demo-template/example-ear/pom.xml
+++ b/examples/demo-template/example-ear/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/offline-access-app/pom.xml b/examples/demo-template/offline-access-app/pom.xml
index d3f6b23a94..f2af2fb3fa 100755
--- a/examples/demo-template/offline-access-app/pom.xml
+++ b/examples/demo-template/offline-access-app/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/pom.xml b/examples/demo-template/pom.xml
index bd239fb9cf..19f8b9184b 100755
--- a/examples/demo-template/pom.xml
+++ b/examples/demo-template/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Demo Examples
diff --git a/examples/demo-template/product-app/pom.xml b/examples/demo-template/product-app/pom.xml
index 3667ab8432..c565ceefd0 100755
--- a/examples/demo-template/product-app/pom.xml
+++ b/examples/demo-template/product-app/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/service-account/pom.xml b/examples/demo-template/service-account/pom.xml
index ca6152f2a2..3f8526639b 100755
--- a/examples/demo-template/service-account/pom.xml
+++ b/examples/demo-template/service-account/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/third-party-cdi/pom.xml b/examples/demo-template/third-party-cdi/pom.xml
index bcbb86fc68..20a7e7eef1 100755
--- a/examples/demo-template/third-party-cdi/pom.xml
+++ b/examples/demo-template/third-party-cdi/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/demo-template/third-party/pom.xml b/examples/demo-template/third-party/pom.xml
index faefb5b760..6aad96ccc7 100755
--- a/examples/demo-template/third-party/pom.xml
+++ b/examples/demo-template/third-party/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-demo-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/fuse/camel/pom.xml b/examples/fuse/camel/pom.xml
index ec500e8e41..0ca3c4e831 100755
--- a/examples/fuse/camel/pom.xml
+++ b/examples/fuse/camel/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/fuse/customer-app-fuse/pom.xml b/examples/fuse/customer-app-fuse/pom.xml
index 38691f2eb7..3c4bfd414d 100755
--- a/examples/fuse/customer-app-fuse/pom.xml
+++ b/examples/fuse/customer-app-fuse/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/fuse/cxf-jaxrs/pom.xml b/examples/fuse/cxf-jaxrs/pom.xml
index 31feea3841..9d3faa06c9 100755
--- a/examples/fuse/cxf-jaxrs/pom.xml
+++ b/examples/fuse/cxf-jaxrs/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/fuse/cxf-jaxws/pom.xml b/examples/fuse/cxf-jaxws/pom.xml
index 24b2fde358..f53164ca97 100755
--- a/examples/fuse/cxf-jaxws/pom.xml
+++ b/examples/fuse/cxf-jaxws/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/fuse/external-config/pom.xml b/examples/fuse/external-config/pom.xml
index 7d79af2e68..3f9f36df60 100755
--- a/examples/fuse/external-config/pom.xml
+++ b/examples/fuse/external-config/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples - External Config
diff --git a/examples/fuse/features/pom.xml b/examples/fuse/features/pom.xml
index eb1cb2b78e..a5fe72e3ea 100755
--- a/examples/fuse/features/pom.xml
+++ b/examples/fuse/features/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/fuse/pom.xml b/examples/fuse/pom.xml
index cfa9d2cc71..48e01255b1 100755
--- a/examples/fuse/pom.xml
+++ b/examples/fuse/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Fuse Examples
diff --git a/examples/fuse/product-app-fuse/pom.xml b/examples/fuse/product-app-fuse/pom.xml
index a4189258b4..e69578e4df 100755
--- a/examples/fuse/product-app-fuse/pom.xml
+++ b/examples/fuse/product-app-fuse/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-fuse-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/js-console/pom.xml b/examples/js-console/pom.xml
index 00e0e6a609..37a64e2c79 100755
--- a/examples/js-console/pom.xml
+++ b/examples/js-console/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/kerberos/pom.xml b/examples/kerberos/pom.xml
index 8687695e77..6d2d5b1814 100755
--- a/examples/kerberos/pom.xml
+++ b/examples/kerberos/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples - Kerberos Credential Delegation
diff --git a/examples/ldap/pom.xml b/examples/ldap/pom.xml
index aa506014e5..62c4d1bb67 100644
--- a/examples/ldap/pom.xml
+++ b/examples/ldap/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/examples/multi-tenant/pom.xml b/examples/multi-tenant/pom.xml
index 697878404b..6c45be0c04 100755
--- a/examples/multi-tenant/pom.xml
+++ b/examples/multi-tenant/pom.xml
@@ -21,7 +21,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples - Multi Tenant
diff --git a/examples/pom.xml b/examples/pom.xml
index 6de9216521..0421e888cd 100755
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Examples
diff --git a/examples/providers/authenticator/pom.xml b/examples/providers/authenticator/pom.xml
index d3f6ffcf80..a4042c7b42 100755
--- a/examples/providers/authenticator/pom.xml
+++ b/examples/providers/authenticator/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Authenticator Example
diff --git a/examples/providers/domain-extension/pom.xml b/examples/providers/domain-extension/pom.xml
index db892c8714..8203215750 100755
--- a/examples/providers/domain-extension/pom.xml
+++ b/examples/providers/domain-extension/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Domain Extension Example
diff --git a/examples/providers/event-listener-sysout/pom.xml b/examples/providers/event-listener-sysout/pom.xml
index b2d919e7a1..6448f1ef48 100755
--- a/examples/providers/event-listener-sysout/pom.xml
+++ b/examples/providers/event-listener-sysout/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Event Listener System.out Example
diff --git a/examples/providers/event-store-mem/pom.xml b/examples/providers/event-store-mem/pom.xml
index 379da38763..ab431451b9 100755
--- a/examples/providers/event-store-mem/pom.xml
+++ b/examples/providers/event-store-mem/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Event Store In-Mem Example
diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml
index 0ea9100760..a55f520678 100755
--- a/examples/providers/pom.xml
+++ b/examples/providers/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Provider Examples
diff --git a/examples/providers/rest/pom.xml b/examples/providers/rest/pom.xml
index 379954f061..9570a740f7 100755
--- a/examples/providers/rest/pom.xml
+++ b/examples/providers/rest/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
REST Example
diff --git a/examples/providers/user-storage-jpa/pom.xml b/examples/providers/user-storage-jpa/pom.xml
index 3bfc8a36a8..a1a5637ed5 100755
--- a/examples/providers/user-storage-jpa/pom.xml
+++ b/examples/providers/user-storage-jpa/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
User Storage JPA Provider Exapmle
diff --git a/examples/providers/user-storage-simple/pom.xml b/examples/providers/user-storage-simple/pom.xml
index 065f21b5eb..36a41cb173 100755
--- a/examples/providers/user-storage-simple/pom.xml
+++ b/examples/providers/user-storage-simple/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-providers-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
UserStorageProvider Simple Example
diff --git a/examples/saml/pom.xml b/examples/saml/pom.xml
index 9aaf1261a3..e69c6df1c5 100755
--- a/examples/saml/pom.xml
+++ b/examples/saml/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
SAML Examples
diff --git a/examples/saml/post-with-encryption/pom.xml b/examples/saml/post-with-encryption/pom.xml
index 947083d962..d4bed04efa 100755
--- a/examples/saml/post-with-encryption/pom.xml
+++ b/examples/saml/post-with-encryption/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-saml-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
saml-post-encryption
diff --git a/examples/saml/post-with-signature/pom.xml b/examples/saml/post-with-signature/pom.xml
index 1378997f37..02713e6f6e 100755
--- a/examples/saml/post-with-signature/pom.xml
+++ b/examples/saml/post-with-signature/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-saml-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
sales-post-sig
diff --git a/examples/saml/redirect-with-signature/pom.xml b/examples/saml/redirect-with-signature/pom.xml
index 41ae3efcaf..9f42085afb 100755
--- a/examples/saml/redirect-with-signature/pom.xml
+++ b/examples/saml/redirect-with-signature/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-saml-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
saml-redirect-signatures
diff --git a/examples/saml/servlet-filter/pom.xml b/examples/saml/servlet-filter/pom.xml
index cdfcb25002..e586f3e586 100755
--- a/examples/saml/servlet-filter/pom.xml
+++ b/examples/saml/servlet-filter/pom.xml
@@ -22,7 +22,7 @@
keycloak-examples-saml-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
saml-servlet-filter
diff --git a/examples/themes/pom.xml b/examples/themes/pom.xml
index 8282f60590..7d18fdf4ce 100755
--- a/examples/themes/pom.xml
+++ b/examples/themes/pom.xml
@@ -20,7 +20,7 @@
keycloak-examples-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Themes Examples
diff --git a/examples/themes/src/main/resources/theme/logo-example/admin/theme.properties b/examples/themes/src/main/resources/theme/logo-example/admin/theme.properties
index 3541fb4bed..7c933cfaca 100755
--- a/examples/themes/src/main/resources/theme/logo-example/admin/theme.properties
+++ b/examples/themes/src/main/resources/theme/logo-example/admin/theme.properties
@@ -17,4 +17,4 @@
parent=keycloak
import=common/keycloak
-styles=lib/patternfly/css/patternfly.css lib/select2-3.4.1/select2.css css/styles.css css/logo.css
\ No newline at end of file
+styles=lib/patternfly/css/patternfly.css node_modules/select2/select2.css css/styles.css css/logo.css
\ No newline at end of file
diff --git a/federation/kerberos/pom.xml b/federation/kerberos/pom.xml
index 5d25b4acea..6b026eb08c 100755
--- a/federation/kerberos/pom.xml
+++ b/federation/kerberos/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
4.0.0
diff --git a/federation/ldap/pom.xml b/federation/ldap/pom.xml
index da55bf062e..4618792225 100755
--- a/federation/ldap/pom.xml
+++ b/federation/ldap/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
4.0.0
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java
index 1f2473baab..3cf91b9485 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java
@@ -18,6 +18,7 @@
package org.keycloak.storage.ldap.mappers;
import org.jboss.logging.Logger;
+import org.keycloak.models.AbstractKeycloakTransaction;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
@@ -25,12 +26,10 @@ import org.keycloak.storage.ldap.idm.model.LDAPObject;
/**
* @author Marek Posolda
*/
-public class LDAPTransaction implements KeycloakTransaction {
+public class LDAPTransaction extends AbstractKeycloakTransaction {
public static final Logger logger = Logger.getLogger(LDAPTransaction.class);
- protected TransactionState state = TransactionState.NOT_STARTED;
-
private final LDAPStorageProvider ldapProvider;
private final LDAPObject ldapUser;
@@ -39,57 +38,21 @@ public class LDAPTransaction implements KeycloakTransaction {
this.ldapUser = ldapUser;
}
- @Override
- public void begin() {
- if (state != TransactionState.NOT_STARTED) {
- throw new IllegalStateException("Transaction already started");
- }
-
- state = TransactionState.STARTED;
- }
@Override
- public void commit() {
- if (state != TransactionState.STARTED) {
- throw new IllegalStateException("Transaction in illegal state for commit: " + state);
- }
-
+ protected void commitImpl() {
if (logger.isTraceEnabled()) {
logger.trace("Transaction commit! Updating LDAP attributes for object " + ldapUser.getDn().toString() + ", attributes: " + ldapUser.getAttributes());
}
ldapProvider.getLdapIdentityStore().update(ldapUser);
- state = TransactionState.FINISHED;
}
- @Override
- public void rollback() {
- if (state != TransactionState.STARTED && state != TransactionState.ROLLBACK_ONLY) {
- throw new IllegalStateException("Transaction in illegal state for rollback: " + state);
- }
+ @Override
+ protected void rollbackImpl() {
logger.warn("Transaction rollback! Ignoring LDAP updates for object " + ldapUser.getDn().toString());
- state = TransactionState.FINISHED;
}
- @Override
- public void setRollbackOnly() {
- state = TransactionState.ROLLBACK_ONLY;
- }
-
- @Override
- public boolean getRollbackOnly() {
- return state == TransactionState.ROLLBACK_ONLY;
- }
-
- @Override
- public boolean isActive() {
- return state == TransactionState.STARTED || state == TransactionState.ROLLBACK_ONLY;
- }
-
-
- protected enum TransactionState {
- NOT_STARTED, STARTED, ROLLBACK_ONLY, FINISHED
- }
}
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java
index 2bf88f23dd..09f4051e36 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java
@@ -41,7 +41,7 @@ public abstract class TxAwareLDAPUserModelDelegate extends UserModelDelegate {
protected void ensureTransactionStarted() {
LDAPTransaction transaction = provider.getUserManager().getTransaction(getId());
- if (transaction.state == LDAPTransaction.TransactionState.NOT_STARTED) {
+ if (transaction.getState() == LDAPTransaction.TransactionState.NOT_STARTED) {
if (logger.isTraceEnabled()) {
logger.trace("Starting and enlisting transaction for object " + ldapUser.getDn().toString());
}
diff --git a/federation/pom.xml b/federation/pom.xml
index dce02fbe7d..9136832004 100755
--- a/federation/pom.xml
+++ b/federation/pom.xml
@@ -22,7 +22,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/federation/sssd/pom.xml b/federation/sssd/pom.xml
index 55e028ced3..1e40781d8a 100644
--- a/federation/sssd/pom.xml
+++ b/federation/sssd/pom.xml
@@ -4,7 +4,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
4.0.0
diff --git a/integration/admin-client/pom.xml b/integration/admin-client/pom.xml
index d59b23ed2a..ee006ef079 100755
--- a/integration/admin-client/pom.xml
+++ b/integration/admin-client/pom.xml
@@ -22,7 +22,7 @@
keycloak-integration-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
index cba7eb3d7e..c6a1edb57b 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
@@ -38,6 +38,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -184,6 +185,12 @@ public interface RealmResource {
@QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential,
@QueryParam("useTruststoreSpi") String useTruststoreSpi, @QueryParam("connectionTimeout") String connectionTimeout);
+ @Path("testSMTPConnection/{config}")
+ @POST
+ @NoCache
+ @Consumes(MediaType.APPLICATION_JSON)
+ Response testSMTPConnection(final @PathParam("config") String config) throws Exception;
+
@Path("clear-realm-cache")
@POST
void clearRealmCache();
diff --git a/integration/client-cli/admin-cli/pom.xml b/integration/client-cli/admin-cli/pom.xml
index 733ba06ff1..10d629bed7 100755
--- a/integration/client-cli/admin-cli/pom.xml
+++ b/integration/client-cli/admin-cli/pom.xml
@@ -21,7 +21,7 @@
keycloak-client-cli-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/integration/client-cli/client-cli-dist/pom.xml b/integration/client-cli/client-cli-dist/pom.xml
index 32572ce19f..38a1d5631f 100755
--- a/integration/client-cli/client-cli-dist/pom.xml
+++ b/integration/client-cli/client-cli-dist/pom.xml
@@ -21,7 +21,7 @@
keycloak-client-cli-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-client-cli-dist
diff --git a/integration/client-cli/client-registration-cli/pom.xml b/integration/client-cli/client-registration-cli/pom.xml
index c194ddedc5..6a76bf0397 100755
--- a/integration/client-cli/client-registration-cli/pom.xml
+++ b/integration/client-cli/client-registration-cli/pom.xml
@@ -21,7 +21,7 @@
keycloak-client-cli-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/integration/client-cli/pom.xml b/integration/client-cli/pom.xml
index e4bf08723c..1ffbf10e33 100644
--- a/integration/client-cli/pom.xml
+++ b/integration/client-cli/pom.xml
@@ -20,7 +20,7 @@
keycloak-integration-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Client CLI
diff --git a/integration/client-registration/pom.xml b/integration/client-registration/pom.xml
index 979b329211..c8d2d222a8 100755
--- a/integration/client-registration/pom.xml
+++ b/integration/client-registration/pom.xml
@@ -21,7 +21,7 @@
keycloak-integration-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
4.0.0
diff --git a/integration/pom.xml b/integration/pom.xml
index 11266cd9f8..2c829800dd 100755
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -20,7 +20,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../pom.xml
Keycloak Integration
diff --git a/misc/Testsuite.md b/misc/Testsuite.md
index cb77ad7a59..7f5e036d62 100644
--- a/misc/Testsuite.md
+++ b/misc/Testsuite.md
@@ -29,6 +29,15 @@ When starting the server it can also import a realm from a json file:
mvn exec:java -Pkeycloak-server -Dimport=testrealm.json
+When starting the server, https transport can be set up by setting keystore containing the server certificate
+and https port, optionally setting the truststore.
+
+ mvn exec:java -Pkeycloak-server \
+ -Djavax.net.ssl.trustStore=/path/to/truststore.jks \
+ -Djavax.net.ssl.keyStore=/path/to/keystore.jks \
+ -Djavax.net.ssl.keyStorePassword=CHANGEME \
+ -Dkeycloak.port.https=8443
+
### Live edit of html and styles
The Keycloak test server can load resources directly from the filesystem instead of the classpath. This allows editing html, styles and updating images without restarting the server. To make the server use resources from the filesystem start with:
diff --git a/misc/keycloak-test-helper/pom.xml b/misc/keycloak-test-helper/pom.xml
index 5a9983c092..8747ec19d9 100644
--- a/misc/keycloak-test-helper/pom.xml
+++ b/misc/keycloak-test-helper/pom.xml
@@ -6,7 +6,7 @@
keycloak-misc-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-test-helper
diff --git a/misc/pom.xml b/misc/pom.xml
index b9c3b588fc..d65bbe7b96 100644
--- a/misc/pom.xml
+++ b/misc/pom.xml
@@ -3,7 +3,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
Keycloak Misc
diff --git a/misc/spring-boot-starter/keycloak-spring-boot-starter/pom.xml b/misc/spring-boot-starter/keycloak-spring-boot-starter/pom.xml
index f48407f504..2f55a9ac55 100644
--- a/misc/spring-boot-starter/keycloak-spring-boot-starter/pom.xml
+++ b/misc/spring-boot-starter/keycloak-spring-boot-starter/pom.xml
@@ -4,7 +4,7 @@
org.keycloak
keycloak-spring-boot-starter-parent
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
keycloak-spring-boot-starter
Keycloak :: Spring :: Boot :: Default :: Starter
diff --git a/misc/spring-boot-starter/pom.xml b/misc/spring-boot-starter/pom.xml
index cbea8390fc..70f7daf336 100644
--- a/misc/spring-boot-starter/pom.xml
+++ b/misc/spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
keycloak-misc-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
org.keycloak
keycloak-spring-boot-starter-parent
@@ -20,7 +20,7 @@
org.keycloak.bom
keycloak-adapter-bom
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
pom
import
diff --git a/model/infinispan/pom.xml b/model/infinispan/pom.xml
index 8917daa415..7d7dfe1584 100755
--- a/model/infinispan/pom.xml
+++ b/model/infinispan/pom.xml
@@ -21,7 +21,7 @@
keycloak-parent
org.keycloak
- 3.2.0.CR1-SNAPSHOT
+ 3.3.0.CR1-SNAPSHOT
../../pom.xml
4.0.0
diff --git a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/CrossDCAwareCacheFactory.java b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/CrossDCAwareCacheFactory.java
index 17795ca213..65ca09d98e 100644
--- a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/CrossDCAwareCacheFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/CrossDCAwareCacheFactory.java
@@ -52,6 +52,12 @@ abstract class CrossDCAwareCacheFactory {
// For cross-DC scenario, we need to return underlying remoteCache for atomic operations to work properly
RemoteStore remoteStore = remoteStores.iterator().next();
RemoteCache remoteCache = remoteStore.getRemoteCache();
+
+ if (remoteCache == null) {
+ String cacheName = remoteStore.getConfiguration().remoteCacheName();
+ throw new IllegalStateException("Remote cache '" + cacheName + "' is not available.");
+ }
+
return new RemoteCacheWrapperFactory(remoteCache);
}
}
diff --git a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProvider.java b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProvider.java
index 5a4bdb744b..bd23e90133 100644
--- a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProvider.java
@@ -25,6 +25,11 @@ import org.keycloak.cluster.ExecutionResult;
import org.keycloak.common.util.Time;
import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
/**
@@ -43,11 +48,14 @@ public class InfinispanClusterProvider implements ClusterProvider {
private final CrossDCAwareCacheFactory crossDCAwareCacheFactory;
private final InfinispanNotificationsManager notificationsManager; // Just to extract notifications related stuff to separate class
- public InfinispanClusterProvider(int clusterStartupTime, String myAddress, CrossDCAwareCacheFactory crossDCAwareCacheFactory, InfinispanNotificationsManager notificationsManager) {
+ private final ExecutorService localExecutor;
+
+ public InfinispanClusterProvider(int clusterStartupTime, String myAddress, CrossDCAwareCacheFactory crossDCAwareCacheFactory, InfinispanNotificationsManager notificationsManager, ExecutorService localExecutor) {
this.myAddress = myAddress;
this.clusterStartupTime = clusterStartupTime;
this.crossDCAwareCacheFactory = crossDCAwareCacheFactory;
this.notificationsManager = notificationsManager;
+ this.localExecutor = localExecutor;
}
@@ -85,6 +93,34 @@ public class InfinispanClusterProvider implements ClusterProvider {
}
+ @Override
+ public Future executeIfNotExecutedAsync(String taskKey, int taskTimeoutInSeconds, Callable task) {
+ TaskCallback newCallback = new TaskCallback();
+ TaskCallback callback = this.notificationsManager.registerTaskCallback(TASK_KEY_PREFIX + taskKey, newCallback);
+
+ // We successfully submitted our task
+ if (newCallback == callback) {
+ Callable wrappedTask = () -> {
+ boolean executed = executeIfNotExecuted(taskKey, taskTimeoutInSeconds, task).isExecuted();
+
+ if (!executed) {
+ logger.infof("Task already in progress on other cluster node. Will wait until it's finished");
+ }
+
+ callback.getTaskCompletedLatch().await(taskTimeoutInSeconds, TimeUnit.SECONDS);
+ return callback.isSuccess();
+ };
+
+ Future future = localExecutor.submit(wrappedTask);
+ callback.setFuture(future);
+ } else {
+ logger.infof("Task already in progress on this cluster node. Will wait until it's finished");
+ }
+
+ return callback.getFuture();
+ }
+
+
@Override
public void registerListener(String taskKey, ClusterListener task) {
this.notificationsManager.registerListener(taskKey, task);
@@ -92,11 +128,10 @@ public class InfinispanClusterProvider implements ClusterProvider {
@Override
- public void notify(String taskKey, ClusterEvent event, boolean ignoreSender) {
- this.notificationsManager.notify(taskKey, event, ignoreSender);
+ public void notify(String taskKey, ClusterEvent event, boolean ignoreSender, DCNotify dcNotify) {
+ this.notificationsManager.notify(taskKey, event, ignoreSender, dcNotify);
}
-
private LockEntry createLockEntry() {
LockEntry lock = new LockEntry();
lock.setNode(myAddress);
diff --git a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java
index a96621d7b2..330de4fd62 100644
--- a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java
@@ -35,12 +35,15 @@ import org.keycloak.common.util.Time;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -62,17 +65,18 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
// Ensure that atomic operations (like putIfAbsent) must work correctly in any of: non-clustered, clustered or cross-Data-Center (cross-DC) setups
private CrossDCAwareCacheFactory crossDCAwareCacheFactory;
- private String myAddress;
-
private int clusterStartupTime;
// Just to extract notifications related stuff to separate class
private InfinispanNotificationsManager notificationsManager;
+ private ExecutorService localExecutor = Executors.newCachedThreadPool();
+
@Override
public ClusterProvider create(KeycloakSession session) {
lazyInit(session);
- return new InfinispanClusterProvider(clusterStartupTime, myAddress, crossDCAwareCacheFactory, notificationsManager);
+ String myAddress = InfinispanUtil.getMyAddress(session);
+ return new InfinispanClusterProvider(clusterStartupTime, myAddress, crossDCAwareCacheFactory, notificationsManager, localExecutor);
}
private void lazyInit(KeycloakSession session) {
@@ -83,33 +87,23 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
workCache = ispnConnections.getCache(InfinispanConnectionProvider.WORK_CACHE_NAME);
workCache.getCacheManager().addListener(new ViewChangeListener());
- initMyAddress();
- Set remoteStores = getRemoteStores();
+ // See if we have RemoteStore (external JDG) configured for cross-Data-Center scenario
+ Set remoteStores = InfinispanUtil.getRemoteStores(workCache);
crossDCAwareCacheFactory = CrossDCAwareCacheFactory.getFactory(workCache, remoteStores);
clusterStartupTime = initClusterStartupTime(session);
- notificationsManager = InfinispanNotificationsManager.create(workCache, myAddress, remoteStores);
+ String myAddress = InfinispanUtil.getMyAddress(session);
+ String mySite = InfinispanUtil.getMySite(session);
+
+ notificationsManager = InfinispanNotificationsManager.create(workCache, myAddress, mySite, remoteStores);
}
}
}
}
- // See if we have RemoteStore (external JDG) configured for cross-Data-Center scenario
- private Set getRemoteStores() {
- return workCache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(RemoteStore.class);
- }
-
-
- protected void initMyAddress() {
- Transport transport = workCache.getCacheManager().getTransport();
- this.myAddress = transport == null ? HostUtils.getHostName() + "-" + workCache.hashCode() : transport.getAddress().toString();
- logger.debugf("My address: %s", this.myAddress);
- }
-
-
protected int initClusterStartupTime(KeycloakSession session) {
Integer existingClusterStartTime = (Integer) crossDCAwareCacheFactory.getCache().get(InfinispanClusterProvider.CLUSTER_STARTUP_TIME_KEY);
if (existingClusterStartTime != null) {
@@ -201,6 +195,10 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
if (logger.isTraceEnabled()) {
logger.tracef("Removing task %s due it's node left cluster", rem);
}
+
+ // If we have task in progress, it needs to be notified
+ notificationsManager.taskFinished(rem, false);
+
cache.remove(rem);
}
}
diff --git a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanNotificationsManager.java b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanNotificationsManager.java
index fa73420ebb..0c5e6e92bc 100644
--- a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanNotificationsManager.java
+++ b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanNotificationsManager.java
@@ -20,32 +20,35 @@ package org.keycloak.cluster.infinispan;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.infinispan.Cache;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.annotation.ClientCacheEntryCreated;
import org.infinispan.client.hotrod.annotation.ClientCacheEntryModified;
+import org.infinispan.client.hotrod.annotation.ClientCacheEntryRemoved;
import org.infinispan.client.hotrod.annotation.ClientListener;
import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent;
import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent;
-import org.infinispan.client.hotrod.event.ClientEvent;
+import org.infinispan.client.hotrod.event.ClientCacheEntryRemovedEvent;
import org.infinispan.context.Flag;
-import org.infinispan.marshall.core.MarshalledEntry;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
-import org.infinispan.persistence.manager.PersistenceManager;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
import org.infinispan.persistence.remote.RemoteStore;
-import org.infinispan.remoting.transport.Transport;
import org.jboss.logging.Logger;
import org.keycloak.cluster.ClusterEvent;
import org.keycloak.cluster.ClusterListener;
import org.keycloak.cluster.ClusterProvider;
-import org.keycloak.common.util.HostUtils;
-import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.common.util.ConcurrentMultivaluedHashMap;
+import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
/**
* Impl for sending infinispan messages across cluster and listening to them
@@ -56,37 +59,52 @@ public class InfinispanNotificationsManager {
protected static final Logger logger = Logger.getLogger(InfinispanNotificationsManager.class);
- private final MultivaluedHashMap listeners = new MultivaluedHashMap<>();
+ private final ConcurrentMultivaluedHashMap listeners = new ConcurrentMultivaluedHashMap<>();
+
+ private final ConcurrentMap taskCallbacks = new ConcurrentHashMap<>();
private final Cache workCache;
+ private final RemoteCache workRemoteCache;
+
private final String myAddress;
+ private final String mySite;
- protected InfinispanNotificationsManager(Cache workCache, String myAddress) {
+
+ protected InfinispanNotificationsManager(Cache workCache, RemoteCache workRemoteCache, String myAddress, String mySite) {
this.workCache = workCache;
+ this.workRemoteCache = workRemoteCache;
this.myAddress = myAddress;
+ this.mySite = mySite;
}
// Create and init manager including all listeners etc
- public static InfinispanNotificationsManager create(Cache workCache, String myAddress, Set remoteStores) {
- InfinispanNotificationsManager manager = new InfinispanNotificationsManager(workCache, myAddress);
+ public static InfinispanNotificationsManager create(Cache workCache, String myAddress, String mySite, Set remoteStores) {
+ RemoteCache workRemoteCache = null;
- // We need CacheEntryListener just if we don't have remoteStore. With remoteStore will be all cluster nodes notified anyway from HotRod listener
- if (remoteStores.isEmpty()) {
- workCache.addListener(manager.new CacheEntryListener());
+ if (!remoteStores.isEmpty()) {
+ RemoteStore remoteStore = remoteStores.iterator().next();
+ workRemoteCache = remoteStore.getRemoteCache();
- logger.debugf("Added listener for infinispan cache: %s", workCache.getName());
- } else {
- for (RemoteStore remoteStore : remoteStores) {
- RemoteCache