Implemented OAuth2 authorization error response using redirect URI.
Change-Id: Id79f3eec0beacaca792fb3130e3e41f5d9bbc7ad
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuAuthorizationService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuAuthorizationService.java
index c0353be..77f8e17 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuAuthorizationService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuAuthorizationService.java
@@ -1,5 +1,8 @@
package de.ids_mannheim.korap.oauth2.oltu.service;
+import java.net.URI;
+import java.net.URISyntaxException;
+
import javax.servlet.http.HttpServletRequest;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
@@ -13,6 +16,8 @@
import com.sun.jersey.api.client.ClientResponse.Status;
import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
import de.ids_mannheim.korap.oauth2.entity.OAuth2Client;
import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
@@ -35,29 +40,60 @@
* @param request
* @param authzRequest
* @param username
- * @return
+ * @return redirect URI containing authorization code if
+ * successful.
+ *
* @throws KustvaktException
* @throws OAuthSystemException
*/
public String requestAuthorizationCode (HttpServletRequest request,
OAuthAuthzRequest authzRequest, String username)
- throws KustvaktException, OAuthSystemException {
+ throws OAuthSystemException, KustvaktException {
String code = oauthIssuer.authorizationCode();
checkResponseType(authzRequest.getResponseType());
String clientId = authzRequest.getClientId();
OAuth2Client client = clientService.authenticateClientId(clientId);
-
+
String redirectUri = authzRequest.getRedirectURI();
String verifiedRedirectUri = verifyRedirectUri(client, redirectUri);
- String scope = createAuthorization(username, authzRequest.getClientId(),
- redirectUri, authzRequest.getScopes(), code);
- OAuthResponse oAuthResponse = OAuthASResponse
- .authorizationResponse(request, Status.FOUND.getStatusCode())
- .setCode(code).setScope(scope)
- .location(verifiedRedirectUri).buildQueryMessage();
+ URI redirectURI;
+ try {
+ redirectURI = new URI(verifiedRedirectUri);
+ }
+ catch (URISyntaxException e) {
+ throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
+ "Invalid redirect URI", OAuth2Error.INVALID_REQUEST);
+ }
+
+ String scope;
+ try {
+ scope = createAuthorization(username, authzRequest.getClientId(),
+ redirectUri, authzRequest.getScopes(), code);
+ }
+ catch (KustvaktException e) {
+ e.setRedirectUri(redirectURI);
+ throw e;
+ }
+
+ OAuthResponse oAuthResponse;
+ try {
+ oAuthResponse = OAuthASResponse
+ .authorizationResponse(request,
+ Status.FOUND.getStatusCode())
+ .setCode(code).setScope(scope).location(verifiedRedirectUri)
+ .buildQueryMessage();
+ }
+ catch (OAuthSystemException e) {
+ // Should not happen
+ KustvaktException ke =
+ new KustvaktException(StatusCodes.OAUTH2_SYSTEM_ERROR,
+ e.getMessage(), OAuth2Error.SERVER_ERROR);
+ ke.setRedirectUri(redirectURI);
+ throw ke;
+ }
return oAuthResponse.getLocationUri();
}
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java b/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java
index f6a223c..d244e90 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java
@@ -4,6 +4,7 @@
import java.net.URISyntaxException;
import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
@@ -13,6 +14,7 @@
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
+import org.apache.oltu.oauth2.common.message.OAuthResponse.OAuthErrorResponseBuilder;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.exceptions.StatusCodes;
@@ -105,10 +107,37 @@
int statusCode) throws OAuthSystemException {
OAuthProblemException oAuthProblemException = OAuthProblemException
.error(e.getEntity()).description(e.getMessage());
- return OAuthResponse.errorResponse(statusCode)
- .error(oAuthProblemException).buildJSONMessage();
+
+ OAuthErrorResponseBuilder responseBuilder = OAuthResponse
+ .errorResponse(statusCode).error(oAuthProblemException);
+ URI redirectUri = e.getRedirectUri();
+ if (redirectUri != null) {
+ responseBuilder.location(redirectUri.toString());
+ return responseBuilder.buildQueryMessage();
+ }
+
+ return responseBuilder.buildJSONMessage();
}
+ /**
+ * RFC 6749 regarding authorization error response:
+ *
+ * If the request fails due to a missing, invalid, or mismatching
+ * redirection URI, or if the client identifier is missing or
+ * invalid, the authorization server SHOULD inform the resource
+ * owner of the error and MUST NOT automatically redirect the
+ * user-agent to the invalid redirection URI.
+ *
+ * If the resource owner denies the access request or if the
+ * request fails for reasons other than a missing or invalid
+ * redirection URI, the authorization server informs the client by
+ * adding the following parameters to the query component of the
+ * redirection URI using the "application/x-www-form-urlencoded"
+ * format.
+ *
+ * @param oAuthResponse
+ * @return
+ */
public Response createResponse (OAuthResponse oAuthResponse) {
ResponseBuilder builder =
Response.status(oAuthResponse.getResponseStatus());
@@ -121,6 +150,17 @@
builder.header(HttpHeaders.WWW_AUTHENTICATE,
"Basic realm=\"Kustvakt\"");
}
+ String uri = oAuthResponse.getLocationUri();
+ if (uri != null && !uri.isEmpty()) {
+ try {
+ builder.location(new URI(uri));
+ builder.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
+ }
+ catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+
return builder.build();
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/OpenIdResponseHandler.java b/full/src/main/java/de/ids_mannheim/korap/web/OpenIdResponseHandler.java
index 4c50d75..21cecdb 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/OpenIdResponseHandler.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/OpenIdResponseHandler.java
@@ -4,6 +4,7 @@
import java.util.HashMap;
import java.util.Map;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
@@ -104,7 +105,8 @@
state, responseMode).toURI();
}
- ResponseBuilder builder = Response.temporaryRedirect(uri);
+ ResponseBuilder builder = Response.temporaryRedirect(uri)
+ .type(MediaType.APPLICATION_FORM_URLENCODED);
return builder.build();
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
index 4b2e19e..6614f11 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
@@ -79,9 +79,9 @@
TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
String username = tokenContext.getUsername();
+ HttpServletRequest requestWithForm =
+ new FormRequestWrapper(request, form);
try {
- HttpServletRequest requestWithForm =
- new FormRequestWrapper(request, form);
OAuth2AuthorizationRequest authzRequest =
new OAuth2AuthorizationRequest(requestWithForm);
String uri = authorizationService.requestAuthorizationCode(
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
index d3605de..82affd6 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
@@ -5,7 +5,6 @@
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
-import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;