Implemented openid authentication for authorization code request.
Change-Id: I1f93d20315d1da6573a98d92515d5e4ed979fbed
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java
index af04f45..6bcb11c 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java
@@ -28,7 +28,7 @@
@PersistenceContext
private EntityManager entityManager;
- public void storeAuthorizationCode (String clientId, String userId,
+ public Authorization storeAuthorizationCode (String clientId, String userId,
String code, Set<AccessScope> scopes, String redirectURI)
throws KustvaktException {
ParameterChecker.checkStringValue(clientId, "client_id");
@@ -45,6 +45,7 @@
entityManager.persist(authCode);
// what if unique fails
+ return authCode;
}
public Authorization retrieveAuthorizationCode (String code)
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
new file mode 100644
index 0000000..9f371eb
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuAuthorizationService.java
@@ -0,0 +1,63 @@
+package de.ids_mannheim.korap.oauth2.oltu.service;
+
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
+import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
+import org.apache.oltu.oauth2.as.response.OAuthASResponse;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.apache.oltu.oauth2.common.message.OAuthResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.sun.jersey.api.client.ClientResponse.Status;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.entity.AccessScope;
+import de.ids_mannheim.korap.oauth2.entity.Authorization;
+import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
+
+/**
+ * OAuth2 authorization service using Apache Oltu
+ *
+ * @author margaretha
+ *
+ */
+@Service
+public class OltuAuthorizationService extends OAuth2AuthorizationService {
+
+ @Autowired
+ private OAuthIssuer oauthIssuer;
+
+ /**
+ * Authorization code request does not require client
+ * authentication, but only checks if the client id exists.
+ *
+ * @param request
+ * @param authzRequest
+ * @param username
+ * @return
+ * @throws KustvaktException
+ * @throws OAuthSystemException
+ */
+ public String requestAuthorizationCode (HttpServletRequest request,
+ OAuthAuthzRequest authzRequest, String username)
+ throws KustvaktException, OAuthSystemException {
+
+ String code = oauthIssuer.authorizationCode();
+ Authorization authorization = createAuthorization(username,
+ authzRequest.getClientId(), authzRequest.getResponseType(),
+ authzRequest.getRedirectURI(), authzRequest.getScopes(), code);
+
+ Set<AccessScope> scopes = authorization.getScopes();
+ String scopeStr = scopeService.convertAccessScopesToString(scopes);
+
+ OAuthResponse oAuthResponse = OAuthASResponse
+ .authorizationResponse(request, Status.FOUND.getStatusCode())
+ .setCode(code).setScope(scopeStr)
+ .location(authorization.getRedirectURI()).buildQueryMessage();
+ return oAuthResponse.getLocationUri();
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/service/OpenIdAuthorizationService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/service/OpenIdAuthorizationService.java
new file mode 100644
index 0000000..985a7e8
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/service/OpenIdAuthorizationService.java
@@ -0,0 +1,57 @@
+package de.ids_mannheim.korap.oauth2.openid.service;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.stereotype.Service;
+
+import com.nimbusds.oauth2.sdk.AuthorizationCode;
+import com.nimbusds.oauth2.sdk.AuthorizationRequest;
+import com.nimbusds.oauth2.sdk.ResponseType;
+import com.nimbusds.oauth2.sdk.Scope;
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.oauth2.sdk.id.State;
+import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
+import com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.oauth2.entity.Authorization;
+import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
+
+@Service
+public class OpenIdAuthorizationService
+ extends OAuth2AuthorizationService {
+
+ public URI requestAuthorizationCode (AuthenticationRequest authRequest,
+ String username) throws KustvaktException {
+
+ ClientID clientId = authRequest.getClientID();
+ URI redirectUri = authRequest.getRedirectionURI();
+ State state = authRequest.getState();
+ Scope scope = authRequest.getScope();
+ ResponseType responseType = authRequest.getResponseType();
+
+ String redirectUriStr =
+ (redirectUri != null) ? redirectUri.toString() : null;
+ Set<String> scopeSet =
+ (scope != null) ? new HashSet<>(scope.toStringList()) : null;
+ AuthorizationCode code = new AuthorizationCode();
+
+ Authorization authorization = createAuthorization(username,
+ clientId.toString(), responseType.toString(), redirectUriStr,
+ scopeSet, code.getValue());
+
+ try {
+ return new AuthenticationSuccessResponse(
+ new URI(authorization.getRedirectURI()), code, null, null,
+ state, null, null).toURI();
+ }
+ catch (URISyntaxException e) {
+ throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
+ "Invalid redirect URI.");
+ }
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
index b258fc0..2d64aa6 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
@@ -3,20 +3,11 @@
import java.time.ZonedDateTime;
import java.util.Set;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
-import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
-import org.apache.oltu.oauth2.as.response.OAuthASResponse;
-import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
-import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import com.sun.jersey.api.client.ClientResponse.Status;
-
import de.ids_mannheim.korap.config.FullConfiguration;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.exceptions.StatusCodes;
@@ -26,7 +17,7 @@
import de.ids_mannheim.korap.oauth2.entity.Authorization;
import de.ids_mannheim.korap.oauth2.entity.OAuth2Client;
-@Service
+@Service(value="authorizationService")
public class OAuth2AuthorizationService {
private static Logger jlog =
@@ -35,9 +26,7 @@
@Autowired
private OAuth2ClientService clientService;
@Autowired
- private OAuth2ScopeService scopeService;
- @Autowired
- private OAuthIssuer oauthIssuer;
+ protected OAuth2ScopeService scopeService;
@Autowired
private AuthorizationDao authorizationDao;
@@ -49,44 +38,38 @@
* Authorization code request does not require client
* authentication, but only checks if the client id exists.
*
- * @param request
- * @param authzRequest
* @param username
+ * @param clientId
+ * @param responseType
+ * @param redirectUri
+ * @param scopeSet
+ * @param code
* @return
* @throws KustvaktException
- * @throws OAuthSystemException
*/
- public OAuthResponse requestAuthorizationCode (HttpServletRequest request,
- OAuthAuthzRequest authzRequest, String username)
- throws KustvaktException, OAuthSystemException {
+ public Authorization createAuthorization (String username, String clientId,
+ String responseType, String redirectUri, Set<String> scopeSet,
+ String code) throws KustvaktException {
- checkResponseType(authzRequest.getResponseType());
+ checkResponseType(responseType);
- OAuth2Client client =
- clientService.authenticateClientId(authzRequest.getClientId());
+ OAuth2Client client = clientService.authenticateClientId(clientId);
- String redirectUri = authzRequest.getRedirectURI();
- boolean hasRedirectUri = hasRedirectUri(redirectUri);
- redirectUri = verifyRedirectUri(client, hasRedirectUri, redirectUri);
+ String verifiedRedirectUri = verifyRedirectUri(client, redirectUri);
- String code = oauthIssuer.authorizationCode();
- Set<String> scopeSet = authzRequest.getScopes();
if (scopeSet == null || scopeSet.isEmpty()) {
scopeSet = config.getDefaultAccessScopes();
}
- String scopeStr = String.join(" ", scopeSet);
Set<AccessScope> scopes = scopeService.convertToAccessScope(scopeSet);
- authorizationDao.storeAuthorizationCode(authzRequest.getClientId(),
- username, code, scopes, authzRequest.getRedirectURI());
+ Authorization authorization = authorizationDao.storeAuthorizationCode(
+ clientId, username, code, scopes, redirectUri);
- return OAuthASResponse
- .authorizationResponse(request, Status.FOUND.getStatusCode())
- .setCode(code).setScope(scopeStr).location(redirectUri)
- .buildQueryMessage();
+ authorization.setRedirectURI(verifiedRedirectUri);
+ return authorization;
}
- private void checkResponseType (String responseType)
+ public void checkResponseType (String responseType)
throws KustvaktException {
if (responseType == null || responseType.isEmpty()) {
throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
@@ -103,15 +86,6 @@
}
}
-
-
- private boolean hasRedirectUri (String redirectURI) {
- if (redirectURI != null && !redirectURI.isEmpty()) {
- return true;
- }
- return false;
- }
-
/**
* If the request contains a redirect_uri parameter, the server
* must confirm it is a valid redirect URI.
@@ -132,12 +106,11 @@
* @return a client's redirect URI
* @throws KustvaktException
*/
- private String verifyRedirectUri (OAuth2Client client,
- boolean hasRedirectUri, String redirectUri)
+ public String verifyRedirectUri (OAuth2Client client, String redirectUri)
throws KustvaktException {
String registeredUri = client.getRedirectURI();
- if (hasRedirectUri) {
+ if (redirectUri != null && !redirectUri.isEmpty()) {
// check if the redirect URI the same as that in DB
if (!redirectUri.equals(registeredUri)) {
throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
@@ -153,7 +126,7 @@
redirectUri = registeredUri;
}
else {
- throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
+ throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
"redirect_uri is required",
OAuth2Error.INVALID_REQUEST);
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
index 2487b45..e4da82b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
@@ -174,11 +174,10 @@
}
- public void deregisterConfidentialClient (OAuthRequest oAuthRequest)
- throws KustvaktException {
+ public void deregisterConfidentialClient (String clientId,
+ String clientSecret) throws KustvaktException {
- OAuth2Client client = authenticateClient(oAuthRequest.getClientId(),
- oAuthRequest.getClientSecret());
+ OAuth2Client client = authenticateClient(clientId, clientSecret);
clientDao.deregisterClient(client);
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java
index eedc744..e6609d4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java
@@ -39,8 +39,10 @@
@Autowired
private OAuth2ClientService clientService;
+
@Autowired
private OAuth2AuthorizationService authorizationService;
+
@Autowired
private OAuth2ScopeService scopeService;
@Autowired
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 ae53294..4b2e19e 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
@@ -26,7 +26,7 @@
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.oauth2.OAuth2AuthorizationRequest;
-import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
+import de.ids_mannheim.korap.oauth2.oltu.service.OltuAuthorizationService;
import de.ids_mannheim.korap.oauth2.service.OAuth2TokenService;
import de.ids_mannheim.korap.security.context.TokenContext;
import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
@@ -43,7 +43,7 @@
@Autowired
private OAuth2TokenService oAuth2Service;
@Autowired
- private OAuth2AuthorizationService authorizationService;
+ private OltuAuthorizationService authorizationService;
/**
* Requests an authorization code.
@@ -84,10 +84,9 @@
new FormRequestWrapper(request, form);
OAuth2AuthorizationRequest authzRequest =
new OAuth2AuthorizationRequest(requestWithForm);
- OAuthResponse authResponse =
- authorizationService.requestAuthorizationCode(
- requestWithForm, authzRequest, username);
- return responseHandler.sendRedirect(authResponse.getLocationUri());
+ String uri = authorizationService.requestAuthorizationCode(
+ requestWithForm, authzRequest, username);
+ return responseHandler.sendRedirect(uri);
}
catch (OAuthSystemException e) {
throw responseHandler.throwit(e);
@@ -182,14 +181,15 @@
throw responseHandler.throwit(e);
}
}
-
-// @POST
-// @Path("revoke")
-// @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-// @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-// public Response revokeAccessToken (@Context HttpServletRequest request,
-// @FormParam("grant_type") String grantType,
-// MultivaluedMap<String, String> form) {
-// return null;
-// }
+
+ // @POST
+ // @Path("revoke")
+ // @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ // @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ // public Response revokeAccessToken (@Context HttpServletRequest
+ // request,
+ // @FormParam("grant_type") String grantType,
+ // MultivaluedMap<String, String> form) {
+ // return null;
+ // }
}
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
new file mode 100644
index 0000000..c87516f
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
@@ -0,0 +1,116 @@
+package de.ids_mannheim.korap.web.controller;
+
+import java.net.URI;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.SecurityContext;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
+import com.sun.jersey.spi.container.ResourceFilters;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.openid.service.OpenIdAuthorizationService;
+import de.ids_mannheim.korap.security.context.TokenContext;
+import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
+import de.ids_mannheim.korap.web.filter.BlockingFilter;
+import de.ids_mannheim.korap.web.utils.MapUtils;
+
+@Controller
+@Path("/oauth2/openid")
+public class OAuth2WithOpenIdController {
+
+ @Autowired
+ private OpenIdAuthorizationService authzService;
+
+ /**
+ * Required parameters for OpenID authentication requests:
+ *
+ * <ul>
+ * <li>scope: MUST contain "openid" for OpenID Connect
+ * requests,</li>
+ * <li>response_type,</li>
+ * <li>client_id,</li>
+ * <li>redirect_uri: MUST match a pre-registered redirect uri
+ * during client registration.</li>
+ * </ul>
+ *
+ * Other parameters:
+ *
+ * <ul>
+ * <li>state (recommended): Opaque value used to maintain state between the request and the
+ * callback.</li>
+ * <li>response_mode (optional) : mechanism to be used for returning parameters</li>
+ * <li>nonce (optional): String value used to associate a Client session with an ID Token,
+ * and to mitigate replay attacks. </li>
+ * <li>display (optional): specifies how the Authorization Server displays the authentication
+ * and consent user interface pages</li>
+ * <li>prompt (optional): specifies if the Authorization Server prompts the End-User
+ * for reauthentication and consent. Defined values: none, login, consent, select_account </li>
+ * <li>max_age (optional): maximum Authentication Age.</li>
+ * <li>ui_locales (optional): preferred languages and scripts for the user interface
+ * represented as a space-separated list of BCP47 [RFC5646] </li>
+ * <li>id_token_hint (optional): ID Token previously issued by the Authorization Server
+ * being passed as a hint</li>
+ * <li>login_hint (optional): hint to the Authorization Server about the login identifier
+ * the End-User might use to log in</li>
+ * <li>acr_values (optional): requested Authentication Context Class Reference values. </li>
+ * </ul>
+ *
+ * @see OpenID Connect Core 1.0 specification
+ *
+ * @param request
+ * @param context
+ * @param form
+ * @return a redirect to client redirect uri
+ */
+ @POST
+ @Path("authorize")
+ @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public Response requestAuthorizationCode (
+ @Context HttpServletRequest request,
+ @Context SecurityContext context,
+ MultivaluedMap<String, String> form) {
+
+ Map<String, String> map = MapUtils.toMap(form);
+ AuthenticationRequest authRequest = null;
+ try {
+ authRequest = AuthenticationRequest.parse(map);
+ }
+ catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ }
+
+ TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
+ String username = tokenContext.getUsername();
+
+ URI uri = null;
+ try {
+ uri = authzService.requestAuthorizationCode(authRequest, username);
+ // System.out.println(uri.toString());
+ }
+ catch (KustvaktException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ ResponseBuilder builder = Response.temporaryRedirect(uri);
+ return builder.build();
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
index d272f73..cb00c12 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
@@ -33,8 +33,10 @@
import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
-/** Defines controllers for OAuth2 clients, namely applications attempting
- * to access users' resources.
+/**
+ * Defines controllers for OAuth2 clients, namely applications
+ * attempting
+ * to access users' resources.
*
* @author margaretha
*
@@ -48,20 +50,29 @@
@Autowired
private OAuth2ResponseHandler responseHandler;
- /** Registers a client application. Before starting an OAuth process,
- * client applications have to be registered first. Only registered
- * users are allowed to register client applications. After registration,
- * the client will receive a client_id and a client_secret, if the client
- * is confidential (capable of storing the client_secret), that are needed
+ /**
+ * Registers a client application. Before starting an OAuth
+ * process,
+ * client applications have to be registered first. Only
+ * registered
+ * users are allowed to register client applications. After
+ * registration,
+ * the client will receive a client_id and a client_secret, if the
+ * client
+ * is confidential (capable of storing the client_secret), that
+ * are needed
* in the authorization process.
*
* From RFC 6749:
- * The authorization server SHOULD document the size of any identifier
+ * The authorization server SHOULD document the size of any
+ * identifier
* it issues.
*
* @param context
- * @param clientJson a JSON object describing the client
- * @return client_id and client_secret if the client type is confidential
+ * @param clientJson
+ * a JSON object describing the client
+ * @return client_id and client_secret if the client type is
+ * confidential
*
* @see OAuth2ClientJson
*/
@@ -85,11 +96,13 @@
}
- /** Deregisters a public client via owner authentication.
+ /**
+ * Deregisters a public client via owner authentication.
*
*
* @param securityContext
- * @param clientId the client id
+ * @param clientId
+ * the client id
* @return HTTP Response OK if successful.
*/
@DELETE
@@ -112,7 +125,8 @@
}
- /** Deregisters confidential clients. Clients must authenticate.
+ /**
+ * Deregisters confidential clients. Clients must authenticate.
*
* @param securityContext
* @param request
@@ -130,7 +144,8 @@
OAuthRequest oAuthRequest = new OAuth2DeregisterClientRequest(
new FormRequestWrapper(request, form));
- clientService.deregisterConfidentialClient(oAuthRequest);
+ clientService.deregisterConfidentialClient(
+ oAuthRequest.getClientId(), oAuthRequest.getClientSecret());
return Response.ok().build();
}
catch (KustvaktException e) {
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/utils/MapUtils.java b/full/src/main/java/de/ids_mannheim/korap/web/utils/MapUtils.java
new file mode 100644
index 0000000..df2dfc1
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/utils/MapUtils.java
@@ -0,0 +1,30 @@
+package de.ids_mannheim.korap.web.utils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+/**
+ * @author margaretha
+ *
+ */
+public class MapUtils {
+
+ public static Map<String, String> toMap (
+ MultivaluedMap<String, String> multivaluedMap) {
+
+ Set<String> keySet = multivaluedMap.keySet();
+ Map<String, String> map = new HashMap<String, String>(keySet.size());
+
+ for (String key : keySet){
+ List<String> values = multivaluedMap.get(key);
+ String value = values.stream().collect(Collectors.joining(" "));
+ map.put(key, value);
+ }
+ return map;
+ }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java
new file mode 100644
index 0000000..da84a06
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java
@@ -0,0 +1,59 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.http.entity.ContentType;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.net.HttpHeaders;
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+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;
+
+public class OAuth2OpenIdControllerTest extends SpringJerseyTest {
+
+ @Autowired
+ private HttpAuthorizationHandler handler;
+
+ @Test
+ public void testAuthorize () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+
+ String redirectUri =
+ "https://korap.ids-mannheim.de/confidential/redirect";
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("response_type", "code");
+ form.add("scope", "openid");
+ form.add("redirect_uri", redirectUri);
+ form.add("client_id", "fCBbQkAyYzI4NzUxMg");
+
+ ClientResponse response = resource().path("oauth2").path("openid")
+ .path("authorize")
+ .header(Attributes.AUTHORIZATION,
+ handler.createBasicAuthorizationHeaderValue("dory",
+ "password"))
+ .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .entity(form).post(ClientResponse.class);
+
+ URI location = response.getLocation();
+
+ assertEquals(redirectUri, location.getScheme() + "://"
+ + location.getHost() + location.getPath());
+ assertTrue(location.getQuery().startsWith("code"));
+ }
+
+}
diff --git a/full/src/test/resources/kustvakt-test.conf b/full/src/test/resources/kustvakt-test.conf
index d9eda87..ebfb216 100644
--- a/full/src/test/resources/kustvakt-test.conf
+++ b/full/src/test/resources/kustvakt-test.conf
@@ -50,7 +50,7 @@
oauth.native.client.host=korap.ids-mannheim.de
oauth2.max.attempts = 2
# -- scopes separated by space
-oauth2.default.scopes = read_username read_email
+oauth2.default.scopes = openid read_username read_email
oauth2.client.credentials.scopes = read_client_info
# JWT