Handled scopes & added request token with authorization code tests.
Change-Id: I775141b8b94bf2d1c86ad873807fcb1b12f3914f
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java b/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
index 619b795..246e14e 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
@@ -11,6 +11,7 @@
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AbstractRefreshableWebApplicationContext;
import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
@@ -72,8 +73,9 @@
return new WebAppDescriptor.Builder(classPackages)
.servletClass(SpringServlet.class)
.contextListenerClass(StaticContextLoaderListener.class)
- // .contextParam("contextConfigLocation",
- // "classpath:test-config.xml")
+// .contextListenerClass(ContextLoaderListener.class)
+// .contextParam("contextConfigLocation",
+// "classpath:test-config.xml")
.build();
}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
index ca4d0ee..216d7a1 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
@@ -18,12 +18,14 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.net.HttpHeaders;
import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.uri.UriComponent;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
import de.ids_mannheim.korap.config.Attributes;
import de.ids_mannheim.korap.config.SpringJerseyTest;
import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
import de.ids_mannheim.korap.utils.JsonUtils;
/**
@@ -34,7 +36,7 @@
@Autowired
private HttpAuthorizationHandler handler;
-
+
private ClientResponse requestAuthorizationConfidentialClient (
MultivaluedMap<String, String> form) throws KustvaktException {
@@ -127,6 +129,25 @@
node.at("/error_description").asText());
}
+ @Test
+ public void testAuthorizeInvalidScope () throws KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("response_type", "code");
+ form.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ form.add("username", "dory");
+ form.add("password", "password");
+ form.add("scope", "read_address");
+
+ ClientResponse response = requestAuthorizationConfidentialClient(form);
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuth2Error.INVALID_SCOPE, node.at("/error").asText());
+ assertEquals("read_address is an invalid scope",
+ node.at("/error_description").asText());
+ }
+
private ClientResponse requestToken (MultivaluedMap<String, String> form)
throws KustvaktException {
return resource().path("oauth2").path("token")
@@ -139,24 +160,30 @@
@Test
public void testRequestTokenAuthorizationConfidential ()
throws KustvaktException {
-
+
MultivaluedMap<String, String> authForm = new MultivaluedMapImpl();
authForm.add("response_type", "code");
authForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
authForm.add("username", "dory");
authForm.add("password", "password");
authForm.add("scope", "read_username");
-
- ClientResponse response = requestAuthorizationConfidentialClient(authForm);
+
+ ClientResponse response =
+ requestAuthorizationConfidentialClient(authForm);
URI redirectUri = response.getLocation();
- String code = redirectUri.getQuery().split("=")[1];
-
+ MultivaluedMap<String, String> params =
+ UriComponent.decodeQuery(redirectUri, true);
+ String code = params.get("code").get(0);
+ String scopes = params.get("scope").get(0);
+
+ assertEquals(scopes, "read_username");
+
MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
tokenForm.add("grant_type", "authorization_code");
tokenForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
tokenForm.add("client_secret", "secret");
tokenForm.add("code", code);
-
+
response = requestToken(tokenForm);
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
@@ -165,8 +192,115 @@
assertEquals(TokenType.BEARER.toString(),
node.at("/token_type").asText());
assertNotNull(node.at("/expires_in").asText());
+
+ testRequestTokenWithUsedAuthorization(tokenForm);
}
-
+
+ private void testRequestTokenWithUsedAuthorization (
+ MultivaluedMap<String, String> form) throws KustvaktException {
+ ClientResponse response = requestToken(form);
+ String entity = response.getEntity(String.class);
+
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuthError.TokenResponse.INVALID_GRANT,
+ node.at("/error").asText());
+ assertEquals("Invalid authorization",
+ node.at("/error_description").asText());
+ }
+
+ @Test
+ public void testRequestTokenInvalidAuthorizationCode ()
+ throws KustvaktException {
+ MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
+ tokenForm.add("grant_type", "authorization_code");
+ tokenForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ tokenForm.add("client_secret", "secret");
+ tokenForm.add("code", "blahblah");
+
+ ClientResponse response = requestToken(tokenForm);
+ String entity = response.getEntity(String.class);
+
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
+ node.at("/error").asText());
+ }
+
+ @Test
+ public void testRequestTokenAuthorizationReplyAttack ()
+ throws KustvaktException {
+ String uri = "https://korap.ids-mannheim.de/confidential/redirect";
+ MultivaluedMap<String, String> authForm = new MultivaluedMapImpl();
+ authForm.add("response_type", "code");
+ authForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ authForm.add("username", "dory");
+ authForm.add("password", "password");
+ authForm.add("scope", "read_username");
+ authForm.add("redirect_uri", uri);
+
+ ClientResponse response =
+ requestAuthorizationConfidentialClient(authForm);
+ URI redirectUri = response.getLocation();
+ MultivaluedMap<String, String> params =
+ UriComponent.decodeQuery(redirectUri, true);
+ String code = params.get("code").get(0);
+
+ testRequestTokenAuthorizationInvalidClient(code);
+ testRequestTokenAuthorizationInvalidRedirectUri(code);
+ testRequestTokenAuthorizationRevoked(code, uri);
+ }
+
+ private void testRequestTokenAuthorizationInvalidClient (String code)
+ throws KustvaktException {
+ MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
+ tokenForm.add("grant_type", "authorization_code");
+ tokenForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ tokenForm.add("client_secret", "blah");
+ tokenForm.add("code", code);
+
+ ClientResponse response = requestToken(tokenForm);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuth2Error.INVALID_CLIENT, node.at("/error").asText());
+ }
+
+ private void testRequestTokenAuthorizationInvalidRedirectUri (String code)
+ throws KustvaktException {
+ MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
+ tokenForm.add("grant_type", "authorization_code");
+ tokenForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ tokenForm.add("client_secret", "secret");
+ tokenForm.add("code", code);
+ tokenForm.add("redirect_uri", "https://blahblah.com");
+
+ ClientResponse response = requestToken(tokenForm);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuth2Error.INVALID_GRANT, node.at("/error").asText());
+ }
+
+ private void testRequestTokenAuthorizationRevoked (String code, String uri)
+ throws KustvaktException {
+ MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
+ tokenForm.add("grant_type", "authorization_code");
+ tokenForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ tokenForm.add("client_secret", "secret");
+ tokenForm.add("code", code);
+ tokenForm.add("redirect_uri", uri);
+
+ ClientResponse response = requestToken(tokenForm);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuthError.TokenResponse.INVALID_GRANT,
+ node.at("/error").asText());
+ assertEquals("Invalid authorization",
+ node.at("/error_description").asText());
+ }
+
+
@Test
public void testRequestTokenPasswordGrantConfidential ()
throws KustvaktException {
@@ -228,7 +362,7 @@
assertEquals("Missing parameters: client_id",
node.at("/error_description").asText());
}
-
+
@Test
public void testRequestTokenPasswordGrantPublic ()
throws KustvaktException {
@@ -293,6 +427,30 @@
}
@Test
+ public void testRequestTokenClientCredentialsGrantReducedScope ()
+ throws KustvaktException {
+
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("grant_type", "client_credentials");
+ form.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ form.add("client_secret", "secret");
+ form.add("scope", "read_username read_client_info");
+
+ ClientResponse response = requestToken(form);
+ String entity = response.getEntity(String.class);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+ JsonNode node = JsonUtils.readTree(entity);
+ // length?
+ assertNotNull(node.at("/access_token").asText());
+ assertNotNull(node.at("/refresh_token").asText());
+ assertEquals(TokenType.BEARER.toString(),
+ node.at("/token_type").asText());
+ assertNotNull(node.at("/expires_in").asText());
+ assertEquals("read_client_info", node.at("/scope").asText());
+ }
+
+ @Test
public void testRequestTokenMissingGrantType () throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
ClientResponse response = requestToken(form);
diff --git a/full/src/test/resources/kustvakt-test.conf b/full/src/test/resources/kustvakt-test.conf
index b26384b..d9eda87 100644
--- a/full/src/test/resources/kustvakt-test.conf
+++ b/full/src/test/resources/kustvakt-test.conf
@@ -48,6 +48,10 @@
### oauth.password.authentication values)
oauth.password.authentication = TEST
oauth.native.client.host=korap.ids-mannheim.de
+oauth2.max.attempts = 2
+# -- scopes separated by space
+oauth2.default.scopes = read_username read_email
+oauth2.client.credentials.scopes = read_client_info
# JWT
security.jwt.issuer=korap.ids-mannheim.de