Compare commits

..
Author SHA1 Message Date
keycloak-bot f66e5610e9 Set version to 1.9.0.Final 2016-02-23 18:50:05 +00:00
Stian Thorgersen 49516dca16 Merge pull request #2265 from stianst/1.9.x
KEYCLOAK-2530
2016-02-23 19:24:34 +01:00
Stian Thorgersen 034e28f1ff Updated examples with moved themes directory 2016-02-23 15:31:12 +01:00
Stian Thorgersen 0aa8ab4d68 KEYCLOAK-2530
Missing IP address in Login Events
2016-02-23 14:33:13 +01:00
Stian Thorgersen 8d14c193a9 Merge pull request #2261 from stianst/1.9.x
KEYCLOAK-2527
2016-02-23 14:15:30 +01:00
Stian Thorgersen fc54e481fa KEYCLOAK-2527
Cordova not working
2016-02-23 13:31:49 +01:00
Marek Posolda f6a6a5375b Merge pull request #2260 from mposolda/1.9.x
Fix fuse adapter
2016-02-23 11:57:14 +01:00
mposolda 2599289564 Fix fuse adapter 2016-02-23 11:18:36 +01:00
Stian Thorgersen 16fb74fa96 Merge pull request #2256 from stianst/1.9.x
1.9.x
2016-02-23 10:59:57 +01:00
Marek Posolda 51f800326b Merge pull request #2258 from mposolda/1.9.x
KEYCLOAK-2526 JPA migration from 1.8.1 doesn't work
2016-02-23 10:38:03 +01:00
mposolda a2714d0ce6 KEYCLOAK-2526 JPA migration from 1.8.1 doesn't work 2016-02-23 10:00:29 +01:00
Stian Thorgersen ce69dd340f KEYCLOAK-2525
Built-in themes not loaded from modules
2016-02-23 09:48:49 +01:00
Stian Thorgersen 8e0d6f00a5 Remove old logo from sunrise theme example 2016-02-23 09:06:35 +01:00
Stian Thorgersen 05d070c29a Merge pull request #2254 from abstractj/KEYCLOAK-2524
Admin client example fails after login
2016-02-23 08:51:04 +01:00
Stian Thorgersen 4d2b71748b Merge pull request #2253 from abstractj/KEYCLOAK-2521
Angular Product raises an exception on logout
2016-02-23 08:49:44 +01:00
Stian Thorgersen 4752789940 Merge pull request #2252 from abstractj/KEYCLOAK-2519
Admin cannot manage her own profile at Customer Portal app
2016-02-23 08:46:08 +01:00
Bruno Oliveira f6ada4a7ec Admin client example fails after login 2016-02-22 16:03:40 -03:00
Bruno Oliveira 187517d882 Angular Product raises an exception on logout 2016-02-22 13:33:18 -03:00
Bruno Oliveira 8cc4c0967e Admin cannot manage her own profile at Customer Portal app 2016-02-22 11:59:55 -03:00
Marek Posolda 950c50c750 Merge pull request #2251 from mposolda/1.9.x
Fix SyncFederationTest to work with MSSQL and envs with slower databases
2016-02-22 12:59:09 +01:00
mposolda a34e4f6d2c Fix SyncFederationTest to work with MSSQL and envs with slower databases 2016-02-22 12:10:21 +01:00
1488 changed files with 15408 additions and 36328 deletions

No files matched your search

+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -169,7 +169,11 @@ public class AdapterDeploymentContext {
public void setAuthServerBaseUrl(String authServerBaseUrl) {
this.authServerBaseUrl = authServerBaseUrl;
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
resolveUrls(serverBuilder);
resolveBrowserUrls(serverBuilder);
if (delegate.getRelativeUrls() == RelativeUrlsUsed.ALL_REQUESTS) {
resolveNonBrowserUrls(serverBuilder);
}
}
@Override
@@ -38,6 +38,37 @@ public class AdapterUtils {
return UUID.randomUUID().toString();
}
/**
* Best effort to find origin for REST request calls from web UI application to REST application. In case of relative or absolute
* "auth-server-url" is returned the URL from request. In case of "auth-server-url-for-backend-request" used in configuration, it returns
* the origin of auth server.
*
* This may be the optimization in cluster, so if you have keycloak and applications on same host, the REST request doesn't need to
* go through loadbalancer, but can be sent directly to same host.
*
* @param browserRequestURL
* @param session
* @return
*/
public static String getOriginForRestCalls(String browserRequestURL, KeycloakSecurityContext session) {
if (session instanceof RefreshableKeycloakSecurityContext) {
KeycloakDeployment deployment = ((RefreshableKeycloakSecurityContext)session).getDeployment();
switch (deployment.getRelativeUrls()) {
case ALL_REQUESTS:
case NEVER:
// Resolve baseURI from the request
return UriUtils.getOrigin(browserRequestURL);
case BROWSER_ONLY:
// Resolve baseURI from the codeURL (This is already non-relative and based on our hostname)
return UriUtils.getOrigin(deployment.getTokenUrl());
default:
return "";
}
} else {
return UriUtils.getOrigin(browserRequestURL);
}
}
public static Set<String> getRolesFromSecurityContext(RefreshableKeycloakSecurityContext session) {
Set<String> roles = null;
AccessToken accessToken = session.getToken();
@@ -111,17 +111,39 @@ public class KeycloakDeployment {
public void setAuthServerBaseUrl(AdapterConfig config) {
this.authServerBaseUrl = config.getAuthServerUrl();
if (authServerBaseUrl == null) return;
String authServerURLForBackendReqs = config.getAuthServerUrlForBackendRequests();
if (authServerBaseUrl == null && authServerURLForBackendReqs == null) return;
URI authServerUri = URI.create(authServerBaseUrl);
URI authServerUri = null;
if (authServerBaseUrl != null) {
authServerUri = URI.create(authServerBaseUrl);
}
if (authServerUri.getHost() == null) {
relativeUrls = RelativeUrlsUsed.ALWAYS;
if (authServerUri == null || authServerUri.getHost() == null) {
if (authServerURLForBackendReqs != null) {
relativeUrls = RelativeUrlsUsed.BROWSER_ONLY;
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerURLForBackendReqs);
if (serverBuilder.getHost() == null || serverBuilder.getScheme() == null) {
throw new IllegalStateException("Relative URL not supported for auth-server-url-for-backend-requests option. URL used: "
+ authServerURLForBackendReqs + ", Client: " + config.getResource());
}
resolveNonBrowserUrls(serverBuilder);
} else {
relativeUrls = RelativeUrlsUsed.ALL_REQUESTS;
}
} else {
// We have absolute URI in config
relativeUrls = RelativeUrlsUsed.NEVER;
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
resolveUrls(serverBuilder);
resolveBrowserUrls(serverBuilder);
if (authServerURLForBackendReqs == null) {
resolveNonBrowserUrls(serverBuilder);
} else {
serverBuilder = KeycloakUriBuilder.fromUri(authServerURLForBackendReqs);
resolveNonBrowserUrls(serverBuilder);
}
}
}
@@ -130,14 +152,23 @@ public class KeycloakDeployment {
/**
* @param authUrlBuilder absolute URI
*/
protected void resolveUrls(KeycloakUriBuilder authUrlBuilder) {
protected void resolveBrowserUrls(KeycloakUriBuilder authUrlBuilder) {
if (log.isDebugEnabled()) {
log.debug("resolveUrls");
log.debug("resolveBrowserUrls");
}
String login = authUrlBuilder.clone().path(ServiceUrlConstants.AUTH_PATH).build(getRealm()).toString();
authUrl = KeycloakUriBuilder.fromUri(login);
realmInfoUrl = authUrlBuilder.clone().path(ServiceUrlConstants.REALM_INFO_PATH).build(getRealm()).toString();
}
/**
* @param authUrlBuilder absolute URI
*/
protected void resolveNonBrowserUrls(KeycloakUriBuilder authUrlBuilder) {
if (log.isDebugEnabled()) {
log.debug("resolveNonBrowserUrls");
}
tokenUrl = authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_PATH).build(getRealm()).toString();
logoutUrl = KeycloakUriBuilder.fromUri(authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH).build(getRealm()).toString());
@@ -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()), true);
exchange.getResponse().setCookie(deployment.getStateCookieName(), state, /* need to set path? */ null, null, -1, deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr()), false);
exchange.getResponse().setHeader("Location", redirect);
return true;
}
@@ -54,7 +54,7 @@ public class KeycloakDeploymentBuilderTest {
assertEquals("234234-234234-234234", deployment.getResourceCredentials().get("secret"));
assertEquals(ClientIdAndSecretCredentialsProvider.PROVIDER_ID, deployment.getClientAuthenticator().getId());
assertEquals(20, ((ThreadSafeClientConnManager) deployment.getClient().getConnectionManager()).getMaxTotal());
assertEquals("https://localhost:8443/auth/realms/demo/protocol/openid-connect/token", deployment.getTokenUrl());
assertEquals("https://backend:8443/auth/realms/demo/protocol/openid-connect/token", deployment.getTokenUrl());
assertEquals(RelativeUrlsUsed.NEVER, deployment.getRelativeUrls());
assertTrue(deployment.isAlwaysRefreshToken());
assertTrue(deployment.isRegisterNodeAtStartup());
@@ -24,6 +24,7 @@
"client-keystore": "classpath:/keystore.jks",
"client-keystore-password": "storepass",
"client-key-password": "keypass",
"auth-server-url-for-backend-requests": "https://backend:8443/auth",
"always-refresh-token": true,
"register-node-at-startup": true,
"register-node-period": 1000,
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-integration-pom</artifactId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -18,8 +18,6 @@
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;
@@ -137,44 +135,10 @@ 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);
}
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Jetty Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -163,8 +163,6 @@
}
} else if (initOptions.onLoad) {
onLoad();
} else {
initPromise.setSuccess();
}
} else {
initPromise.setSuccess();
@@ -192,7 +190,7 @@
redirectUri += (redirectUri.indexOf('?') == -1 ? '?' : '&') + 'prompt=' + options.prompt;
}
localStorage.oauthState = JSON.stringify({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) });
sessionStorage.oauthState = JSON.stringify({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) });
var action = 'auth';
if (options && options.action == 'register') {
@@ -689,10 +687,10 @@
function parseCallback(url) {
var oauth = new CallbackParser(url, kc.responseMode).parseUri();
var sessionState = localStorage.oauthState && JSON.parse(localStorage.oauthState);
var sessionState = sessionStorage.oauthState && JSON.parse(sessionStorage.oauthState);
if (sessionState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token) && oauth.state && oauth.state == sessionState.state) {
delete localStorage.oauthState;
delete sessionStorage.oauthState;
oauth.redirectUri = sessionState.redirectUri;
oauth.storedNonce = sessionState.nonce;
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak OIDC Client Adapter Modules</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -51,16 +51,10 @@ public class OIDCFilterSessionStore extends FilterSessionStore implements Adapte
}
public HttpServletRequestWrapper buildWrapper() {
HttpSession session = request.getSession(false);
KeycloakAccount account = null;
if (session != null) {
account = (KeycloakAccount) session.getAttribute(KeycloakAccount.class.getName());
if (account == null) {
account = (KeycloakAccount) request.getAttribute(KeycloakAccount.class.getName());
}
}
HttpSession session = request.getSession();
KeycloakAccount account = (KeycloakAccount)session.getAttribute(KeycloakAccount.class.getName());
if (account == null) {
account = (KeycloakAccount) request.getAttribute(KeycloakAccount.class.getName());
account = (KeycloakAccount)request.getAttribute(KeycloakAccount.class.getName());
}
return buildWrapper(session, account);
}
@@ -95,7 +89,6 @@ public class OIDCFilterSessionStore extends FilterSessionStore implements Adapte
protected void cleanSession(HttpSession session) {
session.removeAttribute(KeycloakAccount.class.getName());
session.removeAttribute(KeycloakSecurityContext.class.getName());
clearSavedRequest(session);
}
@@ -167,7 +160,6 @@ 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);
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -33,7 +33,7 @@ public class ServletOAuthClientBuilderTest {
public void testBuilder() {
ServletOAuthClient oauthClient = ServletOAuthClientBuilder.build(getClass().getResourceAsStream("/keycloak.json"));
Assert.assertEquals("https://localhost:8443/auth/realms/demo/protocol/openid-connect/auth", oauthClient.getDeployment().getAuthUrl().clone().build().toString());
Assert.assertEquals("https://localhost:8443/auth/realms/demo/protocol/openid-connect/token", oauthClient.getDeployment().getTokenUrl());
Assert.assertEquals("https://backend:8443/auth/realms/demo/protocol/openid-connect/token", oauthClient.getDeployment().getTokenUrl());
assertEquals(RelativeUrlsUsed.NEVER, oauthClient.getRelativeUrlsUsed());
Assert.assertEquals("customer-portal", oauthClient.getClientId());
Assert.assertEquals("234234-234234-234234", oauthClient.getCredentials().get(CredentialRepresentation.SECRET));
@@ -19,6 +19,7 @@
"connection-pool-size": 20,
"disable-trust-manager": true,
"allow-any-hostname": true,
"auth-server-url-for-backend-requests": "https://backend:8443/auth",
"always-refresh-token": true,
"register-node-at-startup": true,
"register-node-period": 1000,
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Tomcat Integration</name>
+2 -2
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -45,7 +45,7 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
@@ -69,22 +69,12 @@ 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()) {
request.setAttribute(KeycloakSecurityContext.class.getName(), session);
request.setUserPrincipal(account.getPrincipal());
request.setAuthType("KEYCLOAK");
return;
}
if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) 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()) {
request.setAttribute(KeycloakSecurityContext.class.getName(), session);
request.setUserPrincipal(account.getPrincipal());
request.setAuthType("KEYCLOAK");
return;
}
if (success && session.isActive()) 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");
@@ -95,8 +85,6 @@ 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);
@@ -176,7 +164,6 @@ 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);
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -92,8 +92,7 @@ public class ServletSessionTokenStore implements AdapterTokenStore {
} else {
log.debug("Refresh failed. Account was not active. Returning null and invalidating Http session");
try {
session.removeAttribute(KeycloakUndertowAccount.class.getName());
session.removeAttribute(KeycloakSecurityContext.class.getName());
session.setAttribute(KeycloakUndertowAccount.class.getName(), null);
session.invalidate();
} catch (Exception e) {
log.debug("Failed to invalidate session, might already be invalidated");
@@ -107,7 +106,6 @@ 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());
}
@@ -22,7 +22,6 @@ 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;
@@ -83,7 +82,6 @@ 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;
}
@@ -103,7 +101,6 @@ 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());
}
@@ -114,7 +111,6 @@ 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
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak WildFly Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Keycloak Integration</name>
+1 -5
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -43,10 +43,6 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML EAP Integration</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -39,7 +39,6 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core");
private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-saml-adapter-core");
private static final ModuleIdentifier KEYCLOAK_API_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-saml-adapter-api-public");
private static final ModuleIdentifier KEYCLOAK_COMMON = ModuleIdentifier.create("org.keycloak.keycloak-common");
@Override
@@ -71,7 +70,6 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
private void addCommonModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
// ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_API_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_COMMON, false, false, false, false));
}
-82
View File
@@ -1,82 +0,0 @@
<?xml version="1.0"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
<name>Keycloak SAML Client Adapter Public API</name>
<description/>
<properties>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core-public</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
+1 -11
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -35,11 +35,6 @@
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core-public</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
@@ -50,11 +45,6 @@
<artifactId>keycloak-adapter-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
@@ -26,6 +26,7 @@ import org.keycloak.saml.SAML2NameIDPolicyBuilder;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.common.exceptions.ConfigurationException;
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.w3c.dom.Document;
import java.io.IOException;
import java.security.KeyPair;
@@ -53,8 +54,45 @@ public abstract class AbstractInitiateLogin implements AuthChallenge {
@Override
public boolean challenge(HttpFacade httpFacade) {
try {
SAML2AuthnRequestBuilder authnRequestBuilder = buildSaml2AuthnRequestBuilder(deployment);
BaseSAML2BindingBuilder binding = createSaml2Binding(deployment);
String issuerURL = deployment.getEntityID();
String nameIDPolicyFormat = deployment.getNameIDPolicyFormat();
if (nameIDPolicyFormat == null) {
nameIDPolicyFormat = JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get();
}
SAML2AuthnRequestBuilder authnRequestBuilder = new SAML2AuthnRequestBuilder()
.destination(deployment.getIDP().getSingleSignOnService().getRequestBindingUrl())
.issuer(issuerURL)
.forceAuthn(deployment.isForceAuthentication()).isPassive(deployment.isIsPassive())
.nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat));
if (deployment.getIDP().getSingleSignOnService().getResponseBinding() != null) {
String protocolBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get();
if (deployment.getIDP().getSingleSignOnService().getResponseBinding() == SamlDeployment.Binding.POST) {
protocolBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get();
}
authnRequestBuilder.protocolBinding(protocolBinding);
}
if (deployment.getAssertionConsumerServiceUrl() != null) {
authnRequestBuilder.assertionConsumerUrl(deployment.getAssertionConsumerServiceUrl());
}
BaseSAML2BindingBuilder binding = new BaseSAML2BindingBuilder();
if (deployment.getIDP().getSingleSignOnService().signRequest()) {
KeyPair keypair = deployment.getSigningKeyPair();
if (keypair == null) {
throw new RuntimeException("Signing keys not configured");
}
if (deployment.getSignatureCanonicalizationMethod() != null) {
binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
}
binding.signWith(keypair);
binding.signDocument();
}
sessionStore.saveRequest();
sendAuthnRequest(httpFacade, authnRequestBuilder, binding);
@@ -65,53 +103,6 @@ public abstract class AbstractInitiateLogin implements AuthChallenge {
return true;
}
public static BaseSAML2BindingBuilder createSaml2Binding(SamlDeployment deployment) {
BaseSAML2BindingBuilder binding = new BaseSAML2BindingBuilder();
if (deployment.getIDP().getSingleSignOnService().signRequest()) {
binding.signatureAlgorithm(deployment.getSignatureAlgorithm());
KeyPair keypair = deployment.getSigningKeyPair();
if (keypair == null) {
throw new RuntimeException("Signing keys not configured");
}
if (deployment.getSignatureCanonicalizationMethod() != null) {
binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
}
binding.signWith(keypair);
binding.signDocument();
}
return binding;
}
public static SAML2AuthnRequestBuilder buildSaml2AuthnRequestBuilder(SamlDeployment deployment) {
String issuerURL = deployment.getEntityID();
String nameIDPolicyFormat = deployment.getNameIDPolicyFormat();
if (nameIDPolicyFormat == null) {
nameIDPolicyFormat = JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get();
}
SAML2AuthnRequestBuilder authnRequestBuilder = new SAML2AuthnRequestBuilder()
.destination(deployment.getIDP().getSingleSignOnService().getRequestBindingUrl())
.issuer(issuerURL)
.forceAuthn(deployment.isForceAuthentication()).isPassive(deployment.isIsPassive())
.nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat));
if (deployment.getIDP().getSingleSignOnService().getResponseBinding() != null) {
String protocolBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get();
if (deployment.getIDP().getSingleSignOnService().getResponseBinding() == SamlDeployment.Binding.POST) {
protocolBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get();
}
authnRequestBuilder.protocolBinding(protocolBinding);
}
if (deployment.getAssertionConsumerServiceUrl() != null) {
authnRequestBuilder.assertionConsumerUrl(deployment.getAssertionConsumerServiceUrl());
}
return authnRequestBuilder;
}
protected abstract void sendAuthnRequest(HttpFacade httpFacade, SAML2AuthnRequestBuilder authnRequestBuilder, BaseSAML2BindingBuilder binding) throws ProcessingException, ConfigurationException, IOException;
}
@@ -19,6 +19,7 @@ package org.keycloak.adapters.saml;
import org.keycloak.adapters.spi.AuthenticationError;
import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
import org.keycloak.dom.saml.v2.protocol.StatusType;
/**
* Object that describes the SAML error that happened.
@@ -18,6 +18,8 @@
package org.keycloak.adapters.saml;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
import org.keycloak.dom.saml.v2.protocol.StatusType;
import java.util.List;
@@ -25,6 +25,7 @@ import org.keycloak.saml.common.util.StaxParserUtil;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
/**
@@ -18,6 +18,7 @@
package org.keycloak.adapters.saml.config.parsers;
import org.keycloak.adapters.saml.config.Key;
import org.keycloak.adapters.saml.config.SP;
import org.keycloak.saml.common.exceptions.ParsingException;
import org.keycloak.saml.common.parsers.AbstractParser;
import org.keycloak.saml.common.util.StaxParserUtil;
@@ -23,6 +23,7 @@ import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.saml.profile.SamlInvocationContext;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.saml.common.constants.GeneralConstants;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -20,6 +20,7 @@ package org.keycloak.adapters.saml.profile.webbrowsersso;
import org.keycloak.adapters.saml.OnSessionCreated;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.saml.profile.SamlInvocationContext;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.saml.common.constants.GeneralConstants;
+1 -5
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -60,10 +60,6 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
@@ -18,8 +18,6 @@
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;
@@ -27,8 +25,10 @@ import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.security.authentication.LoginAuthenticator;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.URIUtil;
import org.jboss.logging.Logger;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.saml.profile.SamlAuthenticationHandler;
@@ -135,46 +135,12 @@ 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);
}
@@ -28,6 +28,7 @@ import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpSession;
+1 -5
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -51,10 +51,6 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
+1 -5
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -52,10 +52,6 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
+1 -5
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -56,10 +56,6 @@
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Jetty Integration</name>
+1 -2
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Client Adapter Modules</name>
@@ -31,7 +31,6 @@
<packaging>pom</packaging>
<modules>
<module>core-public</module>
<module>core</module>
<module>undertow</module>
<module>tomcat</module>
+3 -7
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -39,7 +39,7 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
@@ -55,11 +55,7 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
</dependency>
@@ -26,6 +26,7 @@ import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.servlet.FilterSessionStore;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Tomcat Integration</name>
+3 -7
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -45,7 +45,7 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
@@ -65,11 +65,7 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
</dependency>
@@ -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,7 +180,6 @@ 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 {
}
@@ -27,7 +27,10 @@ import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.tomcat.CatalinaUserSessionManagement;
import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.LinkedList;
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-saml-tomcat-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -6
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -52,11 +52,6 @@
<artifactId>keycloak-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Wildfly Integration</name>
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -45,10 +45,6 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
@@ -21,7 +21,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -37,7 +37,6 @@ import org.jboss.modules.ModuleLoader;
public abstract class KeycloakDependencyProcessor implements DeploymentUnitProcessor {
private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core");
private static final ModuleIdentifier KEYCLOAK_API_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-saml-adapter-api-public");
private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-saml-adapter-core");
private static final ModuleIdentifier KEYCLOAK_COMMON = ModuleIdentifier.create("org.keycloak.keycloak-common");
@@ -73,7 +72,6 @@ public abstract class KeycloakDependencyProcessor implements DeploymentUnitProce
// ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_API_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_COMMON, false, false, false, false));
}
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -20,7 +20,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak Client Adapter SPI Modules</name>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -305,7 +305,6 @@ public class FilterSessionStore implements AdapterSessionStore {
@Override
public Principal getUserPrincipal() {
if (account == null) return null;
return account.getPrincipal();
}
+2 -2
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -41,7 +41,7 @@
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
@@ -71,9 +71,9 @@ public class CatalinaUserSessionManagement implements SessionListener {
protected void logoutSession(Session session) {
try {
if (session != null) session.expire();
session.expire();
} catch (Exception e) {
log.debug("Session not present or already invalidated.", e);
log.warn("Session not present or already invalidated.", e);
}
}
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -17,9 +17,6 @@
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>
*/
@@ -34,33 +31,19 @@ public class KerberosConstants {
/**
* OID of SPNEGO mechanism. See http://www.oid-info.com/get/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;
public static final String SPNEGO_OID = "1.3.6.1.5.5.2";
/**
* OID of Kerberos v5 mechanism. See http://www.oid-info.com/get/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;
public static final String KRB5_OID = "1.2.840.113554.1.2.2";
/**
* OID of Kerberos v5 name. See http://www.oid-info.com/get/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);
}
}
public static final String KRB5_NAME_OID = "1.2.840.113554.1.2.2.1";
/**
@@ -25,10 +25,29 @@ public enum RelativeUrlsUsed {
/**
* Always use relative URI and resolve them later based on browser HTTP request
*/
ALWAYS,
ALL_REQUESTS,
/**
* Use relative Uris just for browser requests and resolve those based on browser HTTP requests.
* Backend request (like refresh token request, codeToToken request etc) will use the URI based on current hostname
*/
BROWSER_ONLY,
/**
* Relative Uri not used. Configuration contains absolute URI
*/
NEVER;
public boolean useRelative(boolean isBrowserReq) {
switch (this) {
case ALL_REQUESTS:
return true;
case NEVER:
return false;
case BROWSER_ONLY:
return isBrowserReq;
default:
return true;
}
}
}
@@ -561,7 +561,7 @@ public class Base64
while( raw.hasRemaining() ){
int rem = Math.min(3,raw.remaining());
raw.get(raw3,0,rem);
Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS );
encoded.put(enc4);
} // end input remaining
}
@@ -1282,12 +1282,7 @@ public class Base64
} // end try
catch( java.io.IOException e ) {
if (e.getMessage().equals("Unsupported compression method")) {
System.out.println("Base64 decoding: Ignoring GZIP header and just returning originally-decoded bytes."); // Better to log as debug, but jboss logging not available in the module :/
} else {
e.printStackTrace();
}
e.printStackTrace();
// Just return originally-decoded bytes
} // end catch
finally {
@@ -1,227 +0,0 @@
/*
* 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,13 +25,22 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Set;
import java.lang.reflect.Method;
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
@@ -41,9 +50,18 @@ import org.ietf.jgss.GSSCredential;
*/
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");
@@ -54,17 +72,50 @@ public class KerberosSerializationUtils {
private KerberosSerializationUtils() {
}
public static String serializeCredential(KerberosTicket kerberosTicket, GSSCredential gssCredential) throws KerberosSerializationException {
public static String serializeCredential(GSSCredential gssCredential) throws KerberosSerializationException {
try {
if (gssCredential == null) {
throw new KerberosSerializationException("Null credential given as input");
}
kerberosTicket = KerberosJdkProvider.getProvider().gssCredentialToKerberosTicket(kerberosTicket, gssCredential);
if (!(gssCredential instanceof GSSCredentialImpl)) {
throw new KerberosSerializationException("Unknown credential type: " + gssCredential.getClass());
}
return serialize(kerberosTicket);
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);
} catch (IOException e) {
throw new KerberosSerializationException("Unexpected exception when serialize GSSCredential", e);
throw new KerberosSerializationException("Exception occured", e);
} catch (GSSException e) {
throw new KerberosSerializationException("Exception occured", e);
}
}
@@ -81,12 +132,32 @@ public class KerberosSerializationUtils {
}
KerberosTicket ticket = (KerberosTicket) deserializedCred;
String fullName = ticket.getClient().getName();
return KerberosJdkProvider.getProvider().kerberosTicketToGSSCredential(ticket);
} catch (KerberosSerializationException ke) {
throw ke;
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);
} catch (Exception ioe) {
throw new KerberosSerializationException("Unexpected exception when deserialize GSSCredential", ioe);
throw new KerberosSerializationException("Exception occured", ioe);
}
}
@@ -30,10 +30,6 @@ public class Time {
return ((int) (System.currentTimeMillis() / 1000)) + offset;
}
public static long currentTimeMillis() {
return System.currentTimeMillis() + (offset * 1000);
}
public static Date toDate(int time) {
return new Date(((long) time ) * 1000);
}
@@ -42,10 +38,6 @@ public class Time {
return ((long) time) * 1000;
}
public static int getOffset() {
return offset;
}
public static void setOffset(int offset) {
Time.offset = offset;
}
+1 -1
View File
@@ -21,7 +21,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.9.2.Final</version>
<version>1.9.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
-8
View File
@@ -110,14 +110,6 @@ public class AbstractOAuthClient {
this.publicClient = publicClient;
}
public boolean isSecure() {
return isSecure;
}
public void setSecure(boolean secure) {
isSecure = secure;
}
public RelativeUrlsUsed getRelativeUrlsUsed() {
return relativeUrlsUsed;
}
+1 -5
View File
@@ -135,11 +135,7 @@ public class Config {
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
String v = get(key, null);
if (v != null) {
return Boolean.parseBoolean(v);
} else {
return defaultValue;
}
return v != null ? Boolean.parseBoolean(v) : defaultValue;
}
@Override
@@ -1,59 +0,0 @@
/*
* 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");
}
}
}
Loaded 100 of 1488 files, more files were not shown because too many files have changed in this diff. Show more