keycloak-aplcache

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
index 2466f12..40b5301 100755
--- a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
@@ -25,6 +25,7 @@ import java.util.Map;
 public class IdentityProviderRepresentation {
 
     protected String alias;
+    protected String displayName;
     protected String internalId;
     protected String providerId;
     protected boolean enabled = true;
@@ -176,4 +177,12 @@ public class IdentityProviderRepresentation {
         this.trustEmail = trustEmail;
     }
 
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
index 77ca614..9a94431 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
@@ -59,6 +59,9 @@ public class IdentityProviderEntity {
     @Column(name="PROVIDER_ALIAS")
     private String alias;
 
+    @Column(name="PROVIDER_DISPLAY_NAME")
+    private String displayName;
+
     @Column(name="ENABLED")
     private boolean enabled;
 
@@ -182,6 +185,14 @@ public class IdentityProviderEntity {
         this.trustEmail = trustEmail;
     }
 
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index a5747c6..21aa8d0 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -18,10 +18,9 @@
 package org.keycloak.models.jpa;
 
 import org.jboss.logging.Logger;
+import org.keycloak.common.enums.SslRequired;
 import org.keycloak.common.util.MultivaluedHashMap;
-import org.keycloak.common.util.StringPropertyReplacer;
 import org.keycloak.component.ComponentModel;
-import org.keycloak.common.enums.SslRequired;
 import org.keycloak.jose.jwk.JWKBuilder;
 import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.AuthenticationFlowModel;
@@ -43,12 +42,28 @@ import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserFederationMapperModel;
 import org.keycloak.models.UserFederationProviderCreationEventImpl;
 import org.keycloak.models.UserFederationProviderModel;
-import org.keycloak.models.jpa.entities.*;
+import org.keycloak.models.jpa.entities.AuthenticationExecutionEntity;
+import org.keycloak.models.jpa.entities.AuthenticationFlowEntity;
+import org.keycloak.models.jpa.entities.AuthenticatorConfigEntity;
+import org.keycloak.models.jpa.entities.ClientEntity;
+import org.keycloak.models.jpa.entities.ClientTemplateEntity;
+import org.keycloak.models.jpa.entities.ComponentConfigEntity;
+import org.keycloak.models.jpa.entities.ComponentEntity;
+import org.keycloak.models.jpa.entities.GroupEntity;
+import org.keycloak.models.jpa.entities.IdentityProviderEntity;
+import org.keycloak.models.jpa.entities.IdentityProviderMapperEntity;
+import org.keycloak.models.jpa.entities.RealmAttributeEntity;
+import org.keycloak.models.jpa.entities.RealmAttributes;
+import org.keycloak.models.jpa.entities.RealmEntity;
+import org.keycloak.models.jpa.entities.RequiredActionProviderEntity;
+import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
+import org.keycloak.models.jpa.entities.RoleEntity;
+import org.keycloak.models.jpa.entities.UserFederationMapperEntity;
+import org.keycloak.models.jpa.entities.UserFederationProviderEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
-
 import java.security.Key;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -1255,9 +1270,10 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
         for (IdentityProviderEntity entity: entities) {
             IdentityProviderModel identityProviderModel = new IdentityProviderModel();
-
             identityProviderModel.setProviderId(entity.getProviderId());
             identityProviderModel.setAlias(entity.getAlias());
+            identityProviderModel.setDisplayName(entity.getDisplayName());
+
             identityProviderModel.setInternalId(entity.getInternalId());
             Map<String, String> config = entity.getConfig();
             Map<String, String> copy = new HashMap<>();
@@ -1294,6 +1310,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
         entity.setInternalId(KeycloakModelUtils.generateId());
         entity.setAlias(identityProvider.getAlias());
+        entity.setDisplayName(identityProvider.getDisplayName());
         entity.setProviderId(identityProvider.getProviderId());
         entity.setEnabled(identityProvider.isEnabled());
         entity.setStoreToken(identityProvider.isStoreToken());
@@ -1327,6 +1344,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
         for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
             if (entity.getInternalId().equals(identityProvider.getInternalId())) {
                 entity.setAlias(identityProvider.getAlias());
+                entity.setDisplayName(identityProvider.getDisplayName());
                 entity.setEnabled(identityProvider.isEnabled());
                 entity.setTrustEmail(identityProvider.isTrustEmail());
                 entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml
index 6a3f9fe..a73ee6b 100755
--- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml
+++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml
@@ -33,8 +33,9 @@
 
          <dropColumn tableName="USER_ENTITY" columnName="TOTP" />
 
-
-
+         <addColumn tableName="IDENTITY_PROVIDER">
+             <column name="PROVIDER_DISPLAY_NAME" type="VARCHAR(255)"></column>
+         </addColumn>
      </changeSet>
 
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 86a9001..85592b0 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -21,7 +21,6 @@ import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 
 import org.keycloak.common.util.MultivaluedHashMap;
-import org.keycloak.common.util.StringPropertyReplacer;
 import org.keycloak.component.ComponentModel;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.common.enums.SslRequired;
@@ -914,6 +913,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
 
             identityProviderModel.setProviderId(entity.getProviderId());
             identityProviderModel.setAlias(entity.getAlias());
+            identityProviderModel.setDisplayName(entity.getDisplayName());
             identityProviderModel.setInternalId(entity.getInternalId());
             Map<String, String> config = entity.getConfig();
             Map<String, String> copy = new HashMap<>();
@@ -950,6 +950,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
 
         entity.setInternalId(KeycloakModelUtils.generateId());
         entity.setAlias(identityProvider.getAlias());
+        entity.setDisplayName(identityProvider.getDisplayName());
         entity.setProviderId(identityProvider.getProviderId());
         entity.setEnabled(identityProvider.isEnabled());
         entity.setTrustEmail(identityProvider.isTrustEmail());
@@ -980,6 +981,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
             if (entity.getInternalId().equals(identityProvider.getInternalId())) {
                 entity.setAlias(identityProvider.getAlias());
+                entity.setDisplayName(identityProvider.getDisplayName());
                 entity.setEnabled(identityProvider.isEnabled());
                 entity.setTrustEmail(identityProvider.isTrustEmail());
                 entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
diff --git a/server-spi/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java b/server-spi/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java
index e23198e..b0c39ff 100755
--- a/server-spi/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java
+++ b/server-spi/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java
@@ -26,6 +26,7 @@ public class IdentityProviderEntity {
 
     private String internalId;
     private String alias;
+    private String displayName;
     private String providerId;
     private String name;
     private boolean enabled;
@@ -134,6 +135,14 @@ public class IdentityProviderEntity {
         this.trustEmail = trustEmail;
     }
 
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/server-spi/src/main/java/org/keycloak/models/IdentityProviderModel.java b/server-spi/src/main/java/org/keycloak/models/IdentityProviderModel.java
index 2425c7d..41a1e41 100755
--- a/server-spi/src/main/java/org/keycloak/models/IdentityProviderModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/IdentityProviderModel.java
@@ -57,6 +57,8 @@ public class IdentityProviderModel implements Serializable {
 
     private String postBrokerLoginFlowId;
 
+    private String displayName;
+
     /**
      * <p>A map containing the configuration and properties for a specific identity provider instance and implementation. The items
      * in the map are understood by the identity provider implementation.</p>
@@ -70,6 +72,7 @@ public class IdentityProviderModel implements Serializable {
         this.internalId = model.getInternalId();
         this.providerId = model.getProviderId();
         this.alias = model.getAlias();
+        this.displayName = model.getDisplayName();
         this.config = new HashMap<String, String>(model.getConfig());
         this.enabled = model.isEnabled();
         this.trustEmail = model.isTrustEmail();
@@ -169,5 +172,13 @@ public class IdentityProviderModel implements Serializable {
     public void setTrustEmail(boolean trustEmail) {
         this.trustEmail = trustEmail;
     }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
     
 }
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index b8adc62..4c1a4bb 100755
--- a/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -18,6 +18,8 @@
 package org.keycloak.models.utils;
 
 import org.bouncycastle.openssl.PEMWriter;
+import org.keycloak.broker.social.SocialIdentityProvider;
+import org.keycloak.broker.social.SocialIdentityProviderFactory;
 import org.keycloak.common.util.Base64Url;
 import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.AuthenticationFlowModel;
@@ -47,8 +49,6 @@ import org.keycloak.common.util.PemUtils;
 import org.keycloak.transaction.JtaTransactionManagerLookup;
 
 import javax.crypto.spec.SecretKeySpec;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
 import javax.transaction.InvalidTransactionException;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
@@ -62,7 +62,6 @@ import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.SecureRandom;
 import java.security.cert.X509Certificate;
-import java.sql.DriverManager;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -70,7 +69,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import java.util.function.Function;
 
 /**
  * Set of helper methods, which are useful in various model implementations.
@@ -689,4 +687,21 @@ public final class KeycloakModelUtils {
         }
 
     }
+
+    public static String getIdentityProviderDisplayName(KeycloakSession session, IdentityProviderModel provider) {
+        String displayName = provider.getDisplayName();
+        if (displayName != null && !displayName.isEmpty()) {
+            return displayName;
+        }
+
+        SocialIdentityProviderFactory providerFactory = (SocialIdentityProviderFactory) session.getKeycloakSessionFactory()
+                .getProviderFactory(SocialIdentityProvider.class, provider.getProviderId());
+        if (providerFactory != null) {
+            return providerFactory.getName();
+        } else {
+            return provider.getAlias();
+        }
+    }
+
+
 }
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 659c116..e5e888d 100755
--- a/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -627,6 +627,7 @@ public class ModelToRepresentation {
         providerRep.setInternalId(identityProviderModel.getInternalId());
         providerRep.setProviderId(identityProviderModel.getProviderId());
         providerRep.setAlias(identityProviderModel.getAlias());
+        providerRep.setDisplayName(identityProviderModel.getDisplayName());
         providerRep.setEnabled(identityProviderModel.isEnabled());
         providerRep.setStoreToken(identityProviderModel.isStoreToken());
         providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index f228bc7..4cfdfd0 100755
--- a/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -1524,6 +1524,7 @@ public class RepresentationToModel {
 
         identityProviderModel.setInternalId(representation.getInternalId());
         identityProviderModel.setAlias(representation.getAlias());
+        identityProviderModel.setDisplayName(representation.getDisplayName());
         identityProviderModel.setProviderId(representation.getProviderId());
         identityProviderModel.setEnabled(representation.isEnabled());
         identityProviderModel.setTrustEmail(representation.isTrustEmail());
diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/model/AccountFederatedIdentityBean.java b/services/src/main/java/org/keycloak/forms/account/freemarker/model/AccountFederatedIdentityBean.java
index a20810e..3c63de2 100755
--- a/services/src/main/java/org/keycloak/forms/account/freemarker/model/AccountFederatedIdentityBean.java
+++ b/services/src/main/java/org/keycloak/forms/account/freemarker/model/AccountFederatedIdentityBean.java
@@ -22,6 +22,7 @@ import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.services.resources.AccountService;
 import org.keycloak.services.Urls;
 
@@ -70,7 +71,8 @@ public class AccountFederatedIdentityBean {
                         .queryParam("stateChecker", stateChecker)
                         .build().toString();
 
-                FederatedIdentityEntry entry = new FederatedIdentityEntry(identity, provider.getAlias(), provider.getAlias(), actionUrl,
+                String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session, provider);
+                FederatedIdentityEntry entry = new FederatedIdentityEntry(identity, displayName, provider.getAlias(), provider.getAlias(), actionUrl,
                 		  															provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null);
                 orderedSet.add(entry);
             }
@@ -106,10 +108,12 @@ public class AccountFederatedIdentityBean {
 		private final String providerName;
         private final String actionUrl;
         private final String guiOrder;
+        private final String displayName;
 
-		public FederatedIdentityEntry(FederatedIdentityModel federatedIdentityModel, String providerId, String providerName, String actionUrl, String guiOrder
-				) {
+        public FederatedIdentityEntry(FederatedIdentityModel federatedIdentityModel, String displayName, String providerId,
+                                      String providerName, String actionUrl, String guiOrder) {
             this.federatedIdentityModel = federatedIdentityModel;
+            this.displayName = displayName;
             this.providerId = providerId;
             this.providerName = providerName;
             this.actionUrl = actionUrl;
@@ -143,6 +147,11 @@ public class AccountFederatedIdentityBean {
         public String getGuiOrder() {
             return guiOrder;
         }
+
+        public String getDisplayName() {
+            return displayName;
+        }
+
     }
     
 	public static class IdentityProviderComparator implements Comparator<FederatedIdentityEntry> {
diff --git a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
index 631ff57..515ab76 100755
--- a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
+++ b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
@@ -250,7 +250,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
 
             List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
             identityProviders = LoginFormsUtil.filterIdentityProviders(identityProviders, session, realm, attributes, formData);
-            attributes.put("social", new IdentityProviderBean(realm, identityProviders, baseUri, uriInfo));
+            attributes.put("social", new IdentityProviderBean(realm, session, identityProviders, baseUri, uriInfo));
 
             attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
 
@@ -398,7 +398,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
 
             List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
             identityProviders = LoginFormsUtil.filterIdentityProviders(identityProviders, session, realm, attributes, formData);
-            attributes.put("social", new IdentityProviderBean(realm, identityProviders, baseUri, uriInfo));
+            attributes.put("social", new IdentityProviderBean(realm, session, identityProviders, baseUri, uriInfo));
 
             attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
             attributes.put("requiredActionUrl", new RequiredActionUrlFormatterMethod(realm, baseUri));
@@ -425,7 +425,6 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
         }
     }
 
-
     @Override
     public Response createLogin() {
         return createResponse(LoginFormsPages.LOGIN);
diff --git a/services/src/main/java/org/keycloak/forms/login/freemarker/model/IdentityProviderBean.java b/services/src/main/java/org/keycloak/forms/login/freemarker/model/IdentityProviderBean.java
index 8301660..87b935a 100755
--- a/services/src/main/java/org/keycloak/forms/login/freemarker/model/IdentityProviderBean.java
+++ b/services/src/main/java/org/keycloak/forms/login/freemarker/model/IdentityProviderBean.java
@@ -17,7 +17,9 @@
 package org.keycloak.forms.login.freemarker.model;
 
 import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.services.Urls;
 
 import javax.ws.rs.core.UriInfo;
@@ -35,12 +37,13 @@ import java.util.TreeSet;
 public class IdentityProviderBean {
 
     private boolean displaySocial;
-
     private List<IdentityProvider> providers;
     private RealmModel realm;
+    private final KeycloakSession session;
 
-    public IdentityProviderBean(RealmModel realm, List<IdentityProviderModel> identityProviders, URI baseURI, UriInfo uriInfo) {
+    public IdentityProviderBean(RealmModel realm, KeycloakSession session, List<IdentityProviderModel> identityProviders, URI baseURI, UriInfo uriInfo) {
         this.realm = realm;
+        this.session = session;
 
         if (!identityProviders.isEmpty()) {
             Set<IdentityProvider> orderedSet = new TreeSet<>(IdentityProviderComparator.INSTANCE);
@@ -59,7 +62,10 @@ public class IdentityProviderBean {
 
     private void addIdentityProvider(Set<IdentityProvider> orderedSet, RealmModel realm, URI baseURI, IdentityProviderModel identityProvider) {
         String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider.getAlias(), realm.getName()).toString();
-        orderedSet.add(new IdentityProvider(identityProvider.getAlias(), identityProvider.getProviderId(), loginUrl,
+        String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session, identityProvider);
+
+        orderedSet.add(new IdentityProvider(identityProvider.getAlias(),
+                displayName, identityProvider.getProviderId(), loginUrl,
                 identityProvider.getConfig() != null ? identityProvider.getConfig().get("guiOrder") : null));
     }
 
@@ -77,9 +83,11 @@ public class IdentityProviderBean {
         private final String providerId; // This refer to providerType (facebook, google, etc.)
         private final String loginUrl;
         private final String guiOrder;
+        private final String displayName;
 
-        public IdentityProvider(String alias, String providerId, String loginUrl, String guiOrder) {
+        public IdentityProvider(String alias, String displayName, String providerId, String loginUrl, String guiOrder) {
             this.alias = alias;
+            this.displayName = displayName;
             this.providerId = providerId;
             this.loginUrl = loginUrl;
             this.guiOrder = guiOrder;
@@ -100,6 +108,10 @@ public class IdentityProviderBean {
         public String getGuiOrder() {
             return guiOrder;
         }
+
+        public String getDisplayName() {
+            return displayName;
+        }
     }
 
     public static class IdentityProviderComparator implements Comparator<IdentityProvider> {
@@ -112,7 +124,7 @@ public class IdentityProviderBean {
 
         @Override
         public int compare(IdentityProvider o1, IdentityProvider o2) {
-            
+
             int o1order = parseOrder(o1);
             int o2order = parseOrder(o2);
 
@@ -120,7 +132,7 @@ public class IdentityProviderBean {
                 return 1;
             else if (o1order < o2order)
                 return -1;
-            
+
             return 1;
         }
 
@@ -134,6 +146,5 @@ public class IdentityProviderBean {
             }
             return 10000;
         }
-
     }
 }
diff --git a/services/src/test/java/org/keycloak/test/login/freemarker/model/IdentityProviderBeanTest.java b/services/src/test/java/org/keycloak/test/login/freemarker/model/IdentityProviderBeanTest.java
index ff4c368..0598ef6 100755
--- a/services/src/test/java/org/keycloak/test/login/freemarker/model/IdentityProviderBeanTest.java
+++ b/services/src/test/java/org/keycloak/test/login/freemarker/model/IdentityProviderBeanTest.java
@@ -32,32 +32,32 @@ public class IdentityProviderBeanTest {
     @Test
     public void testIdentityProviderComparator() {
 
-        IdentityProvider o1 = new IdentityProvider("alias1", "id1", "ur1", null);
-        IdentityProvider o2 = new IdentityProvider("alias2", "id2", "ur2", null);
+        IdentityProvider o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", null);
+        IdentityProvider o2 = new IdentityProvider("alias2", "displayName2", "id2", "ur2", null);
 
         // guiOrder not defined at any object - first is always lower
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
 
         // guiOrder is not a number so it is same as not defined - first is always lower
-        o1 = new IdentityProvider("alias1", "id1", "ur1", "not a number");
+        o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "not a number");
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
 
         // guiOrder is defined for one only to it is always first
-        o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
+        o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "0");
         Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
 
         // guiOrder is defined for both but is same - first is always lower
-        o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
-        o2 = new IdentityProvider("alias2", "id2", "ur2", "0");
+        o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "0");
+        o2 = new IdentityProvider("alias2", "displayName2", "id2", "ur2", "0");
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
 
         // guiOrder is reflected
-        o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
-        o2 = new IdentityProvider("alias2", "id2", "ur2", "1");
+        o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "0");
+        o2 = new IdentityProvider("alias2", "displayName2", "id2", "ur2", "1");
         Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
         Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
 
diff --git a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
index dba9c15..ab70714 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
@@ -94,6 +94,7 @@
         {
             "alias" : "model-saml-signed-idp",
             "providerId" : "saml",
+            "displayName": "My SAML",
             "enabled": true,
             "config": {
                 "singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
@@ -157,6 +158,7 @@
         {
             "alias" : "model-oidc-idp",
             "providerId" : "oidc",
+            "displayName": "My OIDC",
             "enabled": false,
             "authenticateByDefault" : "false",
             "config": {
@@ -172,6 +174,7 @@
         {
             "alias" : "kc-oidc-idp",
             "providerId" : "keycloak-oidc",
+            "displayName": "My Keycloak OIDC",
             "enabled": true,
             "storeToken" : true,
             "addReadTokenRoleOnCreate": true,
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 35d11d1..881b8b5 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -38,6 +38,7 @@ import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.ErrorPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.util.IdentityProviderBuilder;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 
@@ -75,6 +76,20 @@ public class AccountTest extends TestRealmKeycloakTest {
                                               .password("password")
                                               .build();
 
+        testRealm.addIdentityProvider(IdentityProviderBuilder.create()
+                                              .providerId("github")
+                                              .alias("github")
+                                              .build());
+        testRealm.addIdentityProvider(IdentityProviderBuilder.create()
+                                              .providerId("saml")
+                                              .alias("mysaml")
+                                              .build());
+        testRealm.addIdentityProvider(IdentityProviderBuilder.create()
+                                              .providerId("oidc")
+                                              .alias("myoidc")
+                                              .displayName("MyOIDC")
+                                              .build());
+
         RealmBuilder.edit(testRealm)
                     .user(user2);
     }
@@ -790,4 +805,13 @@ public class AccountTest extends TestRealmKeycloakTest {
         events.clear();
     }
 
+    @Test
+    public void testIdentityProviderCapitalization(){
+        loginPage.open();
+        Assert.assertEquals("GitHub", loginPage.findSocialButton("github").getText());
+        Assert.assertEquals("mysaml", loginPage.findSocialButton("mysaml").getText());
+        Assert.assertEquals("MyOIDC", loginPage.findSocialButton("myoidc").getText());
+
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java
index e538dcc..5d51db4 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java
@@ -20,9 +20,6 @@ package org.keycloak.testsuite.admin;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -31,16 +28,12 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.events.log.JBossLoggingEventListenerProviderFactory;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.TestRealmKeycloakTest;
 import org.keycloak.testsuite.events.EventsListenerProviderFactory;
 import org.keycloak.testsuite.util.AssertAdminEvents;
 import org.keycloak.util.JsonSerialization;
 
-import static org.junit.Assert.assertArrayEquals;
-
 /**
  * This class adapts the functionality from the old testsuite to make tests
  * easier to port.
@@ -109,4 +102,4 @@ public abstract class AbstractAdminTest extends TestRealmKeycloakTest  {
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java
index fb0a863..8407610 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java
@@ -205,6 +205,7 @@ public class ConsentsTest extends AbstractKeycloakTest {
         IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
 
         identityProviderRepresentation.setAlias(alias);
+        identityProviderRepresentation.setDisplayName(providerId);
         identityProviderRepresentation.setProviderId(providerId);
         identityProviderRepresentation.setEnabled(true);
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
index b9102e1..834fc36 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
@@ -177,6 +177,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
         IdentityProviderRepresentation idp = new IdentityProviderRepresentation();
 
         idp.setAlias(id);
+        idp.setDisplayName(id);
         idp.setProviderId(providerId);
         idp.setEnabled(true);
         if (config != null) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
index b6fca90..a0ed2c1 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
@@ -1440,7 +1440,8 @@ public class PermissionsTest extends AbstractKeycloakTest {
         }, Resource.IDENTITY_PROVIDER, false);
         invoke(new InvocationWithResponse() {
             public void invoke(RealmResource realm, AtomicReference<Response> response) {
-                response.set(realm.identityProviders().create(IdentityProviderBuilder.create().providerId("nosuch").alias("foo").build()));
+                response.set(realm.identityProviders().create(IdentityProviderBuilder.create().providerId("nosuch")
+                        .displayName("nosuch-foo").alias("foo").build()));
             }
         }, Resource.IDENTITY_PROVIDER, true);
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
index 29f796f..cff2005 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
@@ -126,6 +126,7 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
         IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
 
         identityProviderRepresentation.setAlias(alias);
+        identityProviderRepresentation.setDisplayName(providerId);
         identityProviderRepresentation.setProviderId(providerId);
         identityProviderRepresentation.setEnabled(true);
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java
index 2cd04fa..c1eb4f3 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java
@@ -23,10 +23,12 @@ import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
 import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.adapters.HttpClientBuilder;
+import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.pages.LoginPage;
 
 import javax.ws.rs.core.Response;
 import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.util.IdentityProviderBuilder;
 
 /**
  * @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
@@ -37,6 +39,24 @@ public class LoginPageTest extends AbstractI18NTest {
     @Page
     protected LoginPage loginPage;
 
+    @Override
+    public void configureTestRealm(RealmRepresentation testRealm) {
+        testRealm.addIdentityProvider(IdentityProviderBuilder.create()
+                .providerId("github")
+                .alias("github")
+                .build());
+        testRealm.addIdentityProvider(IdentityProviderBuilder.create()
+                .providerId("saml")
+                .alias("mysaml")
+                .build());
+        testRealm.addIdentityProvider(IdentityProviderBuilder.create()
+                .providerId("oidc")
+                .alias("myoidc")
+                .displayName("MyOIDC")
+                .build());
+
+    }
+
     @Test
     public void languageDropdown() {
         loginPage.open();
@@ -87,4 +107,13 @@ public class LoginPageTest extends AbstractI18NTest {
         response = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get();
         Assert.assertTrue(response.readEntity(String.class).contains("Log in to test"));
     }
+
+    @Test
+    public void testIdentityProviderCapitalization(){
+        loginPage.open();
+        Assert.assertEquals("GitHub", loginPage.findSocialButton("github").getText());
+        Assert.assertEquals("mysaml", loginPage.findSocialButton("mysaml").getText());
+        Assert.assertEquals("MyOIDC", loginPage.findSocialButton("myoidc").getText());
+
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java
index bc3dae6..7cb1446 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java
@@ -44,6 +44,11 @@ public class IdentityProviderBuilder {
         return this;
     }
 
+    public IdentityProviderBuilder displayName(String displayName) {
+        rep.setDisplayName(displayName);
+        return this;
+    }
+
     public IdentityProviderRepresentation build() {
         return rep;
     }
diff --git a/themes/src/main/resources/theme/base/account/federatedIdentity.ftl b/themes/src/main/resources/theme/base/account/federatedIdentity.ftl
index 3a18805..9a90173 100755
--- a/themes/src/main/resources/theme/base/account/federatedIdentity.ftl
+++ b/themes/src/main/resources/theme/base/account/federatedIdentity.ftl
@@ -11,7 +11,7 @@
         <#list federatedIdentity.identities as identity>
             <div class="form-group">
                 <div class="col-sm-2 col-md-2">
-                    <label for="${identity.providerId!}" class="control-label">${identity.providerName!}</label>
+                    <label for="${identity.providerId!}" class="control-label">${identity.displayName!}</label>
                 </div>
                 <div class="col-sm-5 col-md-5">
                     <input disabled="true" class="form-control" value="${identity.userName!}">
diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index d3cdd9e..4857924 100644
--- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
+++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -418,7 +418,9 @@ post-broker-login-flow=Post Login Flow
 redirect-uri=Redirect URI
 redirect-uri.tooltip=The redirect uri to use when configuring the identity provider.
 alias=Alias
+display-name=Display Name
 identity-provider.alias.tooltip=The alias uniquely identifies an identity provider and it is also used to build the redirect uri.
+identity-provider.display-name.tooltip=Friendly name for Identity Providers.
 identity-provider.enabled.tooltip=Enable/disable this identity provider.
 authenticate-by-default=Authenticate by Default
 identity-provider.authenticate-by-default.tooltip=Indicates if this provider should be tried by default for authentication even before displaying login screen.
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
old mode 100755
new mode 100644
index 5db9cf0..4b5b839
--- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -768,11 +768,19 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
     if (instance && instance.alias) {
         $scope.identityProvider = angular.copy(instance);
         $scope.newIdentityProvider = false;
+        for (var i in serverInfo.identityProviders) {
+            var provider = serverInfo.identityProviders[i];
+
+            if (provider.id == instance.providerId) {
+                $scope.provider = provider;
+            }
+        }
     } else {
         $scope.identityProvider = {};
         $scope.identityProvider.config = {};
         $scope.identityProvider.alias = providerFactory.id;
         $scope.identityProvider.providerId = providerFactory.id;
+
         $scope.identityProvider.enabled = true;
         $scope.identityProvider.authenticateByDefault = false;
         $scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
@@ -836,7 +844,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
         }
     }
 
-
     $scope.uploadFile = function() {
         if (!$scope.identityProvider.alias) {
             Notifications.error("You must specify an alias");
@@ -906,13 +913,12 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
 
                 for (var i in $scope.allProviders) {
                     var provider = $scope.allProviders[i];
-
-                    if (provider.groupName == 'Social' && (provider.id == configProvidedId)) {
-                        $scope.allProviders.splice(i, 1);
-                        break;
+                    if (provider.id == configProvidedId) {
+                        configuredProviders[j].provider = provider;
                     }
                 }
             }
+            $scope.configuredProviders = angular.copy(configuredProviders);
         }
     }, true);
 
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html
index cd2964d..a7c54f8 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html
@@ -1,7 +1,7 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
     <ol class="breadcrumb">
         <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
-        <li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a></li>
+        <li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.displayName}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/identity-provider-mappers/{{identityProvider.alias}}/mappers">{{:: 'identity-provider-mappers' | translate}}</a></li>
         <li class="active" data-ng-show="create">{{:: 'create-identity-provider-mapper' | translate}}</li>
         <li class="active" data-ng-hide="create">{{mapper.name|capitalize}}</li>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html b/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html
index a2f7eff..89bea67 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html
@@ -1,7 +1,7 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
     <ol class="breadcrumb">
         <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
-        <li>{{identityProvider.alias}}</li>
+        <li>{{identityProvider.displayName}}</li>
     </ol>
 
     <kc-tabs-identity-provider></kc-tabs-identity-provider>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
index 2f5ed40..0de7894 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
@@ -54,7 +54,11 @@
                     <tbody>
                     <tr ng-repeat="identityProvider in configuredProviders">
                         <td>
-                            <a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a>
+                            <a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">
+                                <span data-ng-show="identityProvider.displayName">{{identityProvider.displayName}}</span>
+                                <span data-ng-show="!identityProvider.displayName && identityProvider.provider.groupName == 'Social'">{{identityProvider.provider.name}}</span>
+                                <span data-ng-show="!identityProvider.displayName && identityProvider.provider.groupName != 'Social'">{{identityProvider.alias}}</span>
+                            </a>
                         </td>
                         <td>{{identityProvider.providerId}}</td>
                         <td translate="{{identityProvider.enabled}}"></td>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html
index 3e483f7..78645d2 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html
@@ -1,7 +1,7 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initProvider()">
     <ol class="breadcrumb">
         <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
-        <li>{{identityProvider.alias}}</li>
+        <li>{{identityProvider.displayName}}</li>
     </ol>
 
     <kc-tabs-identity-provider></kc-tabs-identity-provider>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
index bbbf9b9..aceae0a 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
@@ -1,7 +1,9 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
     <ol class="breadcrumb">
         <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
-        <li>{{identityProvider.alias}}</li>
+        <li data-ng-show="!newIdentityProvider && identityProvider.displayName">{{identityProvider.displayName}}</li>
+        <li data-ng-show="!newIdentityProvider && !identityProvider.displayName">{{identityProvider.alias}}</li>
+        <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li>
     </ol>
 
     <kc-tabs-identity-provider></kc-tabs-identity-provider>
@@ -27,6 +29,13 @@
                 </div>
                 <kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip>
             </div>
+            <div class="form-group clearfix">
+                <label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label>
+                <div class="col-md-6">
+                    <input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName">
+                </div>
+                <kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip>
+            </div>
             <div class="form-group">
                 <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label>
                 <div class="col-md-6">
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
index eaf4439..0ed66c6 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
@@ -1,7 +1,9 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initSamlProvider()">
     <ol class="breadcrumb">
         <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
-        <li>{{identityProvider.alias}}</li>
+        <li data-ng-show="!newIdentityProvider && identityProvider.displayName">{{identityProvider.displayName}}</li>
+        <li data-ng-show="!newIdentityProvider && !identityProvider.displayName">{{identityProvider.alias}}</li>
+        <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li>
     </ol>
 
     <kc-tabs-identity-provider></kc-tabs-identity-provider>
@@ -24,6 +26,13 @@
                 </div>
                 <kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip>
             </div>
+            <div class="form-group clearfix">
+                <label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label>
+                <div class="col-md-6">
+                    <input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName">
+                </div>
+                <kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip>
+            </div>
             <div class="form-group">
                 <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label>
                 <div class="col-md-6">
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
index 6c7ceb7..2c51dd5 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
@@ -1,7 +1,8 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
     <ol class="breadcrumb">
         <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
-        <li>{{identityProvider.alias}}</li>
+        <li data-ng-hide="newIdentityProvider">{{provider.name}}</li>
+        <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li>
     </ol>
 
     <kc-tabs-identity-provider></kc-tabs-identity-provider>
diff --git a/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-identity-provider.html b/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-identity-provider.html
index 0195f10..279e598 100644
--- a/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-identity-provider.html
+++ b/themes/src/main/resources/theme/base/admin/resources/templates/kc-tabs-identity-provider.html
@@ -1,6 +1,9 @@
 <div data-ng-controller="IdentityProviderTabCtrl">
     <h1 data-ng-hide="path[0] == 'create'">
-        {{identityProvider.alias|capitalize}}
+        <span data-ng-show="identityProvider.displayName">{{identityProvider.displayName}}</span>
+        <span data-ng-show="!identityProvider.displayName && provider.groupName == 'Social'">{{provider.name}}</span>
+        <span data-ng-show="!identityProvider.displayName && provider.groupName != 'Social'">{{identityProvider.alias}}</span>
+
         <i class="pficon pficon-delete clickable" data-ng-hide="newIdentityProvider || changed" data-ng-click="removeIdentityProvider()"></i>
     </h1>
     <h1 data-ng-show="path[0] == 'create'">{{:: 'add-identity-provider' | translate}}</h1>
diff --git a/themes/src/main/resources/theme/base/login/login.ftl b/themes/src/main/resources/theme/base/login/login.ftl
index 3f70f0c..ab4b363 100755
--- a/themes/src/main/resources/theme/base/login/login.ftl
+++ b/themes/src/main/resources/theme/base/login/login.ftl
@@ -70,7 +70,7 @@
             <div id="kc-social-providers">
                 <ul>
                     <#list social.providers as p>
-                        <li><a href="${p.loginUrl}" id="zocial-${p.alias}" class="zocial ${p.providerId}"> <span class="text">${p.alias}</span></a></li>
+                        <li><a href="${p.loginUrl}" id="zocial-${p.alias}" class="zocial ${p.providerId}"> <span class="text">${p.displayName}</span></a></li>
                     </#list>
                 </ul>
             </div>
diff --git a/themes/src/main/resources/theme/keycloak/login/resources/css/login.css b/themes/src/main/resources/theme/keycloak/login/resources/css/login.css
index 8d702d9..0ed51ac 100644
--- a/themes/src/main/resources/theme/keycloak/login/resources/css/login.css
+++ b/themes/src/main/resources/theme/keycloak/login/resources/css/login.css
@@ -229,9 +229,6 @@ ol#kc-totp-settings li:first-of-type {
 .zocial.google {
     background-color: #dd4b39 !important;
 }
-.zocial.google .text:after {
-    content: "+";
-}
 
 .zocial.facebook:hover,
 .zocial.github:hover,