keycloak-developers

[KEYCLOAK-997] - Redirect directly to provider if password

1/23/2015 6:20:19 PM

Details

diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/UrlBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/UrlBean.java
index 5408a1d..de7e432 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/UrlBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/UrlBean.java
@@ -40,7 +40,7 @@ public class UrlBean {
     }
 
     public String getSocialUrl() {
-        return Urls.accountSocialPage(baseQueryURI, realm).toString();
+        return Urls.accountFederatedIdentityPage(baseQueryURI, realm).toString();
     }
 
     public String getTotpUrl() {
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
index 399fb15..80f29bb 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
@@ -23,9 +23,8 @@ package org.keycloak.login.freemarker.model;
 
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.services.resources.AuthenticationBrokerResource;
+import org.keycloak.services.resources.flows.Urls;
 
-import javax.ws.rs.core.UriBuilder;
 import java.net.URI;
 import java.util.LinkedList;
 import java.util.List;
@@ -49,11 +48,7 @@ public class IdentityProviderBean {
 
             for (IdentityProviderModel identityProvider : identityProviders) {
                 if (identityProvider.isEnabled()) {
-                    String loginUrl = UriBuilder.fromUri(baseURI)
-                            .path(AuthenticationBrokerResource.class)
-                            .path(AuthenticationBrokerResource.class, "performLogin")
-                            .replaceQueryParam("provider_id", identityProvider.getId())
-                            .build(realm.getName()).toString();
+                    String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider, realm).toString();
                     providers.add(new IdentityProvider(identityProvider.getId(), identityProvider.getName(), loginUrl));
                 }
             }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java b/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
index 9b9f8b9..99e1859 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
@@ -25,9 +25,11 @@ import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
+import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.UserSessionProvider;
@@ -70,6 +72,7 @@ import java.io.InputStream;
 import java.net.URI;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -871,8 +874,27 @@ public class OpenIDConnectService {
             return oauth.cancelLogin(clientSession);
         }
 
+        String accessCode = new ClientSessionCode(realm, clientSession).getCode();
+        List<RequiredCredentialModel> requiredCredentials = realm.getRequiredCredentials();
+
+        if (requiredCredentials.isEmpty()) {
+            List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
+
+            if (!identityProviders.isEmpty()) {
+                if (identityProviders.size() == 1) {
+                    return Response.temporaryRedirect(
+                            Urls.identityProviderAuthnRequest(this.uriInfo.getBaseUri(), identityProviders.get(0), this.realm, accessCode))
+                            .build();
+                }
+
+                return Flows.forms(session, realm, null, uriInfo).setError("Realm [" + this.realm.getName() + "] supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.").createErrorPage();
+            }
+
+            return Flows.forms(session, realm, null, uriInfo).setError("Realm [" + this.realm.getName() + "] does not support any credential type.").createErrorPage();
+        }
+
         LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo)
-                .setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode());
+                .setClientSessionCode(accessCode);
 
         String rememberMeUsername = AuthenticationManager.getRememberMeUsername(realm, headers);
 
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index f3f6e9a..00b45ba 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -675,7 +675,7 @@ public class AccountService {
 
         switch (accountSocialAction) {
             case ADD:
-                String redirectUri = UriBuilder.fromUri(Urls.accountSocialPage(uriInfo.getBaseUri(), realm.getName())).build().toString();
+                String redirectUri = UriBuilder.fromUri(Urls.accountFederatedIdentityPage(uriInfo.getBaseUri(), realm.getName())).build().toString();
 
                 try {
                     ClientSessionModel clientSession = auth.getClientSession();
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index 09c4df3..60feca8 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -21,9 +21,13 @@
  */
 package org.keycloak.services.resources.flows;
 
+import org.keycloak.OAuth2Constants;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.oidc.OpenIDConnect;
 import org.keycloak.protocol.oidc.OpenIDConnectService;
 import org.keycloak.services.resources.AccountService;
+import org.keycloak.services.resources.AuthenticationBrokerResource;
 import org.keycloak.services.resources.LoginActionsService;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.ThemeResource;
@@ -56,7 +60,7 @@ public class Urls {
         return accountBase(baseUri).path(AccountService.class, "passwordPage").build(realmId);
     }
 
-    public static URI accountSocialPage(URI baseUri, String realmId) {
+    public static URI accountFederatedIdentityPage(URI baseUri, String realmId) {
         return accountBase(baseUri).path(AccountService.class, "federatedIdentityPage").build(realmId);
     }
 
@@ -64,6 +68,23 @@ public class Urls {
         return accountBase(baseUri).path(AccountService.class, "processFederatedIdentityUpdate").build(realmName);
     }
 
+    public static URI identityProviderAuthnRequest(URI baseURI, IdentityProviderModel identityProvider, RealmModel realm, String accessCode) {
+        UriBuilder uriBuilder = UriBuilder.fromUri(baseURI)
+                .path(AuthenticationBrokerResource.class)
+                .path(AuthenticationBrokerResource.class, "performLogin")
+                .replaceQueryParam("provider_id", identityProvider.getProviderId());
+
+        if (accessCode != null) {
+            uriBuilder.replaceQueryParam(OAuth2Constants.CODE, accessCode);
+        }
+
+        return uriBuilder.build(realm.getName());
+    }
+
+    public static URI identityProviderAuthnRequest(URI baseURI, IdentityProviderModel identityProvider, RealmModel realm) {
+        return identityProviderAuthnRequest(baseURI, identityProvider, realm, null);
+    }
+
     public static URI accountTotpPage(URI baseUri, String realmId) {
         return accountBase(baseUri).path(AccountService.class, "totpPage").build(realmId);
     }