keycloak-uncached

Merge pull request #630 from patriot1burke/master expanded

8/14/2014 10:01:26 PM

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 0b11d7e..c9355c8 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -34,6 +34,7 @@ import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.AccessTokenResponse;
 import org.keycloak.representations.RefreshToken;
 import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.ForbiddenException;
 import org.keycloak.services.managers.AccessCode;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
@@ -245,11 +246,6 @@ public class TokenService {
 
         ClientModel client = authorizeClient(authorizationHeader, form, audit);
 
-        if ( (client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
-            audit.error(Errors.NOT_ALLOWED);
-            return createError("not_allowed", "Bearer-only applications are not allowed to invoke grants/access", Response.Status.FORBIDDEN);
-        }
-
         if (!realm.isEnabled()) {
             audit.error(Errors.REALM_DISABLED);
             return createError("realm_disabled", "Realm is disabled", Response.Status.UNAUTHORIZED);
@@ -312,6 +308,9 @@ public class TokenService {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Response validateAccessToken(@QueryParam("access_token") String tokenString) {
+        if (!checkSsl()) {
+            return createError("https_required", "HTTPS required", Response.Status.FORBIDDEN);
+        }
         audit.event(EventType.VALIDATE_ACCESS_TOKEN);
         AccessToken token = null;
         try {
@@ -423,7 +422,7 @@ public class TokenService {
                                        final MultivaluedMap<String, String> form) {
         logger.info("--> refreshAccessToken");
         if (!checkSsl()) {
-            throw new NotAcceptableException("HTTPS required");
+            return createError("https_required", "HTTPS required", Response.Status.FORBIDDEN);
         }
 
         audit.event(EventType.REFRESH_TOKEN);
@@ -716,7 +715,7 @@ public class TokenService {
         logger.debug("accessRequest <---");
 
         if (!checkSsl()) {
-            throw new NotAcceptableException("HTTPS required");
+            throw new ForbiddenException("HTTPS required");
         }
 
         audit.event(EventType.CODE_TO_TOKEN);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 155acb1..d3bb915 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -29,6 +29,10 @@ import org.keycloak.OAuth2Constants;
 import org.keycloak.audit.Details;
 import org.keycloak.audit.Errors;
 import org.keycloak.audit.Event;
+import org.keycloak.enums.SslRequired;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.AccessToken;
@@ -277,13 +281,7 @@ public class AccessTokenTest {
 
         org.keycloak.representations.AccessTokenResponse tokenResponse = null;
         {
-            String header = BasicAuthHelper.createHeader("test-app", "password");
-            Form form = new Form();
-            form.param("username", "test-user@localhost")
-                    .param("password", "password");
-            Response response = grantTarget.request()
-                    .header(HttpHeaders.AUTHORIZATION, header)
-                    .post(Entity.form(form));
+            Response response = executeGrantAccessTokenRequest(grantTarget);
             Assert.assertEquals(200, response.getStatus());
             tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
             response.close();
@@ -320,5 +318,209 @@ public class AccessTokenTest {
 
     }
 
+    @Test
+    public void testGrantAccessToken() throws Exception {
+        Client client = ClientBuilder.newClient();
+        UriBuilder builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
+        URI grantUri = TokenService.grantAccessTokenUrl(builder).build("test");
+        WebTarget grantTarget = client.target(grantUri);
+
+        {   // test checkSsl
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                realm.setSslRequired(SslRequired.ALL);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(403, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                realm.setSslRequired(SslRequired.EXTERNAL);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+
+        {   // test null username
+            String header = BasicAuthHelper.createHeader("test-app", "password");
+            Form form = new Form();
+            form.param("password", "password");
+            Response response = grantTarget.request()
+                    .header(HttpHeaders.AUTHORIZATION, header)
+                    .post(Entity.form(form));
+            Assert.assertEquals(401, response.getStatus());
+            response.close();
+        }
+
+        {   // test no password
+            String header = BasicAuthHelper.createHeader("test-app", "password");
+            Form form = new Form();
+            form.param("username", "test-user@localhost");
+            Response response = grantTarget.request()
+                    .header(HttpHeaders.AUTHORIZATION, header)
+                    .post(Entity.form(form));
+            Assert.assertEquals(400, response.getStatus());
+            response.close();
+        }
+
+        {   // test bearer-only
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                ApplicationModel clientModel = realm.getApplicationByName("test-app");
+                clientModel.setBearerOnly(true);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(400, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                ApplicationModel clientModel = realm.getApplicationByName("test-app");
+                clientModel.setBearerOnly(false);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+
+        {   // test realm disabled
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                realm.setEnabled(false);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(401, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                realm.setEnabled(true);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+
+        {   // test application disabled
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                ClientModel clientModel = realm.findClient("test-app");
+                clientModel.setEnabled(false);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(400, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                ClientModel clientModel = realm.findClient("test-app");
+                clientModel.setEnabled(true);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+
+        {   // test user action required
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
+                user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(400, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
+                user.removeRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+        {   // test user disabled
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
+                user.setEnabled(false);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(400, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
+                user.setEnabled(true);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+
+
+        {
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(200, response.getStatus());
+            org.keycloak.representations.AccessTokenResponse tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
+            response.close();
+        }
+
+        client.close();
+        events.clear();
+
+    }
+
+    protected Response executeGrantAccessTokenRequest(WebTarget grantTarget) {
+        String header = BasicAuthHelper.createHeader("test-app", "password");
+        Form form = new Form();
+        form.param("username", "test-user@localhost")
+                .param("password", "password");
+        return grantTarget.request()
+                .header(HttpHeaders.AUTHORIZATION, header)
+                .post(Entity.form(form));
+    }
+
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java
index 361d0c1..bc1195a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java
@@ -29,8 +29,12 @@ import org.keycloak.OAuth2Constants;
 import org.keycloak.audit.Details;
 import org.keycloak.audit.Errors;
 import org.keycloak.audit.Event;
+import org.keycloak.enums.SslRequired;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.RefreshToken;
@@ -335,6 +339,89 @@ public class RefreshTokenTest {
         events.clear();
     }
 
+    @Test
+    public void testCheckSsl() throws Exception {
+        Client client = ClientBuilder.newClient();
+        UriBuilder builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
+        URI grantUri = TokenService.grantAccessTokenUrl(builder).build("test");
+        WebTarget grantTarget = client.target(grantUri);
+        builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
+        URI uri = TokenService.refreshUrl(builder).build("test");
+        WebTarget refreshTarget = client.target(uri);
+
+        String refreshToken = null;
+        {
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(200, response.getStatus());
+            org.keycloak.representations.AccessTokenResponse tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
+            refreshToken = tokenResponse.getRefreshToken();
+            response.close();
+        }
+
+        {
+            Response response = executeRefreshToken(refreshTarget, refreshToken);
+            Assert.assertEquals(200, response.getStatus());
+            org.keycloak.representations.AccessTokenResponse tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
+            refreshToken = tokenResponse.getRefreshToken();
+            response.close();
+        }
+
+        {   // test checkSsl
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                realm.setSslRequired(SslRequired.ALL);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+            Response response = executeRefreshToken(refreshTarget, refreshToken);
+            Assert.assertEquals(403, response.getStatus());
+            response.close();
+
+            {
+                KeycloakSession session = keycloakRule.startSession();
+                RealmModel realm = session.realms().getRealmByName("test");
+                realm.setSslRequired(SslRequired.EXTERNAL);
+                session.getTransaction().commit();
+                session.close();
+            }
+
+        }
+
+        {
+            Response response = executeRefreshToken(refreshTarget, refreshToken);
+            Assert.assertEquals(200, response.getStatus());
+            org.keycloak.representations.AccessTokenResponse tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
+            refreshToken = tokenResponse.getRefreshToken();
+            response.close();
+        }
+
+
+        client.close();
+        events.clear();
+
+    }
+
+    protected Response executeRefreshToken(WebTarget refreshTarget, String refreshToken) {
+        String header = BasicAuthHelper.createHeader("test-app", "password");
+        Form form = new Form();
+        form.param("refresh_token", refreshToken);
+        return refreshTarget.request()
+                .header(HttpHeaders.AUTHORIZATION, header)
+                .post(Entity.form(form));
+    }
+
+    protected Response executeGrantAccessTokenRequest(WebTarget grantTarget) {
+        String header = BasicAuthHelper.createHeader("test-app", "password");
+        Form form = new Form();
+        form.param("username", "test-user@localhost")
+                .param("password", "password");
+        return grantTarget.request()
+                .header(HttpHeaders.AUTHORIZATION, header)
+                .post(Entity.form(form));
+    }
+
 
 
 }