keycloak-uncached

KEYCLOAK-3451

12/14/2016 6:04:53 PM

Details

diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java
index b7a8b62..8bfb995 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java
@@ -89,6 +89,11 @@ public class SpnegoAuthenticator extends AbstractUsernameFormAuthenticator imple
 
         CredentialValidationOutput output = context.getSession().userCredentialManager().authenticate(context.getSession(), context.getRealm(), spnegoCredential);
 
+        if (output == null) {
+            logger.warn("Received kerberos token, but there is no user storage provider that handles kerberos credentials.");
+            context.attempted();
+            return;
+        }
         if (output.getAuthStatus() == CredentialValidationOutput.Status.AUTHENTICATED) {
             context.setUser(output.getAuthenticatedUser());
             if (output.getState() != null && !output.getState().isEmpty()) {
diff --git a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java
index 0fabb1f..4e2b52a 100644
--- a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java
+++ b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java
@@ -146,7 +146,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser
     protected <T> List<T> getCredentialProviders(RealmModel realm, Class<T> type) {
         List<T> list = new LinkedList<T>();
         for (ProviderFactory f : session.getKeycloakSessionFactory().getProviderFactories(CredentialProvider.class)) {
-            if (!Types.supports(CredentialInputUpdater.class, f, CredentialProviderFactory.class)) continue;
+            if (!Types.supports(type, f, CredentialProviderFactory.class)) continue;
             list.add((T)session.getProvider(CredentialProvider.class, f.getId()));
         }
         return list;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java
index aeb58b2..af4fd22 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KerberosStandaloneTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 import org.junit.runners.MethodSorters;
+import org.keycloak.authentication.authenticators.browser.SpnegoAuthenticator;
 import org.keycloak.common.constants.KerberosConstants;
 import org.keycloak.common.util.MultivaluedHashMap;
 import org.keycloak.federation.kerberos.CommonKerberosConfig;
@@ -45,6 +46,8 @@ import org.keycloak.utils.CredentialHelper;
 import javax.ws.rs.core.Response;
 import java.net.URL;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Test of KerberosFederationProvider (Kerberos not backed by LDAP)
@@ -189,5 +192,58 @@ public class KerberosStandaloneTest extends AbstractKerberosTest {
         }
     }
 
+    /**
+     * KEYCLOAK-3451
+     *
+     * Test that if there is no User Storage Provider that can handle kerberos we can still login
+     *
+     * @throws Exception
+     */
+    @Test
+    public void noProvider() throws Exception {
+        KeycloakSession session = keycloakRule.startSession();
+        try {
+            RealmModel realm = session.realms().getRealm("test");
+            realm.removeComponent(kerberosModel);
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
+        /*
+         To do this we do a valid kerberos login.  The authenticator will obtain a valid token, but there will
+         be no user storage provider that can process it.  This means we should be on the login page.
+         We do this through a JAX-RS client request.  We extract the action URL from the login page, and stuff it
+         into selenium then just perform a regular login.
+         */
+        Response spnegoResponse = spnegoLogin("hnelson", "secret");
+        String context = spnegoResponse.readEntity(String.class);
+        spnegoResponse.close();
+        Pattern pattern = Pattern.compile("action=\"([^\"]+)\"");
+        Matcher m = pattern.matcher(context);
+        Assert.assertTrue(m.find());
+        String url = m.group(1);
+        driver.navigate().to(url);
+        Assert.assertTrue(loginPage.isCurrent());
+        loginPage.login("test-user@localhost", "password");
+        String pageSource = driver.getPageSource();
+        Assert.assertTrue(pageSource.contains("Kerberos Test") && pageSource.contains("Kerberos servlet secured content"));
+
+
+        events.clear();
+        session = keycloakRule.startSession();
+        try {
+            RealmModel realm = session.realms().getRealm("test");
+            realm.addComponentModel(kerberosModel);
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
+
+
+
+
+    }
+
+
+
+
 
 }