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);
}