@Override public void updateCredentialDirectly(UserCredentialValueModel credModel) { CredentialEntity credentialEntity = getCredentialEntity(user, credModel.getType()); if (credentialEntity == null) { credentialEntity = new CredentialEntity(); credentialEntity.setId(KeycloakModelUtils.generateId()); credentialEntity.setType(credModel.getType()); credentialEntity.setCreatedDate(credModel.getCreatedDate()); credentialEntity.setUser(user); em.persist(credentialEntity); user.getCredentials().add(credentialEntity); } credentialEntity.setValue(credModel.getValue()); credentialEntity.setSalt(credModel.getSalt()); credentialEntity.setDevice(credModel.getDevice()); credentialEntity.setHashIterations(credModel.getHashIterations()); credentialEntity.setCounter(credModel.getCounter()); credentialEntity.setAlgorithm(credModel.getAlgorithm()); credentialEntity.setDigits(credModel.getDigits()); credentialEntity.setPeriod(credModel.getPeriod()); em.flush(); }
@Override public void updateCredential(UserCredentialModel cred) { CredentialEntity credentialEntity = getCredentialEntity(user, cred.getType()); if (credentialEntity == null) { credentialEntity = new CredentialEntity(); credentialEntity.setId(KeycloakModelUtils.generateId()); credentialEntity.setType(cred.getType()); credentialEntity.setDevice(cred.getDevice()); credentialEntity.setUser(user); em.persist(credentialEntity); user.getCredentials().add(credentialEntity); } if (cred.getType().equals(UserCredentialModel.PASSWORD)) { byte[] salt = getSalt(); int hashIterations = 1; PasswordPolicy policy = realm.getPasswordPolicy(); if (policy != null) { hashIterations = policy.getHashIterations(); if (hashIterations == -1) hashIterations = 1; } credentialEntity.setValue( new Pbkdf2PasswordEncoder(salt).encode(cred.getValue(), hashIterations)); credentialEntity.setSalt(salt); credentialEntity.setHashIterations(hashIterations); } else { credentialEntity.setValue(cred.getValue()); } credentialEntity.setDevice(cred.getDevice()); em.flush(); }
protected AccessToken initToken( RealmModel realm, ClientModel client, UserModel user, UserSessionModel session, ClientSessionModel clientSession) { AccessToken token = new AccessToken(); if (clientSession != null) token.clientSession(clientSession.getId()); token.id(KeycloakModelUtils.generateId()); token.subject(user.getId()); token.audience(client.getClientId()); token.issuedNow(); token.issuedFor(client.getClientId()); token.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER)); if (session != null) { token.setSessionState(session.getId()); } if (realm.getAccessTokenLifespan() > 0) { token.expiration(Time.currentTime() + realm.getAccessTokenLifespan()); } Set<String> allowedOrigins = client.getWebOrigins(); if (allowedOrigins != null) { token.setAllowedOrigins(allowedOrigins); } return token; }
@Override public void preprocessFederatedIdentity( KeycloakSession session, RealmModel realm, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String template = mapperModel.getConfig().get(TEMPLATE); Matcher m = substitution.matcher(template); StringBuffer sb = new StringBuffer(); while (m.find()) { String variable = m.group(1); if (variable.equals("ALIAS")) { m.appendReplacement(sb, context.getIdpConfig().getAlias()); } else if (variable.equals("UUID")) { m.appendReplacement(sb, KeycloakModelUtils.generateId()); } else if (variable.startsWith("CLAIM.")) { String name = variable.substring("CLAIM.".length()); Object value = AbstractClaimMapper.getClaimValue(context, name); if (value == null) value = ""; m.appendReplacement(sb, value.toString()); } else { m.appendReplacement(sb, m.group(1)); } } m.appendTail(sb); String username = sb.toString(); context.setModelUsername(username); }
@Override public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { Class<? extends MongoEntity> clazz = entity.getClass(); // Find annotations for ID, for all the properties and for the name of the collection. EntityInfo entityInfo = getEntityInfo(clazz); // Create instance of BasicDBObject and add all declared properties to it (properties with null // value probably should be skipped) BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class); DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName()); String currentId = entity.getId(); // Generate random ID if not set already if (currentId == null) { currentId = KeycloakModelUtils.generateId(); entity.setId(currentId); } // Adding "_id" dbObject.put("_id", currentId); try { dbCollection.insert(dbObject); } catch (MongoException e) { throw convertException(e); } // Treat object as created in this transaction (It is already submited to transaction) context.addCreatedEntity(entity); }
private CredentialEntity setCredentials(UserEntity user, UserCredentialModel cred) { CredentialEntity credentialEntity = new CredentialEntity(); credentialEntity.setId(KeycloakModelUtils.generateId()); credentialEntity.setType(cred.getType()); credentialEntity.setDevice(cred.getDevice()); credentialEntity.setUser(user); return credentialEntity; }
private void persistAttributeValue(String name, String value) { UserAttributeEntity attr = new UserAttributeEntity(); attr.setId(KeycloakModelUtils.generateId()); attr.setName(name); attr.setValue(value); attr.setUser(user); em.persist(attr); user.getAttributes().add(attr); }
private String insertApplicationRole(DBCollection roles, String roleName, String applicationId) { BasicDBObject role = new BasicDBObject(); String roleId = KeycloakModelUtils.generateId(); role.append("_id", roleId); role.append("name", roleName); role.append("applicationId", applicationId); role.append("nameIndex", applicationId + "//" + roleName); roles.insert(role); return roleId; }
public AccessTokenResponseBuilder generateRefreshToken() { if (accessToken == null) { throw new IllegalStateException("accessToken not set"); } refreshToken = new RefreshToken(accessToken); refreshToken.id(KeycloakModelUtils.generateId()); refreshToken.issuedNow(); refreshToken.expiration(Time.currentTime() + realm.getSsoSessionIdleTimeout()); return this; }
@Override public Scope create(final String name, final ResourceServer resourceServer) { ScopeEntity entity = new ScopeEntity(); entity.setId(KeycloakModelUtils.generateId()); entity.setName(name); entity.setResourceServerId(resourceServer.getId()); getMongoStore().insertEntity(entity, getInvocationContext()); return new ScopeAdapter(entity, getInvocationContext(), this.authorizationProvider); }
@Override public Policy create(String name, String type, ResourceServer resourceServer) { PolicyEntity entity = new PolicyEntity(); entity.setId(KeycloakModelUtils.generateId()); entity.setName(name); entity.setType(type); entity.setResourceServerId(resourceServer.getId()); getMongoStore().insertEntity(entity, getInvocationContext()); return new PolicyAdapter(entity, getInvocationContext(), this.authorizationProvider); }
@Override public void addConsent(UserConsentModel consent) { String clientId = consent.getClient().getId(); UserConsentEntity consentEntity = getGrantedConsentEntity(clientId); if (consentEntity != null) { throw new ModelDuplicateException( "Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]"); } consentEntity = new UserConsentEntity(); consentEntity.setId(KeycloakModelUtils.generateId()); consentEntity.setUser(user); consentEntity.setClientId(clientId); em.persist(consentEntity); em.flush(); updateGrantedConsentEntity(consentEntity, consent); }
public AccessTokenResponseBuilder generateIDToken() { if (accessToken == null) { throw new IllegalStateException("accessToken not set"); } idToken = new IDToken(); idToken.id(KeycloakModelUtils.generateId()); idToken.subject(accessToken.getSubject()); idToken.audience(client.getClientId()); idToken.issuedNow(); idToken.issuedFor(accessToken.getIssuedFor()); idToken.issuer(accessToken.getIssuer()); idToken.setSessionState(accessToken.getSessionState()); if (realm.getAccessTokenLifespan() > 0) { idToken.expiration(Time.currentTime() + realm.getAccessTokenLifespan()); } transformIDToken( session, idToken, realm, client, userSession.getUser(), userSession, clientSession); return this; }
private void addDefaultMappers(KeycloakSession session, DBCollection clients) { DBCursor clientsCursor = clients.find(); try { while (clientsCursor.hasNext()) { BasicDBObject currentClient = (BasicDBObject) clientsCursor.next(); BasicDBList dbProtocolMappers = new BasicDBList(); currentClient.put("protocolMappers", dbProtocolMappers); Object claimMask = currentClient.get("allowedClaimsMask"); MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class); List<ProtocolMapperRepresentation> protocolMappers = migrationProvider.getMappersForClaimMask((Long) claimMask); for (ProtocolMapperRepresentation protocolMapper : protocolMappers) { BasicDBObject dbMapper = new BasicDBObject(); dbMapper.put("id", KeycloakModelUtils.generateId()); dbMapper.put("protocol", protocolMapper.getProtocol()); dbMapper.put("name", protocolMapper.getName()); dbMapper.put("consentRequired", protocolMapper.isConsentRequired()); dbMapper.put("consentText", protocolMapper.getConsentText()); dbMapper.put("protocolMapper", protocolMapper.getProtocolMapper()); Map<String, String> config = protocolMapper.getConfig(); BasicDBObject dbConfig = MapMapper.convertMap(config); dbMapper.put("config", dbConfig); dbProtocolMappers.add(dbMapper); } // Remove obsolete keys from client currentClient.remove("allowedClaimsMask"); log.debugv("Added default mappers to application {1}", currentClient.get("name")); clients.save(currentClient); } } finally { clientsCursor.close(); } }
private void addAdminRole( String roleName, String realmId, String applicationId, String realmAdminAppRoleId) { String roleTableName = database.correctObjectName("KEYCLOAK_ROLE", Table.class); String compositeRoleTableName = database.correctObjectName("COMPOSITE_ROLE", Table.class); String newRoleId = KeycloakModelUtils.generateId(); InsertStatement insertRole = new InsertStatement(null, null, roleTableName) .addColumnValue("ID", newRoleId) .addColumnValue("APP_REALM_CONSTRAINT", applicationId) .addColumnValue("APPLICATION_ROLE", true) .addColumnValue("NAME", roleName) .addColumnValue("REALM_ID", realmId) .addColumnValue("APPLICATION", applicationId); // Add newly created role to the composite roles of 'realm-admin' role InsertStatement insertCompRole = new InsertStatement(null, null, compositeRoleTableName) .addColumnValue("COMPOSITE", realmAdminAppRoleId) .addColumnValue("CHILD_ROLE", newRoleId); statements.add(insertRole); statements.add(insertCompRole); }
public void setEmail(String email) { this.email = email; this.emailConstraint = email != null ? email : KeycloakModelUtils.generateId(); }
protected void addDefaultProtocolMappers() throws SQLException, DatabaseException { String protocolMapperTableName = database.correctObjectName("PROTOCOL_MAPPER", Table.class); String protocolMapperCfgTableName = database.correctObjectName("PROTOCOL_MAPPER_CONFIG", Table.class); PreparedStatement statement = jdbcConnection.prepareStatement("select ID, NAME, ALLOWED_CLAIMS_MASK from CLIENT"); try { ResultSet resultSet = statement.executeQuery(); try { boolean first = true; while (resultSet.next()) { if (first) { confirmationMessage.append("Migrating claimsMask to protocol mappers for clients: "); first = false; } Object acmObj = resultSet.getObject("ALLOWED_CLAIMS_MASK"); long mask = (acmObj != null) ? ((Number) acmObj).longValue() : ClaimMask.ALL; MigrationProvider migrationProvider = this.kcSession.getProvider(MigrationProvider.class); List<ProtocolMapperRepresentation> protocolMappers = migrationProvider.getMappersForClaimMask(mask); for (ProtocolMapperRepresentation protocolMapper : protocolMappers) { String mapperId = KeycloakModelUtils.generateId(); InsertStatement insert = new InsertStatement(null, null, protocolMapperTableName) .addColumnValue("ID", mapperId) .addColumnValue("PROTOCOL", protocolMapper.getProtocol()) .addColumnValue("NAME", protocolMapper.getName()) .addColumnValue("CONSENT_REQUIRED", protocolMapper.isConsentRequired()) .addColumnValue("CONSENT_TEXT", protocolMapper.getConsentText()) .addColumnValue("PROTOCOL_MAPPER_NAME", protocolMapper.getProtocolMapper()) .addColumnValue("CLIENT_ID", resultSet.getString("ID")); statements.add(insert); for (Map.Entry<String, String> cfgEntry : protocolMapper.getConfig().entrySet()) { InsertStatement cfgInsert = new InsertStatement(null, null, protocolMapperCfgTableName) .addColumnValue("PROTOCOL_MAPPER_ID", mapperId) .addColumnValue("NAME", cfgEntry.getKey()) .addColumnValue("VALUE", cfgEntry.getValue()); statements.add(cfgInsert); } } confirmationMessage.append(resultSet.getString("NAME") + ", "); } // It means that some provider where processed if (!first) { confirmationMessage.append(". "); } } finally { resultSet.close(); } } finally { statement.close(); } }
protected void convertSocialToIdFedRealms() throws SQLException, DatabaseException { String identityProviderTableName = database.correctObjectName("IDENTITY_PROVIDER", Table.class); String idpConfigTableName = database.correctObjectName("IDENTITY_PROVIDER_CONFIG", Table.class); PreparedStatement statement = jdbcConnection.prepareStatement( "select RSC.NAME, VALUE, REALM_ID, UPDATE_PROFILE_ON_SOC_LOGIN from REALM_SOCIAL_CONFIG RSC,REALM where RSC.REALM_ID = REALM.ID ORDER BY RSC.REALM_ID, RSC.NAME"); try { ResultSet resultSet = statement.executeQuery(); try { boolean providerInProgress = false; String socialProviderId = null; String clientId = null; String clientSecret; String realmId = null; boolean updateProfileOnSocialLogin = false; boolean first = true; while (resultSet.next()) { if (first) { confirmationMessage.append("Migrating social to identity providers: "); first = false; } if (!providerInProgress) { String key = resultSet.getString("NAME"); int keyIndex = key.indexOf(".key"); if (keyIndex == -1) { throw new IllegalStateException("Can't parse the provider from column: " + key); } socialProviderId = key.substring(0, keyIndex); clientId = resultSet.getString("VALUE"); realmId = resultSet.getString("REALM_ID"); updateProfileOnSocialLogin = resultSet.getBoolean("UPDATE_PROFILE_ON_SOC_LOGIN"); providerInProgress = true; } else { clientSecret = resultSet.getString("VALUE"); String internalId = KeycloakModelUtils.generateId(); InsertStatement idpInsert = new InsertStatement(null, null, identityProviderTableName) .addColumnValue("INTERNAL_ID", internalId) .addColumnValue("ENABLED", true) .addColumnValue("PROVIDER_ALIAS", socialProviderId) .addColumnValue("PROVIDER_ID", socialProviderId) .addColumnValue("UPDATE_PROFILE_FIRST_LOGIN", updateProfileOnSocialLogin) .addColumnValue("STORE_TOKEN", false) .addColumnValue("AUTHENTICATE_BY_DEFAULT", false) .addColumnValue("REALM_ID", realmId); InsertStatement clientIdInsert = new InsertStatement(null, null, idpConfigTableName) .addColumnValue("IDENTITY_PROVIDER_ID", internalId) .addColumnValue("NAME", "clientId") .addColumnValue("VALUE", clientId); InsertStatement clientSecretInsert = new InsertStatement(null, null, idpConfigTableName) .addColumnValue("IDENTITY_PROVIDER_ID", internalId) .addColumnValue("NAME", "clientSecret") .addColumnValue("VALUE", clientSecret); statements.add(idpInsert); statements.add(clientIdInsert); statements.add(clientSecretInsert); confirmationMessage.append(socialProviderId + " in realm " + realmId + ", "); providerInProgress = false; } } // It means that some provider where processed if (!first) { confirmationMessage.append(". "); } } finally { resultSet.close(); } } finally { statement.close(); } }
/** * @author <a href="mailto:[email protected]">Bill Burke</a> * @version $Revision: 1 $ */ @NamedQueries({ @NamedQuery( name = "getAllUsersByRealm", query = "select u from UserEntity u where u.realmId = :realmId order by u.username"), @NamedQuery( name = "getAllUsersByRealmExcludeServiceAccount", query = "select u from UserEntity u where u.realmId = :realmId and (u.serviceAccountClientLink is null) order by u.username"), @NamedQuery( name = "searchForUser", query = "select u from UserEntity u where u.realmId = :realmId and (u.serviceAccountClientLink is null) and " + "( lower(u.username) like :search or lower(concat(u.firstName, ' ', u.lastName)) like :search or u.email like :search ) order by u.username"), @NamedQuery( name = "getRealmUserById", query = "select u from UserEntity u where u.id = :id and u.realmId = :realmId"), @NamedQuery( name = "getRealmUserByUsername", query = "select u from UserEntity u where u.username = :username and u.realmId = :realmId"), @NamedQuery( name = "getRealmUserByEmail", query = "select u from UserEntity u where u.email = :email and u.realmId = :realmId"), @NamedQuery( name = "getRealmUserByLastName", query = "select u from UserEntity u where u.lastName = :lastName and u.realmId = :realmId"), @NamedQuery( name = "getRealmUserByFirstLastName", query = "select u from UserEntity u where u.firstName = :first and u.lastName = :last and u.realmId = :realmId"), @NamedQuery( name = "getRealmUserByServiceAccount", query = "select u from UserEntity u where u.serviceAccountClientLink = :clientInternalId and u.realmId = :realmId"), @NamedQuery( name = "getRealmUserCount", query = "select count(u) from UserEntity u where u.realmId = :realmId"), @NamedQuery( name = "deleteUsersByRealm", query = "delete from UserEntity u where u.realmId = :realmId"), @NamedQuery( name = "deleteUsersByRealmAndLink", query = "delete from UserEntity u where u.realmId = :realmId and u.federationLink=:link") }) @Entity @Table( name = "USER_ENTITY", uniqueConstraints = { @UniqueConstraint(columnNames = {"REALM_ID", "USERNAME"}), @UniqueConstraint(columnNames = {"REALM_ID", "EMAIL_CONSTRAINT"}) }) public class UserEntity { @Id @Column(name = "ID", length = 36) @Access( AccessType .PROPERTY) // we do this because relationships often fetch id, but not entity. This // avoids an extra SQL protected String id; @Column(name = "USERNAME") protected String username; @Column(name = "FIRST_NAME") protected String firstName; @Column(name = "CREATED_TIMESTAMP") protected Long createdTimestamp; @Column(name = "LAST_NAME") protected String lastName; @Column(name = "EMAIL") protected String email; @Column(name = "ENABLED") protected boolean enabled; @Column(name = "EMAIL_VERIFIED") protected boolean emailVerified; // Hack just to workaround the fact that on MS-SQL you can't have unique constraint with multiple // NULL values TODO: Find better solution (like unique index with 'where' but that's proprietary) @Column(name = "EMAIL_CONSTRAINT") protected String emailConstraint = KeycloakModelUtils.generateId(); @Column(name = "REALM_ID") protected String realmId; @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "user") protected Collection<UserAttributeEntity> attributes = new ArrayList<UserAttributeEntity>(); @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "user") protected Collection<UserRequiredActionEntity> requiredActions = new ArrayList<UserRequiredActionEntity>(); @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "user") protected Collection<CredentialEntity> credentials = new ArrayList<CredentialEntity>(); @Column(name = "FEDERATION_LINK") protected String federationLink; @Column(name = "SERVICE_ACCOUNT_CLIENT_LINK") protected String serviceAccountClientLink; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Long getCreatedTimestamp() { return createdTimestamp; } public void setCreatedTimestamp(Long timestamp) { createdTimestamp = timestamp; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; this.emailConstraint = email != null ? email : KeycloakModelUtils.generateId(); } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public String getEmailConstraint() { return emailConstraint; } public void setEmailConstraint(String emailConstraint) { this.emailConstraint = emailConstraint; } public boolean isEmailVerified() { return emailVerified; } public void setEmailVerified(boolean emailVerified) { this.emailVerified = emailVerified; } public Collection<UserAttributeEntity> getAttributes() { return attributes; } public void setAttributes(Collection<UserAttributeEntity> attributes) { this.attributes = attributes; } public Collection<UserRequiredActionEntity> getRequiredActions() { return requiredActions; } public void setRequiredActions(Collection<UserRequiredActionEntity> requiredActions) { this.requiredActions = requiredActions; } public String getRealmId() { return realmId; } public void setRealmId(String realmId) { this.realmId = realmId; } public Collection<CredentialEntity> getCredentials() { return credentials; } public void setCredentials(Collection<CredentialEntity> credentials) { this.credentials = credentials; } public String getFederationLink() { return federationLink; } public void setFederationLink(String federationLink) { this.federationLink = federationLink; } public String getServiceAccountClientLink() { return serviceAccountClientLink; } public void setServiceAccountClientLink(String serviceAccountClientLink) { this.serviceAccountClientLink = serviceAccountClientLink; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) return false; if (!(o instanceof UserEntity)) return false; UserEntity that = (UserEntity) o; if (!id.equals(that.id)) return false; return true; } @Override public int hashCode() { return id.hashCode(); } }
private void convertSocialToIdFedRealms() { DBCollection realms = db.getCollection("realms"); DBCursor realmsCursor = realms.find(); try { while (realmsCursor.hasNext()) { BasicDBObject realm = (BasicDBObject) realmsCursor.next(); boolean updateProfileOnInitialSocialLogin = realm.getBoolean("updateProfileOnInitialSocialLogin"); BasicDBObject socialConfig = (BasicDBObject) realm.get("socialConfig"); BasicDBList identityProviders = (BasicDBList) realm.get("identityProviders"); if (identityProviders == null) { identityProviders = new BasicDBList(); realm.put("identityProviders", identityProviders); } if (socialConfig != null) { for (Map.Entry<String, Object> entry : socialConfig.entrySet()) { if (entry.getKey().endsWith("###key")) { String socialProviderId = entry.getKey().substring(0, entry.getKey().indexOf("###")); String clientId = (String) entry.getValue(); String clientSecret = socialConfig.getString(socialProviderId + "###secret"); DBObject identityProviderConfig = new BasicDBObjectBuilder() .add("clientId", clientId) .add("clientSecret", clientSecret) .get(); DBObject identityProvider = new BasicDBObjectBuilder() .add("internalId", KeycloakModelUtils.generateId()) .add("providerId", socialProviderId) .add("alias", socialProviderId) .add("updateProfileFirstLogin", updateProfileOnInitialSocialLogin) .add("enabled", true) .add("storeToken", false) .add("authenticateByDefault", false) .add("config", identityProviderConfig) .get(); identityProviders.add(identityProvider); log.debugv("Converted social provider {0} to identity provider", socialProviderId); } } } // Remove obsolete keys from realm realm.remove("social"); realm.remove("updateProfileOnInitialSocialLogin"); realm.remove("socialConfig"); // Update realm in DB now realms.save(realm); log.debugv( "Social providers of realm {0} converted to identity providers", realm.get("_id")); } } finally { realmsCursor.close(); } }