Compare commits
212
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
118d3db203 | ||
|
|
b371521b33 | ||
|
|
f151933d91 | ||
|
|
5ea93822e7 | ||
|
|
cafd2d80d2 | ||
|
|
c9dcd7973a | ||
|
|
c17b70e454 | ||
|
|
1199fa7f6d | ||
|
|
4928f779f7 | ||
|
|
8371c256b2 | ||
|
|
fa0335613f | ||
|
|
dc1d0e7f44 | ||
|
|
229eca302f | ||
|
|
446c9fea4b | ||
|
|
1d882cdb87 | ||
|
|
bdc5f1c185 | ||
|
|
7b578b8c87 | ||
|
|
37f605de5b | ||
|
|
8d21cfc234 | ||
|
|
df56265976 | ||
|
|
7be0b1c9f5 | ||
|
|
52f3693747 | ||
|
|
392b1f1e17 | ||
|
|
ebb61c104b | ||
|
|
6fe3a3da71 | ||
|
|
f597f163f7 | ||
|
|
1ac0529d04 | ||
|
|
3c60881d8c | ||
|
|
74ac00349e | ||
|
|
048c64b6bd | ||
|
|
5917d5885b | ||
|
|
8da768a514 | ||
|
|
ad63b18781 | ||
|
|
95d5ce9dd4 | ||
|
|
56c3d53a24 | ||
|
|
c91255f620 | ||
|
|
4f047565fb | ||
|
|
f65a053182 | ||
|
|
b709ca96b1 | ||
|
|
4a027d97b0 | ||
|
|
4be6dc2f0c | ||
|
|
57b6ddbace | ||
|
|
bf38ec040f | ||
|
|
2c79456e72 | ||
|
|
8caad0118c | ||
|
|
afdbdb285d | ||
|
|
ad2638cc20 | ||
|
|
05c590ac88 | ||
|
|
8d6f71e7d1 | ||
|
|
10e1b6206f | ||
|
|
002074bb30 | ||
|
|
375d4e9e83 | ||
|
|
286de3e905 | ||
|
|
a258dd51ee | ||
|
|
b4239c40c1 | ||
|
|
b6118a6705 | ||
|
|
2bf3531c43 | ||
|
|
2d42ad9993 | ||
|
|
2edb7f6831 | ||
|
|
402feb9710 | ||
|
|
13506bec82 | ||
|
|
13b6c6f507 | ||
|
|
7b8869bde6 | ||
|
|
e4815cd103 | ||
|
|
4214793a2d | ||
|
|
860b58552e | ||
|
|
a13bac4c9d | ||
|
|
c6fc7622d2 | ||
|
|
c584a1a161 | ||
|
|
b8c50c431c | ||
|
|
cc776abacb | ||
|
|
fea5d5099d | ||
|
|
95e1dedb32 | ||
|
|
370b86141c | ||
|
|
45b940ad2d | ||
|
|
8c3545d219 | ||
|
|
2f3a1626d7 | ||
|
|
5d93f4a298 | ||
|
|
66a75d93ee | ||
|
|
e107a403cf | ||
|
|
8270c0a19a | ||
|
|
db5efdca64 | ||
|
|
5eb319f3c5 | ||
|
|
6baa4a7950 | ||
|
|
73b6751219 | ||
|
|
c0de43d51f | ||
|
|
5d9966f6df | ||
|
|
893fb2a55b | ||
|
|
4add134dff | ||
|
|
7dc228beca | ||
|
|
e6e367392a | ||
|
|
0768bcc452 | ||
|
|
4f8669d668 | ||
|
|
c65ed96bd7 | ||
|
|
7ad8a6e074 | ||
|
|
2bddd9ad34 | ||
|
|
ff9ebb0f79 | ||
|
|
09133a9e2a | ||
|
|
32d15e2027 | ||
|
|
8aa0727d88 | ||
|
|
c0d0c1f39a | ||
|
|
64daa568b9 | ||
|
|
47652ae179 | ||
|
|
e2558ca827 | ||
|
|
5fb7e8186f | ||
|
|
e66060b00b | ||
|
|
84de9cca8e | ||
|
|
37584a24e0 | ||
|
|
cfc61fa262 | ||
|
|
4286f0560f | ||
|
|
116d147bf7 | ||
|
|
a71adde8fa | ||
|
|
45a03a654f | ||
|
|
2154dd120b | ||
|
|
2a4dfe7920 | ||
|
|
5556736968 | ||
|
|
24336bcd4d | ||
|
|
6fae1c6411 | ||
|
|
d7641f8830 | ||
|
|
24328fdc47 | ||
|
|
4f46ab45cc | ||
|
|
ccfae82b77 | ||
|
|
711e6a54ca | ||
|
|
1d8f3d8702 | ||
|
|
a0696fcb97 | ||
|
|
abddbfb3a4 | ||
|
|
a97c4bdff9 | ||
|
|
e7a5b88b2d | ||
|
|
4f0609f8b2 | ||
|
|
e4d056f54b | ||
|
|
a3f7339fca | ||
|
|
57cd7e132c | ||
|
|
d766c56eba | ||
|
|
0fa2b5c25d | ||
|
|
072fe0d8a0 | ||
|
|
2ec355e2d2 | ||
|
|
94b3e85513 | ||
|
|
4abcb2761f | ||
|
|
aae550a7c7 | ||
|
|
7f32ce810a | ||
|
|
13acd512b6 | ||
|
|
b94ced2204 | ||
|
|
c59123e974 | ||
|
|
ff2c100664 | ||
|
|
41949b63f6 | ||
|
|
aea35454bf | ||
|
|
25d183c1d9 | ||
|
|
3b8364f1e6 | ||
|
|
ca81f3f18d | ||
|
|
6df72d67c5 | ||
|
|
f6c7ecf8e3 | ||
|
|
d723efae77 | ||
|
|
b7f4d52de1 | ||
|
|
3ca39801dc | ||
|
|
da8f2dc2ce | ||
|
|
2fce06ffca | ||
|
|
14ea988b24 | ||
|
|
5723baa367 | ||
|
|
450ce0e0e0 | ||
|
|
17ea3fca0b | ||
|
|
f10f00ba71 | ||
|
|
8c73f8743d | ||
|
|
ab96114ef8 | ||
|
|
c45e40db99 | ||
|
|
9488787986 | ||
|
|
64b2aed370 | ||
|
|
f63bb66170 | ||
|
|
1957103270 | ||
|
|
3383b044b2 | ||
|
|
f34260478e | ||
|
|
4cf26a68fc | ||
|
|
2c16335a03 | ||
|
|
af26b5b610 | ||
|
|
eacd689f91 | ||
|
|
023b558f43 | ||
|
|
8601b321d5 | ||
|
|
83181f28b2 | ||
|
|
77c16c320e | ||
|
|
a6458250bc | ||
|
|
6654a154b9 | ||
|
|
4d82cc92fe | ||
|
|
3e1976b3e5 | ||
|
|
695f8d34ab | ||
|
|
ad753a50a3 | ||
|
|
0fc9cb78d5 | ||
|
|
ec9c9b8ee1 | ||
|
|
5ac3443729 | ||
|
|
fac8c4a6d0 | ||
|
|
d7f4277ba8 | ||
|
|
a1d9753ec2 | ||
|
|
599faa454b | ||
|
|
4dcdaf4985 | ||
|
|
03215787e0 | ||
|
|
838764ba5a | ||
|
|
4fd97091ff | ||
|
|
daa09f9a41 | ||
|
|
1511f7088f | ||
|
|
2e64d01251 | ||
|
|
c45524d8d4 | ||
|
|
d3769caaac | ||
|
|
3a138db842 | ||
|
|
b41dd22ed3 | ||
|
|
c34aa5763d | ||
|
|
02851989b3 | ||
|
|
9bde0af0f1 | ||
|
|
8006c64dba | ||
|
|
4b5fee02cc | ||
|
|
1569cf7fb5 | ||
|
|
5a0711655a | ||
|
|
b5660cbbab | ||
|
|
ec2cfba670 | ||
|
|
97d0f39346 |
No files matched your search
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ public class OAuthRequestAuthenticator {
|
||||
tokenStore.saveRequest();
|
||||
log.debug("Sending redirect to login page: " + redirect);
|
||||
exchange.getResponse().setStatus(302);
|
||||
exchange.getResponse().setCookie(deployment.getStateCookieName(), state, /* need to set path? */ null, null, -1, deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr()), false);
|
||||
exchange.getResponse().setCookie(deployment.getStateCookieName(), state, /* need to set path? */ null, null, -1, deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr()), true);
|
||||
exchange.getResponse().setHeader("Location", redirect);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-as7-integration-pom</artifactId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+36
@@ -18,6 +18,8 @@
|
||||
package org.keycloak.adapters.jetty.core;
|
||||
|
||||
import org.eclipse.jetty.security.DefaultUserIdentity;
|
||||
import org.eclipse.jetty.security.IdentityService;
|
||||
import org.eclipse.jetty.security.LoginService;
|
||||
import org.eclipse.jetty.security.ServerAuthException;
|
||||
import org.eclipse.jetty.security.UserAuthentication;
|
||||
import org.eclipse.jetty.security.authentication.DeferredAuthentication;
|
||||
@@ -135,10 +137,44 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
|
||||
return new DefaultUserIdentity(theSubject, principal, theRoles);
|
||||
}
|
||||
|
||||
private class DummyLoginService implements LoginService {
|
||||
@Override
|
||||
public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserIdentity login(String username, Object credentials) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(UserIdentity user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityService getIdentityService() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentityService(IdentityService service) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(UserIdentity user) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(AuthConfiguration configuration) {
|
||||
//super.setConfiguration(configuration);
|
||||
initializeKeycloak();
|
||||
// need this so that getUserPrincipal does not throw NPE
|
||||
_loginService = new DummyLoginService();
|
||||
String error = configuration.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE);
|
||||
setErrorPage(error);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Jetty Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -878,31 +878,28 @@
|
||||
var loginUrl = kc.createLoginUrl(options);
|
||||
var ref = window.open(loginUrl, '_blank', o);
|
||||
|
||||
var callback;
|
||||
var error;
|
||||
var completed = false;
|
||||
|
||||
ref.addEventListener('loadstart', function(event) {
|
||||
if (event.url.indexOf('http://localhost') == 0) {
|
||||
callback = parseCallback(event.url);
|
||||
var callback = parseCallback(event.url);
|
||||
processCallback(callback, promise);
|
||||
ref.close();
|
||||
completed = true;
|
||||
}
|
||||
});
|
||||
|
||||
ref.addEventListener('loaderror', function(event) {
|
||||
if (event.url.indexOf('http://localhost') == 0) {
|
||||
callback = parseCallback(event.url);
|
||||
ref.close();
|
||||
} else {
|
||||
error = true;
|
||||
ref.close();
|
||||
}
|
||||
});
|
||||
|
||||
ref.addEventListener('exit', function(event) {
|
||||
if (error || !callback) {
|
||||
promise.setError();
|
||||
} else {
|
||||
processCallback(callback, promise);
|
||||
if (!completed) {
|
||||
if (event.url.indexOf('http://localhost') == 0) {
|
||||
var callback = parseCallback(event.url);
|
||||
processCallback(callback, promise);
|
||||
ref.close();
|
||||
completed = true;
|
||||
} else {
|
||||
promise.setError();
|
||||
ref.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OIDC Client Adapter Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+2
@@ -89,6 +89,7 @@ public class OIDCFilterSessionStore extends FilterSessionStore implements Adapte
|
||||
|
||||
protected void cleanSession(HttpSession session) {
|
||||
session.removeAttribute(KeycloakAccount.class.getName());
|
||||
session.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
clearSavedRequest(session);
|
||||
}
|
||||
|
||||
@@ -160,6 +161,7 @@ public class OIDCFilterSessionStore extends FilterSessionStore implements Adapte
|
||||
SerializableKeycloakAccount sAccount = new SerializableKeycloakAccount(roles, account.getPrincipal(), securityContext);
|
||||
HttpSession httpSession = request.getSession();
|
||||
httpSession.setAttribute(KeycloakAccount.class.getName(), sAccount);
|
||||
httpSession.setAttribute(KeycloakSecurityContext.class.getName(), sAccount.getKeycloakSecurityContext());
|
||||
if (idMapper != null) idMapper.map(account.getKeycloakSecurityContext().getToken().getClientSession(), account.getPrincipal().getName(), httpSession.getId());
|
||||
//String username = securityContext.getToken().getSubject();
|
||||
//log.fine("userSessionManagement.login: " + username);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Tomcat Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+15
-2
@@ -69,12 +69,22 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
|
||||
// just in case session got serialized
|
||||
if (session.getDeployment() == null) session.setCurrentRequestInfo(deployment, this);
|
||||
|
||||
if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) return;
|
||||
if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) {
|
||||
request.setAttribute(KeycloakSecurityContext.class.getName(), session);
|
||||
request.setUserPrincipal(account.getPrincipal());
|
||||
request.setAuthType("KEYCLOAK");
|
||||
return;
|
||||
}
|
||||
|
||||
// FYI: A refresh requires same scope, so same roles will be set. Otherwise, refresh will fail and token will
|
||||
// not be updated
|
||||
boolean success = session.refreshExpiredToken(false);
|
||||
if (success && session.isActive()) return;
|
||||
if (success && session.isActive()) {
|
||||
request.setAttribute(KeycloakSecurityContext.class.getName(), session);
|
||||
request.setUserPrincipal(account.getPrincipal());
|
||||
request.setAuthType("KEYCLOAK");
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh failed, so user is already logged out from keycloak. Cleanup and expire our session
|
||||
log.fine("Cleanup and expire session " + catalinaSession.getId() + " after failed refresh");
|
||||
@@ -85,6 +95,8 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
|
||||
}
|
||||
|
||||
protected void cleanSession(Session catalinaSession) {
|
||||
catalinaSession.getSession().removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
catalinaSession.getSession().removeAttribute(SerializableKeycloakAccount.class.getName());
|
||||
catalinaSession.getSession().removeAttribute(OidcKeycloakAccount.class.getName());
|
||||
catalinaSession.setPrincipal(null);
|
||||
catalinaSession.setAuthType(null);
|
||||
@@ -164,6 +176,7 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
|
||||
session.setPrincipal(principal);
|
||||
session.setAuthType("KEYCLOAK");
|
||||
session.getSession().setAttribute(SerializableKeycloakAccount.class.getName(), sAccount);
|
||||
session.getSession().setAttribute(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext());
|
||||
String username = securityContext.getToken().getSubject();
|
||||
log.fine("userSessionManagement.login: " + username);
|
||||
this.sessionManagement.login(session);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+3
-1
@@ -92,7 +92,8 @@ public class ServletSessionTokenStore implements AdapterTokenStore {
|
||||
} else {
|
||||
log.debug("Refresh failed. Account was not active. Returning null and invalidating Http session");
|
||||
try {
|
||||
session.setAttribute(KeycloakUndertowAccount.class.getName(), null);
|
||||
session.removeAttribute(KeycloakUndertowAccount.class.getName());
|
||||
session.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
session.invalidate();
|
||||
} catch (Exception e) {
|
||||
log.debug("Failed to invalidate session, might already be invalidated");
|
||||
@@ -106,6 +107,7 @@ public class ServletSessionTokenStore implements AdapterTokenStore {
|
||||
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
|
||||
HttpSession session = getSession(true);
|
||||
session.setAttribute(KeycloakUndertowAccount.class.getName(), account);
|
||||
session.setAttribute(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext());
|
||||
sessionManagement.login(servletRequestContext.getDeployment().getSessionManager());
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -22,6 +22,7 @@ import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.server.session.Session;
|
||||
import io.undertow.util.Sessions;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.OidcKeycloakAccount;
|
||||
@@ -82,6 +83,7 @@ public class UndertowSessionTokenStore implements AdapterTokenStore {
|
||||
} else {
|
||||
log.debug("Account was not active, returning false");
|
||||
session.removeAttribute(KeycloakUndertowAccount.class.getName());
|
||||
session.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
session.invalidate(exchange);
|
||||
return false;
|
||||
}
|
||||
@@ -101,6 +103,7 @@ public class UndertowSessionTokenStore implements AdapterTokenStore {
|
||||
public void saveAccountInfo(OidcKeycloakAccount account) {
|
||||
Session session = Sessions.getOrCreateSession(exchange);
|
||||
session.setAttribute(KeycloakUndertowAccount.class.getName(), account);
|
||||
session.setAttribute(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext());
|
||||
sessionManagement.login(session.getSessionManager());
|
||||
}
|
||||
|
||||
@@ -111,6 +114,7 @@ public class UndertowSessionTokenStore implements AdapterTokenStore {
|
||||
KeycloakUndertowAccount account = (KeycloakUndertowAccount)session.getAttribute(KeycloakUndertowAccount.class.getName());
|
||||
if (account == null) return;
|
||||
session.removeAttribute(KeycloakUndertowAccount.class.getName());
|
||||
session.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak WildFly Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML EAP Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+36
@@ -18,6 +18,8 @@
|
||||
package org.keycloak.adapters.saml.jetty;
|
||||
|
||||
import org.eclipse.jetty.security.DefaultUserIdentity;
|
||||
import org.eclipse.jetty.security.IdentityService;
|
||||
import org.eclipse.jetty.security.LoginService;
|
||||
import org.eclipse.jetty.security.ServerAuthException;
|
||||
import org.eclipse.jetty.security.UserAuthentication;
|
||||
import org.eclipse.jetty.security.authentication.DeferredAuthentication;
|
||||
@@ -135,12 +137,46 @@ public abstract class AbstractSamlAuthenticator extends LoginAuthenticator {
|
||||
|
||||
}
|
||||
|
||||
private class DummyLoginService implements LoginService {
|
||||
@Override
|
||||
public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserIdentity login(String username, Object credentials) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(UserIdentity user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityService getIdentityService() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentityService(IdentityService service) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(UserIdentity user) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setConfiguration(AuthConfiguration configuration) {
|
||||
//super.setConfiguration(configuration);
|
||||
initializeKeycloak();
|
||||
// need this so that getUserPrincipal does not throw NPE
|
||||
_loginService = new DummyLoginService();
|
||||
String error = configuration.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE);
|
||||
setErrorPage(error);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Jetty Integration</name>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Client Adapter Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Tomcat Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+3
-2
@@ -167,9 +167,9 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
|
||||
@Override
|
||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||
log.fine("*********************** SAML ************");
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(response, request);
|
||||
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||
if (request.getRequestURI().substring(request.getContextPath().length()).endsWith("/saml")) {
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(response, request);
|
||||
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||
if (deployment != null && deployment.isConfigured()) {
|
||||
SamlSessionStore tokenStore = getSessionStore(request, facade, deployment);
|
||||
SamlAuthenticator authenticator = new CatalinaSamlEndpoint(facade, deployment, tokenStore);
|
||||
@@ -180,6 +180,7 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
|
||||
}
|
||||
|
||||
try {
|
||||
getSessionStore(request, facade, deployment).isLoggedIn(); // sets request UserPrincipal if logged in. we do this so that the UserPrincipal is available on unsecured, unconstrainted URLs
|
||||
super.invoke(request, response);
|
||||
} finally {
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak SAML Wildfly Integration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak Client Adapter SPI Modules</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
package org.keycloak.common.constants;
|
||||
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.Oid;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@@ -31,19 +34,33 @@ public class KerberosConstants {
|
||||
/**
|
||||
* OID of SPNEGO mechanism. See http://www.oid-info.com/get/1.3.6.1.5.5.2
|
||||
*/
|
||||
public static final String SPNEGO_OID = "1.3.6.1.5.5.2";
|
||||
private static final String SPNEGO_OID_STR = "1.3.6.1.5.5.2";
|
||||
public static final Oid SPNEGO_OID;
|
||||
|
||||
|
||||
/**
|
||||
* OID of Kerberos v5 mechanism. See http://www.oid-info.com/get/1.2.840.113554.1.2.2
|
||||
*/
|
||||
public static final String KRB5_OID = "1.2.840.113554.1.2.2";
|
||||
private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
|
||||
public static final Oid KRB5_OID;
|
||||
|
||||
|
||||
/**
|
||||
* OID of Kerberos v5 name. See http://www.oid-info.com/get/1.2.840.113554.1.2.2.1
|
||||
*/
|
||||
public static final String KRB5_NAME_OID = "1.2.840.113554.1.2.2.1";
|
||||
private static final String KRB5_NAME_OID_STR = "1.2.840.113554.1.2.2.1";
|
||||
public static final Oid KRB5_NAME_OID;
|
||||
|
||||
|
||||
static {
|
||||
try {
|
||||
KRB5_OID = new Oid(KerberosConstants.KRB5_OID_STR);
|
||||
KRB5_NAME_OID = new Oid(KerberosConstants.KRB5_NAME_OID_STR);
|
||||
SPNEGO_OID = new Oid(KerberosConstants.SPNEGO_OID_STR);
|
||||
} catch (GSSException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.common.util;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class Environment {
|
||||
|
||||
public static final boolean IS_IBM_JAVA = System.getProperty("java.vendor").contains("IBM");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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.common.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import javax.security.auth.login.AppConfigurationEntry;
|
||||
import javax.security.auth.login.Configuration;
|
||||
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.GSSName;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
|
||||
/**
|
||||
* Provides abstraction to handle differences between various JDK vendors (Sun, IBM)
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public abstract class KerberosJdkProvider {
|
||||
|
||||
public abstract Configuration createJaasConfigurationForServer(String keytab, String serverPrincipal, boolean debug);
|
||||
public abstract Configuration createJaasConfigurationForUsernamePasswordLogin(boolean debug);
|
||||
|
||||
public abstract KerberosTicket gssCredentialToKerberosTicket(KerberosTicket kerberosTicket, GSSCredential gssCredential);
|
||||
|
||||
|
||||
|
||||
public GSSCredential kerberosTicketToGSSCredential(KerberosTicket kerberosTicket) {
|
||||
return kerberosTicketToGSSCredential(kerberosTicket, GSSCredential.DEFAULT_LIFETIME, GSSCredential.INITIATE_ONLY);
|
||||
}
|
||||
|
||||
// Actually can use same on both JDKs
|
||||
public GSSCredential kerberosTicketToGSSCredential(KerberosTicket kerberosTicket, final int lifetime, final int usage) {
|
||||
try {
|
||||
final GSSManager gssManager = GSSManager.getInstance();
|
||||
|
||||
KerberosPrincipal kerberosPrincipal = kerberosTicket.getClient();
|
||||
String krbPrincipalName = kerberosTicket.getClient().getName();
|
||||
final GSSName gssName = gssManager.createName(krbPrincipalName, KerberosConstants.KRB5_NAME_OID);
|
||||
|
||||
Set<KerberosPrincipal> principals = Collections.singleton(kerberosPrincipal);
|
||||
Set<GSSName> publicCreds = Collections.singleton(gssName);
|
||||
Set<KerberosTicket> privateCreds = Collections.singleton(kerberosTicket);
|
||||
Subject subject = new Subject(false, principals, publicCreds, privateCreds);
|
||||
|
||||
return Subject.doAs(subject, new PrivilegedExceptionAction<GSSCredential>() {
|
||||
|
||||
@Override
|
||||
public GSSCredential run() throws Exception {
|
||||
return gssManager.createCredential(gssName, lifetime, KerberosConstants.KRB5_OID, usage);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new KerberosSerializationUtils.KerberosSerializationException("Unexpected exception during convert KerberosTicket to GSSCredential", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static KerberosJdkProvider getProvider() {
|
||||
if (Environment.IS_IBM_JAVA) {
|
||||
return new IBMJDKProvider();
|
||||
} else {
|
||||
return new SunJDKProvider();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// IMPL Subclasses
|
||||
|
||||
|
||||
// Works for Oracle and OpenJDK
|
||||
private static class SunJDKProvider extends KerberosJdkProvider {
|
||||
|
||||
|
||||
@Override
|
||||
public Configuration createJaasConfigurationForServer(final String keytab, final String serverPrincipal, final boolean debug) {
|
||||
return new Configuration() {
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("storeKey", "true");
|
||||
options.put("doNotPrompt", "true");
|
||||
options.put("isInitiator", "false");
|
||||
options.put("useKeyTab", "true");
|
||||
|
||||
options.put("keyTab", keytab);
|
||||
options.put("principal", serverPrincipal);
|
||||
options.put("debug", String.valueOf(debug));
|
||||
AppConfigurationEntry kerberosLMConfiguration = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
|
||||
return new AppConfigurationEntry[] { kerberosLMConfiguration };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Configuration createJaasConfigurationForUsernamePasswordLogin(final boolean debug) {
|
||||
return new Configuration() {
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("storeKey", "true");
|
||||
options.put("debug", String.valueOf(debug));
|
||||
AppConfigurationEntry kerberosLMConfiguration = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
|
||||
return new AppConfigurationEntry[] { kerberosLMConfiguration };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Note: input kerberosTicket is null for Sun based JDKs
|
||||
@Override
|
||||
public KerberosTicket gssCredentialToKerberosTicket(KerberosTicket kerberosTicket, GSSCredential gssCredential) {
|
||||
try {
|
||||
Class<?> gssUtil = Class.forName("com.sun.security.jgss.GSSUtil");
|
||||
Method createSubject = gssUtil.getMethod("createSubject", GSSName.class, GSSCredential.class);
|
||||
Subject subject = (Subject) createSubject.invoke(null, null, gssCredential);
|
||||
Set<KerberosTicket> kerberosTickets = subject.getPrivateCredentials(KerberosTicket.class);
|
||||
Iterator<KerberosTicket> iterator = kerberosTickets.iterator();
|
||||
if (iterator.hasNext()) {
|
||||
return iterator.next();
|
||||
} else {
|
||||
throw new KerberosSerializationUtils.KerberosSerializationException("Not available kerberosTicket in subject credentials. Subject was: " + subject.toString());
|
||||
}
|
||||
} catch (KerberosSerializationUtils.KerberosSerializationException ke) {
|
||||
throw ke;
|
||||
} catch (Exception e) {
|
||||
throw new KerberosSerializationUtils.KerberosSerializationException("Unexpected error during convert GSSCredential to KerberosTicket", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Works for IBM JDK
|
||||
private static class IBMJDKProvider extends KerberosJdkProvider {
|
||||
|
||||
@Override
|
||||
public Configuration createJaasConfigurationForServer(String keytab, final String serverPrincipal, final boolean debug) {
|
||||
final String keytabUrl = getKeytabURL(keytab);
|
||||
|
||||
return new Configuration() {
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("noAddress", "true");
|
||||
options.put("credsType","acceptor");
|
||||
options.put("useKeytab", keytabUrl);
|
||||
options.put("principal", serverPrincipal);
|
||||
options.put("debug", String.valueOf(debug));
|
||||
|
||||
AppConfigurationEntry kerberosLMConfiguration = new AppConfigurationEntry("com.ibm.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
|
||||
return new AppConfigurationEntry[] { kerberosLMConfiguration };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String getKeytabURL(String keytab) {
|
||||
try {
|
||||
return new File(keytab).toURI().toURL().toString();
|
||||
} catch (MalformedURLException mfe) {
|
||||
System.err.println("Invalid keytab location specified in configuration: " + keytab);
|
||||
mfe.printStackTrace();
|
||||
return keytab;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Configuration createJaasConfigurationForUsernamePasswordLogin(final boolean debug) {
|
||||
return new Configuration() {
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("credsType","initiator");
|
||||
options.put("noAddress", "true");
|
||||
options.put("debug", String.valueOf(debug));
|
||||
AppConfigurationEntry kerberosLMConfiguration = new AppConfigurationEntry("com.ibm.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
|
||||
return new AppConfigurationEntry[] { kerberosLMConfiguration };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// For IBM, kerberosTicket was set on JAAS Subject, so we can just return it
|
||||
@Override
|
||||
public KerberosTicket gssCredentialToKerberosTicket(KerberosTicket kerberosTicket, GSSCredential gssCredential) {
|
||||
if (kerberosTicket == null) {
|
||||
throw new KerberosSerializationUtils.KerberosSerializationException("Not available kerberosTicket in subject credentials in IBM JDK");
|
||||
} else {
|
||||
return kerberosTicket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,22 +25,13 @@ import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.Oid;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.common.util.reflections.Reflections;
|
||||
import sun.security.jgss.GSSCredentialImpl;
|
||||
import sun.security.jgss.GSSManagerImpl;
|
||||
import sun.security.jgss.krb5.Krb5InitCredential;
|
||||
import sun.security.jgss.krb5.Krb5NameElement;
|
||||
import sun.security.jgss.spi.GSSCredentialSpi;
|
||||
import sun.security.krb5.Credentials;
|
||||
|
||||
/**
|
||||
* Provides serialization/deserialization of kerberos {@link org.ietf.jgss.GSSCredential}, so it can be transmitted from auth-server to the application
|
||||
@@ -50,18 +41,9 @@ import sun.security.krb5.Credentials;
|
||||
*/
|
||||
public class KerberosSerializationUtils {
|
||||
|
||||
public static final Oid KRB5_OID;
|
||||
public static final Oid KRB5_NAME_OID;
|
||||
public static final String JAVA_INFO;
|
||||
|
||||
static {
|
||||
try {
|
||||
KRB5_OID = new Oid(KerberosConstants.KRB5_OID);
|
||||
KRB5_NAME_OID = new Oid(KerberosConstants.KRB5_NAME_OID);
|
||||
} catch (GSSException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String javaRuntimeVersion = System.getProperty("java.runtime.version");
|
||||
String javaVendor = System.getProperty("java.vendor");
|
||||
@@ -72,50 +54,17 @@ public class KerberosSerializationUtils {
|
||||
private KerberosSerializationUtils() {
|
||||
}
|
||||
|
||||
public static String serializeCredential(GSSCredential gssCredential) throws KerberosSerializationException {
|
||||
public static String serializeCredential(KerberosTicket kerberosTicket, GSSCredential gssCredential) throws KerberosSerializationException {
|
||||
try {
|
||||
if (gssCredential == null) {
|
||||
throw new KerberosSerializationException("Null credential given as input");
|
||||
}
|
||||
|
||||
if (!(gssCredential instanceof GSSCredentialImpl)) {
|
||||
throw new KerberosSerializationException("Unknown credential type: " + gssCredential.getClass());
|
||||
}
|
||||
kerberosTicket = KerberosJdkProvider.getProvider().gssCredentialToKerberosTicket(kerberosTicket, gssCredential);
|
||||
|
||||
GSSCredentialImpl gssCredImpl = (GSSCredentialImpl) gssCredential;
|
||||
Oid[] mechs = gssCredImpl.getMechs();
|
||||
|
||||
for (Oid oid : mechs) {
|
||||
if (oid.equals(KRB5_OID)) {
|
||||
int usage = gssCredImpl.getUsage(oid);
|
||||
boolean initiate = (usage == GSSCredential.INITIATE_ONLY || usage == GSSCredential.INITIATE_AND_ACCEPT);
|
||||
|
||||
GSSCredentialSpi credentialSpi = gssCredImpl.getElement(oid, initiate);
|
||||
if (credentialSpi instanceof Krb5InitCredential) {
|
||||
Krb5InitCredential credential = (Krb5InitCredential) credentialSpi;
|
||||
KerberosTicket kerberosTicket = new KerberosTicket(credential.getEncoded(),
|
||||
credential.getClient(),
|
||||
credential.getServer(),
|
||||
credential.getSessionKey().getEncoded(),
|
||||
credential.getSessionKeyType(),
|
||||
credential.getFlags(),
|
||||
credential.getAuthTime(),
|
||||
credential.getStartTime(),
|
||||
credential.getEndTime(),
|
||||
credential.getRenewTill(),
|
||||
credential.getClientAddresses());
|
||||
return serialize(kerberosTicket);
|
||||
} else {
|
||||
throw new KerberosSerializationException("Unsupported type of credentialSpi: " + credentialSpi.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new KerberosSerializationException("Kerberos credential not found. Available mechanisms: " + mechs);
|
||||
return serialize(kerberosTicket);
|
||||
} catch (IOException e) {
|
||||
throw new KerberosSerializationException("Exception occured", e);
|
||||
} catch (GSSException e) {
|
||||
throw new KerberosSerializationException("Exception occured", e);
|
||||
throw new KerberosSerializationException("Unexpected exception when serialize GSSCredential", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,32 +81,12 @@ public class KerberosSerializationUtils {
|
||||
}
|
||||
|
||||
KerberosTicket ticket = (KerberosTicket) deserializedCred;
|
||||
String fullName = ticket.getClient().getName();
|
||||
|
||||
Method getInstance = Reflections.findDeclaredMethod(Krb5NameElement.class, "getInstance", String.class, Oid.class);
|
||||
Krb5NameElement krb5Name = Reflections.invokeMethod(true, getInstance, Krb5NameElement.class, null, fullName, KRB5_NAME_OID);
|
||||
|
||||
Credentials krb5CredsInternal = new Credentials(
|
||||
ticket.getEncoded(),
|
||||
ticket.getClient().getName(),
|
||||
ticket.getServer().getName(),
|
||||
ticket.getSessionKey().getEncoded(),
|
||||
ticket.getSessionKeyType(),
|
||||
ticket.getFlags(),
|
||||
ticket.getAuthTime(),
|
||||
ticket.getStartTime(),
|
||||
ticket.getEndTime(),
|
||||
ticket.getRenewTill(),
|
||||
ticket.getClientAddresses()
|
||||
);
|
||||
|
||||
Method getInstance2 = Reflections.findDeclaredMethod(Krb5InitCredential.class, "getInstance", Krb5NameElement.class, Credentials.class);
|
||||
Krb5InitCredential initCredential = Reflections.invokeMethod(true, getInstance2, Krb5InitCredential.class, null, krb5Name, krb5CredsInternal);
|
||||
|
||||
GSSManagerImpl manager = (GSSManagerImpl) GSSManager.getInstance();
|
||||
return new GSSCredentialImpl(manager, initCredential);
|
||||
return KerberosJdkProvider.getProvider().kerberosTicketToGSSCredential(ticket);
|
||||
} catch (KerberosSerializationException ke) {
|
||||
throw ke;
|
||||
} catch (Exception ioe) {
|
||||
throw new KerberosSerializationException("Exception occured", ioe);
|
||||
throw new KerberosSerializationException("Unexpected exception when deserialize GSSCredential", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
Executable → Regular
+8
@@ -110,6 +110,14 @@ public class AbstractOAuthClient {
|
||||
this.publicClient = publicClient;
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return isSecure;
|
||||
}
|
||||
|
||||
public void setSecure(boolean secure) {
|
||||
isSecure = secure;
|
||||
}
|
||||
|
||||
public RelativeUrlsUsed getRelativeUrlsUsed() {
|
||||
return relativeUrlsUsed;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,11 @@ public class Config {
|
||||
@Override
|
||||
public Boolean getBoolean(String key, Boolean defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Boolean.parseBoolean(v) : defaultValue;
|
||||
if (v != null) {
|
||||
return Boolean.parseBoolean(v);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.jose.jws.JWSBuilder;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class KeyPairVerifier {
|
||||
|
||||
public static void verify(String privateKeyPem, String publicKeyPem) throws VerificationException {
|
||||
PrivateKey privateKey;
|
||||
try {
|
||||
privateKey = PemUtils.decodePrivateKey(privateKeyPem);
|
||||
} catch (Exception e) {
|
||||
throw new VerificationException("Failed to decode private key");
|
||||
}
|
||||
|
||||
PublicKey publicKey;
|
||||
try {
|
||||
publicKey = PemUtils.decodePublicKey(publicKeyPem);
|
||||
} catch (Exception e) {
|
||||
throw new VerificationException("Failed to decode public key");
|
||||
}
|
||||
|
||||
try {
|
||||
String jws = new JWSBuilder().content("content".getBytes()).rsa256(privateKey);
|
||||
if (!RSAProvider.verify(new JWSInput(jws), publicKey)) {
|
||||
throw new VerificationException("Keys don't match");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new VerificationException("Keys don't match");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,9 @@ import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Available in secured requests under HttpServlerRequest.getAttribute()
|
||||
* Also available in HttpSession.getAttribute under the classname of this class
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ public class AccessTokenResponse {
|
||||
@JsonProperty("not-before-policy")
|
||||
protected int notBeforePolicy;
|
||||
|
||||
@JsonProperty("session-state")
|
||||
@JsonProperty("session_state")
|
||||
protected String sessionState;
|
||||
|
||||
protected Map<String, Object> otherClaims = new HashMap<String, Object>();
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* 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.representations;
|
||||
|
||||
/**
|
||||
* Configuration of KeyStore.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public class KeyStoreConfig {
|
||||
|
||||
protected Boolean realmCertificate;
|
||||
protected String storePassword;
|
||||
protected String keyPassword;
|
||||
protected String keyAlias;
|
||||
protected String realmAlias;
|
||||
protected String format;
|
||||
|
||||
public Boolean isRealmCertificate() {
|
||||
return realmCertificate;
|
||||
}
|
||||
|
||||
public void setRealmCertificate(Boolean realmCertificate) {
|
||||
this.realmCertificate = realmCertificate;
|
||||
}
|
||||
|
||||
public String getStorePassword() {
|
||||
return storePassword;
|
||||
}
|
||||
|
||||
public void setStorePassword(String storePassword) {
|
||||
this.storePassword = storePassword;
|
||||
}
|
||||
|
||||
public String getKeyPassword() {
|
||||
return keyPassword;
|
||||
}
|
||||
|
||||
public void setKeyPassword(String keyPassword) {
|
||||
this.keyPassword = keyPassword;
|
||||
}
|
||||
|
||||
public String getKeyAlias() {
|
||||
return keyAlias;
|
||||
}
|
||||
|
||||
public void setKeyAlias(String keyAlias) {
|
||||
this.keyAlias = keyAlias;
|
||||
}
|
||||
|
||||
public String getRealmAlias() {
|
||||
return realmAlias;
|
||||
}
|
||||
|
||||
public void setRealmAlias(String realmAlias) {
|
||||
this.realmAlias = realmAlias;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.VerificationException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class KeyPairVerifierTest {
|
||||
|
||||
String privateKey1 = "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=";
|
||||
String publicKey1 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB";
|
||||
|
||||
String privateKey2048 = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEpQIBAAKCAQEA4V3MpOnuKsdBbR1UzNjK9o5meEMQ4s5Vpykhv1DpqTilKOiE\n"
|
||||
+ "H7VQ/XtjNxw0yjnFBilCnpK6yN9mDEHbBEzaRjtdrgVhkIejiaXFBP5MBhUQ5l9u\n" + "8E3IZC3E8pwDjVF0Z9u0R4lGeUg2k6O+NKumqIvxoLCTuG0zf53bctGsRd57LuFi\n"
|
||||
+ "pgCkNyxvscOhulsbEMYrLwlb5bMGgx9v+RCnwvunNEb7RK+5pzP+iH1MRejRsX+U\n" + "7h9zHRn2gQhIl7SzG9GXebuPWr4KKwfMHWy0PEuQrsfWRXm9/dTEavbfNkv5E53z\n"
|
||||
+ "WXjWyf93ezkVhBX0YoXmf6UO7PAlvsrjno3TuwIDAQABAoIBAQC5iCAOcCtLemhp\n" + "bOlADwXgPtErFoNTROyMxjbrKrCCSIjniawj8oAvfiHq38Sx6ydBcDxREZjF/+wi\n"
|
||||
+ "ESE+hAp6ISt5NSLh+lhu3FK7TqLFqxgTn+NT36Umm+t0k231LGa5jcz3y5KCDCoq\n" + "F3ZiJCH6xeLxGA00mmn4GLvt5aF+jiO80ICGs4iUg99IoXhc5u/VU0hB5J78BinW\n"
|
||||
+ "inkCABuBNkDLgIqc9BoH4L5MOx3zDqzmHffeq9+2V4X7NiD5QyiyWtABaQpEIY5k\n" + "R48RTno6xN3hvG48/DwkO2gABSLQ/OJd3Hupv4wlmmSc1xo93CaV44hq2i2GsU1i\n"
|
||||
+ "m6d3xDW5AoGBAPCfkvPkqr88xg+8Cu3G/3GFpUsQ0VEme+8dIjXMTJHa13K7xaRh\n" + "GHCVg4a8oHJ/P/vNSwvPyR71iRX4csqkKSaprvJk8vxbU539unmHWKkfUHrywQlz\n"
|
||||
+ "q4OuXOjOdvILLOTsu3/+k6vAIE6SZJiDmf2eGxi9Qbm5rlxE3h3HRAKfAoGBAO/E\n" + "ogHV86LmnJTJbx1hP3IfRHk0qaiSj35ljlAz+3v6GN/KSUYCWTtp2GjRIKY3qQ8I\n"
|
||||
+ "7l+PVTFg3SY7cPq2C9TE+6xroiWkUd2JldPLYSxpWpFNYlo709SzmLquDho+fwJC\n" + "nAxoxKghsXJarz7TRfNyFqDXscS6oQLurU9P5lVlAoGBAJh1QvLtS5Jnu0Z06qfF\n"
|
||||
+ "kkwnVZe+TCGStKvIVciobUts0V2Mw6lnK8kJspBIK5DgN3YfmREe0lufTwBwrqre\n" + "YIRytro2ZA6o/s332ZLuwqpFgQSlktGeTGnerFeFma+6jPNvW025y27jCJVABCTu\n"
|
||||
+ "HT+oUZrXLzGyCFvF9sX/X4QZAoGBAICap4r0h0nJCBOGN+M6Vh2QR9n7NUUF15Gk\n" + "R0EdoLZO3yiqB8NVXydPDpSqFykQkc1OrQz0hG2H1xa6q07OdmoZfiRtVvt5t69s\n"
|
||||
+ "LMD9RZHcsIdfSnG7xVNBQZpf4ZCSFO3RbIH7b//+kn8TxQudptd9SkXba65prBM2\n" + "kh8IbDNBAoGAVsKvkruH7RK7CimDSWcdAKvHARqkjs/PoeKEEY8Yu6zf0Z9TQM5l\n"
|
||||
+ "uC9EwBamYcSusWRcdcz+9HYG58XFnmXq+3EUuFbJ+Ljb8YWBgePjSHDoS/6+/+zq\n" + "B1b5uQp/jYFbYQl50UPRPTF+ul1eQoy7F43Ngj3/5cDRarFZe3ZTzZo=\n"
|
||||
+ "-----END RSA PRIVATE KEY-----";
|
||||
String publicKey2048 = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4V3MpOnuKsdBbR1UzNjK\n"
|
||||
+ "9o5meEMQ4s5Vpykhv1DpqTilKOiEH7VQ/XtjNxw0yjnFBilCnpK6yN9mDEHbBEza\n" + "RjtdrgVhkIejiaXFBP5MBhUQ5l9u8E3IZC3E8pwDjVF0Z9u0R4lGeUg2k6O+NKum\n"
|
||||
+ "qIvxoLCTuG0zf53bctGsRd57LuFipgCkNyxvscOhulsbEMYrLwlb5bMGgx9v+RCn\n" + "wvunNEb7RK+5pzP+iH1MRejRsX+U7h9zHRn2gQhIl7SzG9GXebuPWr4KKwfMHWy0\n"
|
||||
+ "PEuQrsfWRXm9/dTEavbfNkv5E53zWXjWyf93ezkVhBX0YoXmf6UO7PAlvsrjno3T\n" + "uwIDAQAB\n" + "-----END PUBLIC KEY-----";
|
||||
|
||||
@Test
|
||||
public void verify() throws Exception {
|
||||
KeyPairVerifier.verify(privateKey1, publicKey1);
|
||||
KeyPairVerifier.verify(privateKey2048, publicKey2048);
|
||||
|
||||
try {
|
||||
KeyPairVerifier.verify(privateKey1, publicKey2048);
|
||||
Assert.fail("Expected VerificationException");
|
||||
} catch (VerificationException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
KeyPairVerifier.verify(privateKey2048, publicKey1);
|
||||
Assert.fail("Expected VerificationException");
|
||||
} catch (VerificationException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-eap6-adapter-dist-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
-1
@@ -28,7 +28,6 @@
|
||||
<module name="javax.api"/>
|
||||
<module name="javax.activation.api"/>
|
||||
<module name="sun.jdk" optional="true" />
|
||||
<module name="sun.jdk.jgss" optional="true" />
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
-1
@@ -33,7 +33,6 @@
|
||||
<module name="javax.api"/>
|
||||
<module name="javax.activation.api"/>
|
||||
<module name="sun.jdk" optional="true" />
|
||||
<module name="sun.jdk.jgss" optional="true" />
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-as7-eap6-adapter-dist-pom</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak AS7 / JBoss EAP 6 Adapter Distros</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OSGI Features</name>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
<feature name="keycloak-adapter-core" version="${project.version}" resolver="(obr)">
|
||||
<details>The keycloak adapter core stuff</details>
|
||||
<bundle dependency="true">mvn:org.keycloak/keycloak-osgi-thirdparty/${project.version}</bundle>
|
||||
<bundle dependency="true">mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle.crypto.version}</bundle>
|
||||
<bundle dependency="true">mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.crypto.version}</bundle>
|
||||
<bundle dependency="true">mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle.version}</bundle>
|
||||
<bundle dependency="true">mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.version}</bundle>
|
||||
<bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
|
||||
<bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
|
||||
<bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OSGI JAAS Realm Configuration</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak OSGI Integration</name>
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-distribution-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
</parent>
|
||||
|
||||
<name>Adapters Distribution Parent</name>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.9.0.Final-SNAPSHOT</version>
|
||||
<version>1.9.1.Final</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
Loaded 100 of 590 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user