Merge pull request #1010 from mposolda/krb-deleg-cred

Configurable KDC encryption types, Mongo fix
This commit is contained in:
Marek Posolda 2015-03-02 13:27:38 +01:00
commit d1fbe1fd30
7 changed files with 49 additions and 13 deletions

View file

@ -28,6 +28,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
"org.keycloak.models.mongo.keycloak.entities.MongoUserEntity", "org.keycloak.models.mongo.keycloak.entities.MongoUserEntity",
"org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity", "org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity",
"org.keycloak.models.entities.IdentityProviderEntity", "org.keycloak.models.entities.IdentityProviderEntity",
"org.keycloak.models.entities.ClientIdentityProviderMappingEntity",
"org.keycloak.models.entities.RequiredCredentialEntity", "org.keycloak.models.entities.RequiredCredentialEntity",
"org.keycloak.models.entities.CredentialEntity", "org.keycloak.models.entities.CredentialEntity",
"org.keycloak.models.entities.FederatedIdentityEntity", "org.keycloak.models.entities.FederatedIdentityEntity",
@ -36,7 +37,8 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
"org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity", "org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
"org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
"org.keycloak.models.entities.UserFederationProviderEntity" "org.keycloak.models.entities.UserFederationProviderEntity",
"org.keycloak.models.entities.ProtocolMapperEntity"
}; };
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class); private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);

View file

@ -23,7 +23,7 @@ package org.keycloak.models.entities;
public class ClientIdentityProviderMappingEntity { public class ClientIdentityProviderMappingEntity {
private String id; private String id;
private Boolean retrieveToken; private boolean retrieveToken;
public String getId() { public String getId() {
return this.id; return this.id;
@ -33,11 +33,11 @@ public class ClientIdentityProviderMappingEntity {
this.id = id; this.id = id;
} }
public Boolean isRetrieveToken() { public boolean isRetrieveToken() {
return this.retrieveToken; return this.retrieveToken;
} }
public void setRetrieveToken(Boolean retrieveToken) { public void setRetrieveToken(boolean retrieveToken) {
this.retrieveToken = retrieveToken; this.retrieveToken = retrieveToken;
} }

View file

@ -29,14 +29,12 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
protected final T clientEntity; protected final T clientEntity;
private final RealmModel realm; private final RealmModel realm;
protected KeycloakSession session; protected KeycloakSession session;
private final RealmProvider model;
public ClientAdapter(KeycloakSession session, RealmModel realm, T clientEntity, MongoStoreInvocationContext invContext) { public ClientAdapter(KeycloakSession session, RealmModel realm, T clientEntity, MongoStoreInvocationContext invContext) {
super(invContext); super(invContext);
this.clientEntity = clientEntity; this.clientEntity = clientEntity;
this.realm = realm; this.realm = realm;
this.session = session; this.session = session;
this.model = session.realms();
} }
@Override @Override
@ -326,13 +324,14 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
@Override @Override
public void updateAllowedIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) { public void updateAllowedIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
List<ClientIdentityProviderMappingEntity> stored = getMongoEntityAsClient().getIdentityProviders(); List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
for (ClientIdentityProviderMappingModel model : identityProviders) { for (ClientIdentityProviderMappingModel model : identityProviders) {
ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity(); ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
entity.setId(model.getIdentityProvider()); entity.setId(model.getIdentityProvider());
entity.setRetrieveToken(model.isRetrieveToken()); entity.setRetrieveToken(model.isRetrieveToken());
stored.add(entity);
} }
getMongoEntityAsClient().setIdentityProviders(stored); getMongoEntityAsClient().setIdentityProviders(stored);

View file

@ -910,7 +910,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
mapping.setConsentRequired(entity.isConsentRequired()); mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText()); mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>(); Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(config); if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapping.setConfig(config); mapping.setConfig(config);
return mapping; return mapping;
} }

View file

@ -1,5 +1,6 @@
package org.keycloak.protocol; package org.keycloak.protocol;
import org.jboss.logging.Logger;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
@ -14,6 +15,9 @@ import java.util.List;
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public abstract class AbstractLoginProtocolFactory implements LoginProtocolFactory { public abstract class AbstractLoginProtocolFactory implements LoginProtocolFactory {
private static final Logger logger = Logger.getLogger(AbstractLoginProtocolFactory.class);
@Override @Override
public void init(Config.Scope config) { public void init(Config.Scope config) {
} }
@ -27,6 +31,7 @@ public abstract class AbstractLoginProtocolFactory implements LoginProtocolFacto
for (RealmModel realm : realms) addDefaults(realm); for (RealmModel realm : realms) addDefaults(realm);
session.getTransaction().commit(); session.getTransaction().commit();
} catch (Exception e) { } catch (Exception e) {
logger.error("Can't add default mappers to realm", e);
session.getTransaction().rollback(); session.getTransaction().rollback();
} finally { } finally {
session.close(); session.close();

View file

@ -16,6 +16,7 @@ public class EmbeddedServersFactory {
private static final String DEFAULT_KERBEROS_REALM = "KEYCLOAK.ORG"; private static final String DEFAULT_KERBEROS_REALM = "KEYCLOAK.ORG";
private static final int DEFAULT_KDC_PORT = 6088; private static final int DEFAULT_KDC_PORT = 6088;
private static final String DEFAULT_KDC_ENCRYPTION_TYPES = "aes128-cts-hmac-sha1-96, des-cbc-md5, des3-cbc-sha1-kd";
private String baseDN; private String baseDN;
private String bindHost; private String bindHost;
@ -23,6 +24,7 @@ public class EmbeddedServersFactory {
private String ldifFile; private String ldifFile;
private String kerberosRealm; private String kerberosRealm;
private int kdcPort; private int kdcPort;
private String kdcEncryptionTypes;
public static EmbeddedServersFactory readConfiguration() { public static EmbeddedServersFactory readConfiguration() {
@ -40,6 +42,7 @@ public class EmbeddedServersFactory {
this.kerberosRealm = System.getProperty("kerberos.realm"); this.kerberosRealm = System.getProperty("kerberos.realm");
String kdcPort = System.getProperty("kerberos.port"); String kdcPort = System.getProperty("kerberos.port");
this.kdcEncryptionTypes = System.getProperty("kerberos.encTypes");
if (baseDN == null || baseDN.isEmpty()) { if (baseDN == null || baseDN.isEmpty()) {
baseDN = DEFAULT_BASE_DN; baseDN = DEFAULT_BASE_DN;
@ -56,6 +59,9 @@ public class EmbeddedServersFactory {
kerberosRealm = DEFAULT_KERBEROS_REALM; kerberosRealm = DEFAULT_KERBEROS_REALM;
} }
this.kdcPort = (kdcPort == null || kdcPort.isEmpty()) ? DEFAULT_KDC_PORT : Integer.parseInt(kdcPort); this.kdcPort = (kdcPort == null || kdcPort.isEmpty()) ? DEFAULT_KDC_PORT : Integer.parseInt(kdcPort);
if (kdcEncryptionTypes == null || kdcEncryptionTypes.isEmpty()) {
kdcEncryptionTypes = DEFAULT_KDC_ENCRYPTION_TYPES;
}
} }
@ -77,6 +83,6 @@ public class EmbeddedServersFactory {
ldifFile = DEFAULT_KERBEROS_LDIF_FILE; ldifFile = DEFAULT_KERBEROS_LDIF_FILE;
} }
return new KerberosEmbeddedServer(baseDN, bindHost, bindPort, ldifFile, kerberosRealm, kdcPort); return new KerberosEmbeddedServer(baseDN, bindHost, bindPort, ldifFile, kerberosRealm, kdcPort, kdcEncryptionTypes);
} }
} }

View file

@ -2,6 +2,8 @@ package org.keycloak.testutils.ldap;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import javax.security.auth.kerberos.KerberosPrincipal; import javax.security.auth.kerberos.KerberosPrincipal;
@ -20,6 +22,8 @@ import org.apache.directory.server.ldap.handlers.sasl.ntlm.NtlmMechanismHandler;
import org.apache.directory.server.ldap.handlers.sasl.plain.PlainMechanismHandler; import org.apache.directory.server.ldap.handlers.sasl.plain.PlainMechanismHandler;
import org.apache.directory.server.protocol.shared.transport.UdpTransport; import org.apache.directory.server.protocol.shared.transport.UdpTransport;
import org.apache.directory.shared.kerberos.KerberosTime; import org.apache.directory.shared.kerberos.KerberosTime;
import org.apache.directory.shared.kerberos.KerberosUtils;
import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
/** /**
@ -31,6 +35,7 @@ public class KerberosEmbeddedServer extends LDAPEmbeddedServer {
private final String kerberosRealm; private final String kerberosRealm;
private final int kdcPort; private final int kdcPort;
private final String kdcEncryptionTypes;
private KdcServer kdcServer; private KdcServer kdcServer;
@ -43,8 +48,9 @@ public class KerberosEmbeddedServer extends LDAPEmbeddedServer {
} }
protected KerberosEmbeddedServer(String baseDN, String bindHost, int bindPort, String ldifFile, String kerberosRealm, int kdcPort) { protected KerberosEmbeddedServer(String baseDN, String bindHost, int bindPort, String ldifFile, String kerberosRealm, int kdcPort, String kdcEncryptionTypes) {
super(baseDN, bindHost, bindPort, ldifFile); super(baseDN, bindHost, bindPort, ldifFile);
this.kdcEncryptionTypes = kdcEncryptionTypes;
this.kerberosRealm = kerberosRealm; this.kerberosRealm = kerberosRealm;
this.kdcPort = kdcPort; this.kdcPort = kdcPort;
} }
@ -54,7 +60,7 @@ public class KerberosEmbeddedServer extends LDAPEmbeddedServer {
public void init() throws Exception { public void init() throws Exception {
super.init(); super.init();
log.info("Creating KDC server. kerberosRealm: " + kerberosRealm + ", kdcPort: " + kdcPort); log.info("Creating KDC server. kerberosRealm: " + kerberosRealm + ", kdcPort: " + kdcPort + ", kdcEncryptionTypes: " + kdcEncryptionTypes);
createAndStartKdcServer(); createAndStartKdcServer();
} }
@ -93,6 +99,8 @@ public class KerberosEmbeddedServer extends LDAPEmbeddedServer {
kdcConfig.setMaximumTicketLifetime(60000 * 1440); kdcConfig.setMaximumTicketLifetime(60000 * 1440);
kdcConfig.setMaximumRenewableLifetime(60000 * 10080); kdcConfig.setMaximumRenewableLifetime(60000 * 10080);
kdcConfig.setPaEncTimestampRequired(false); kdcConfig.setPaEncTimestampRequired(false);
Set<EncryptionType> encryptionTypes = convertEncryptionTypes();
kdcConfig.setEncryptionTypes(encryptionTypes);
kdcServer = new NoReplayKdcServer(kdcConfig); kdcServer = new NoReplayKdcServer(kdcConfig);
kdcServer.setSearchBaseDn(this.baseDN); kdcServer.setSearchBaseDn(this.baseDN);
@ -122,6 +130,24 @@ public class KerberosEmbeddedServer extends LDAPEmbeddedServer {
} }
private Set<EncryptionType> convertEncryptionTypes() {
Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
String[] configEncTypes = kdcEncryptionTypes.split(",");
for ( String enc : configEncTypes ) {
enc = enc.trim();
for ( EncryptionType type : EncryptionType.getEncryptionTypes() ) {
if ( type.getName().equalsIgnoreCase( enc ) ) {
encryptionTypes.add( type );
}
}
}
encryptionTypes = KerberosUtils.orderEtypesByStrength(encryptionTypes);
return encryptionTypes;
}
/** /**
* Replacement of apacheDS KdcServer class with disabled ticket replay cache. * Replacement of apacheDS KdcServer class with disabled ticket replay cache.
* *
@ -151,12 +177,10 @@ public class KerberosEmbeddedServer extends LDAPEmbeddedServer {
@Override @Override
public void save(KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime, public void save(KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime,
int clientMicroSeconds) { int clientMicroSeconds) {
return;
} }
@Override @Override
public void clear() { public void clear() {
return;
} }
} }