Implemented authorization code request, simplified client
authentication, and added tests.
Change-Id: Id6695cacc6da75da64588499ea3a7c7b1ad64591
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
index 991e8f4..1c22fea 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
@@ -44,7 +44,7 @@
import de.ids_mannheim.korap.security.context.TokenContext;
import de.ids_mannheim.korap.user.DemoUser;
import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.ShibUser;
+import de.ids_mannheim.korap.user.ShibbolethUser;
import de.ids_mannheim.korap.user.User;
import de.ids_mannheim.korap.user.User.CorpusAccess;
import de.ids_mannheim.korap.user.User.Location;
@@ -389,7 +389,7 @@
StatusCodes.LOGIN_FAILED, username);
}
- } else if (unknown instanceof ShibUser) {
+ } else if (unknown instanceof ShibbolethUser) {
// todo
}
jlog.debug("Authentication done: "+unknown);
@@ -521,7 +521,7 @@
* username); }
*/
- } else if (unknown instanceof ShibUser) {
+ } else if (unknown instanceof ShibbolethUser) {
// todo
}
@@ -753,17 +753,20 @@
}
// todo:
- private ShibUser createShibbUserAccount(Map<String, Object> attributes) throws KustvaktException {
+ private ShibbolethUser createShibbUserAccount(Map<String, Object> attributes) throws KustvaktException {
jlog.debug("creating shibboleth user account for user attr: {}", attributes);
Map<String, Object> safeMap = validator.validateMap(attributes);
// todo eppn non-unique.join with idp or use persistent_id as username
// identifier
- ShibUser user = User.UserFactory.getShibInstance((String) safeMap.get(Attributes.EPPN),
- (String) safeMap.get(Attributes.MAIL), (String) safeMap.get(Attributes.CN));
- user.setAffiliation((String) safeMap.get(Attributes.EDU_AFFIL));
- user.setAccountCreation(TimeUtils.getNow().getMillis());
+ // EM: disabled
+// ShibbolethUser user = User.UserFactory.getShibInstance((String) safeMap.get(Attributes.EPPN),
+// (String) safeMap.get(Attributes.MAIL), (String) safeMap.get(Attributes.CN));
+// user.setAffiliation((String) safeMap.get(Attributes.EDU_AFFIL));
+// user.setAccountCreation(TimeUtils.getNow().getMillis());
+ ShibbolethUser user = null;
+
UserDetails d = new UserDetails();
d.read(attributes, true);
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
index 6e75f65..e1759c4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
@@ -6,7 +6,6 @@
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.stereotype.Repository;
@@ -27,8 +26,9 @@
private EntityManager entityManager;
public void registerClient (String id, String secretHashcode, String name,
- OAuth2ClientType type, boolean isNative, String url, int urlHashCode,
- String redirectURI, String registeredBy) throws KustvaktException {
+ OAuth2ClientType type, boolean isNative, String url,
+ int urlHashCode, String redirectURI, String registeredBy,
+ String description) throws KustvaktException {
ParameterChecker.checkStringValue(id, "client id");
ParameterChecker.checkStringValue(name, "client name");
ParameterChecker.checkObjectValue(type, "client type");
@@ -46,6 +46,7 @@
client.setUrlHashCode(urlHashCode);
client.setRedirectURI(redirectURI);
client.setRegisteredBy(registeredBy);
+ client.setDescription(description);
entityManager.persist(client);
}
@@ -68,7 +69,7 @@
}
catch (NoResultException e) {
throw new KustvaktException(StatusCodes.CLIENT_NOT_FOUND,
- "Unknown client with "+clientId+".", "invalid_client");
+ "Unknown client with " + clientId + ".", "invalid_client");
}
catch (Exception e) {
throw new KustvaktException(StatusCodes.CLIENT_NOT_FOUND,
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
index 760fc13..9efab11 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
@@ -37,11 +37,13 @@
private String redirectURI;
@Column(name = "registered_by")
private String registeredBy;
+ private String description;
@Override
public String toString () {
- return "id=" + id + ", secret=" + secret + ", type=" + type + ", name="
- + name + ", url=" + url + ", redirectURI=" + redirectURI
- + ", registeredBy=" + registeredBy;
+ return "id=" + id + ", name=" + name + ", secret=" + secret + ", type="
+ + type + ", isNative=" + isNative + ", url=" + url
+ + ", redirectURI=" + redirectURI + ", registeredBy="
+ + registeredBy + ", description=" + description;
}
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java b/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
index fd3c1e8..fd7fdc2 100644
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
@@ -1,21 +1,11 @@
package de.ids_mannheim.korap.handlers;
-import de.ids_mannheim.korap.config.ParamFields;
-import de.ids_mannheim.korap.config.URIParam;
-import de.ids_mannheim.korap.exceptions.EmptyResultException;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.exceptions.DatabaseException;
-import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
-import de.ids_mannheim.korap.interfaces.KustvaktBaseDaoInterface;
-import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
-import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.ShibUser;
-import de.ids_mannheim.korap.user.DemoUser;
-import de.ids_mannheim.korap.user.User;
-import de.ids_mannheim.korap.user.User.UserFactory;
-import de.ids_mannheim.korap.utils.BooleanUtils;
-import de.ids_mannheim.korap.utils.TimeUtils;
+import java.sql.Date;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
@@ -26,11 +16,19 @@
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
-import java.sql.Date;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import de.ids_mannheim.korap.config.ParamFields;
+import de.ids_mannheim.korap.config.URIParam;
+import de.ids_mannheim.korap.exceptions.DatabaseException;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
+import de.ids_mannheim.korap.interfaces.KustvaktBaseDaoInterface;
+import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
+import de.ids_mannheim.korap.user.KorAPUser;
+import de.ids_mannheim.korap.user.ShibbolethUser;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.BooleanUtils;
+import de.ids_mannheim.korap.utils.TimeUtils;
/* WKP: In computer software, a data access object (DAO) is an object that provides an abstract interface to some type
* of database or other persistence mechanism. By mapping application calls to the persistence layer, the DAO provides
@@ -154,14 +152,14 @@
// "uri_expiration=:exp "
+ "WHERE id=:id";
}
- else if (user instanceof ShibUser) {
- ShibUser s = (ShibUser) user;
+ else if (user instanceof ShibbolethUser) {
+ ShibbolethUser s = (ShibbolethUser) user;
//todo:
// np.addValue("ali", s.getAccountLink());
np.addValue("ali", null);
np.addValue("edu", s.getAffiliation());
np.addValue("id", s.getId());
- np.addValue("cn", s.getCn());
+ np.addValue("cn", s.getCommonName());
np.addValue("mail", s.getMail());
query = "UPDATE shibusers SET account_link=:ali"
@@ -225,8 +223,8 @@
//fixme: still applicable?
}
- else if (user instanceof ShibUser) {
- ShibUser s = (ShibUser) user;
+ else if (user instanceof ShibbolethUser) {
+ ShibbolethUser s = (ShibbolethUser) user;
query = "INSERT INTO shibusers (username, type, account_link, account_creation "
+ "eduPersonScopedAffiliation, cn, mail) "
@@ -237,7 +235,7 @@
np.addValue("edu", s.getAffiliation());
np.addValue("mail", s.getMail());
np.addValue("type", user.getType());
- np.addValue("cn", s.getCn());
+ np.addValue("cn", s.getCommonName());
np.addValue("acr", System.currentTimeMillis());
//todo: deprecate
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/RowMapperFactory.java b/full/src/main/java/de/ids_mannheim/korap/handlers/RowMapperFactory.java
index d18ea69..39b7efa 100644
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/RowMapperFactory.java
+++ b/full/src/main/java/de/ids_mannheim/korap/handlers/RowMapperFactory.java
@@ -6,7 +6,7 @@
import de.ids_mannheim.korap.resources.ResourceFactory;
import de.ids_mannheim.korap.config.Attributes;
import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.ShibUser;
+import de.ids_mannheim.korap.user.ShibbolethUser;
import de.ids_mannheim.korap.user.User;
import org.springframework.jdbc.core.RowMapper;
@@ -39,9 +39,9 @@
case 0:
user = getKorAP(rs);
break;
- case 1:
- user = getShib(rs);
- break;
+// case 1:
+// user = getShib(rs);
+// break;
default:
user = User.UserFactory.getDemoUser();
user.setId(rs.getInt("id"));
@@ -71,13 +71,13 @@
}
- private ShibUser getShib (ResultSet rs) throws SQLException {
- ShibUser user = User.UserFactory.getShibInstance(
- rs.getString(Attributes.USERNAME),
- rs.getString(Attributes.MAIL), rs.getString(Attributes.CN));
- user.setId(rs.getInt(Attributes.ID));
- return user;
- }
+// private ShibbolethUser getShib (ResultSet rs) throws SQLException {
+// ShibbolethUser user = User.UserFactory.getShibInstance(
+// rs.getString(Attributes.USERNAME),
+// rs.getString(Attributes.MAIL), rs.getString(Attributes.CN));
+// user.setId(rs.getInt(Attributes.ID));
+// return user;
+// }
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth/ClientDeregistrationValidator.java b/full/src/main/java/de/ids_mannheim/korap/oauth/ClientDeregistrationValidator.java
new file mode 100644
index 0000000..60525b0
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth/ClientDeregistrationValidator.java
@@ -0,0 +1,23 @@
+package de.ids_mannheim.korap.oauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.oltu.oauth2.common.OAuth;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.utils.OAuthUtils;
+import org.apache.oltu.oauth2.common.validators.AbstractValidator;
+
+public class ClientDeregistrationValidator extends AbstractValidator<HttpServletRequest>{
+
+ public ClientDeregistrationValidator () {
+ enforceClientAuthentication = true;
+ }
+
+ @Override
+ public void validateMethod (HttpServletRequest request)
+ throws OAuthProblemException {
+ if (!request.getMethod().equals(OAuth.HttpMethod.DELETE)) {
+ throw OAuthUtils.handleOAuthProblemException("Method not set to DELETE.");
+ }
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth/OAuthDeregisterClientRequest.java b/full/src/main/java/de/ids_mannheim/korap/oauth/OAuthDeregisterClientRequest.java
new file mode 100644
index 0000000..88ae668
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth/OAuthDeregisterClientRequest.java
@@ -0,0 +1,27 @@
+package de.ids_mannheim.korap.oauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.oltu.oauth2.as.request.OAuthRequest;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.apache.oltu.oauth2.common.utils.OAuthUtils;
+import org.apache.oltu.oauth2.common.validators.OAuthValidator;
+
+public class OAuthDeregisterClientRequest extends OAuthRequest {
+
+ public OAuthDeregisterClientRequest (HttpServletRequest request)
+ throws OAuthSystemException, OAuthProblemException {
+ super(request);
+ }
+
+ @Override
+ protected OAuthValidator<HttpServletRequest> initValidator ()
+ throws OAuthProblemException, OAuthSystemException {
+ validators.put("client_deregistration",
+ ClientDeregistrationValidator.class);
+ final Class<? extends OAuthValidator<HttpServletRequest>> clazz =
+ validators.get("client_deregistration");
+ return OAuthUtils.instantiateClass(clazz);
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2AuthorizationService.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2AuthorizationService.java
new file mode 100644
index 0000000..751c7d2
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2AuthorizationService.java
@@ -0,0 +1,118 @@
+package de.ids_mannheim.korap.service;
+
+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.error.OAuthError;
+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.config.Attributes;
+import de.ids_mannheim.korap.entity.OAuth2Client;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+
+@Service
+public class OAuth2AuthorizationService {
+
+ @Autowired
+ private OAuth2ClientService clientService;
+ @Autowired
+ private OAuth2Service auth2Service;
+ @Autowired
+ private OAuthIssuer oauthIssuer;
+
+ public OAuthResponse requestAuthorizationCode (HttpServletRequest request,
+ OAuthAuthzRequest authzRequest, String authorization)
+ throws KustvaktException, OAuthSystemException {
+
+ String responseType = authzRequest.getResponseType();
+ if (responseType == null || responseType.isEmpty()) {
+ throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
+ "response_type is missing.",
+ OAuthError.CodeResponse.INVALID_REQUEST);
+ }
+
+ OAuth2Client client;
+ try {
+ client = clientService.authenticateClient(
+ authzRequest.getClientId(), authzRequest.getClientSecret());
+ }
+ catch (KustvaktException e) {
+ e.setEntity(OAuthError.CodeResponse.UNAUTHORIZED_CLIENT);
+ throw e;
+ }
+
+ String redirectUri = authzRequest.getRedirectURI();
+ boolean hasRedirectUri = hasRedirectUri(redirectUri);
+ redirectUri = verifyRedirectUri(client, hasRedirectUri, redirectUri);
+
+ auth2Service.authenticateUser(
+ authzRequest.getParam(Attributes.USERNAME),
+ authzRequest.getParam(Attributes.PASSWORD),
+ authzRequest.getScopes());
+
+ return OAuthASResponse
+ .authorizationResponse(request, Status.FOUND.getStatusCode())
+ .setCode(oauthIssuer.authorizationCode()).location(redirectUri)
+ .buildQueryMessage();
+ }
+
+
+ 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.
+ *
+ * If there is no redirect_uri parameter in the request, and only one URI
+ * was registered, the server uses the redirect URL that was previously
+ * registered.
+ *
+ * If no redirect URL has been registered, this is an error.
+ *
+ * @param client an OAuth2Client
+ * @param hasRedirectUri true if request contains redirect_uri, false otherwise
+ * @param redirectUri the redirect_uri value
+ * @return a client's redirect URI
+ * @throws KustvaktException
+ */
+ private String verifyRedirectUri (OAuth2Client client,
+ boolean hasRedirectUri, String redirectUri)
+ throws KustvaktException {
+
+ String registeredUri = client.getRedirectURI();
+ if (hasRedirectUri) {
+ // check if the redirect URI the same as that in DB
+ if (!redirectUri.equals(registeredUri)) {
+ throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
+ redirectUri + " is unknown",
+ OAuthError.CodeResponse.INVALID_REQUEST);
+ }
+ }
+ else {
+ // check if there is a redirect URI in the DB
+ // This should not happened as it is required in client registration!
+ if (registeredUri != null && !registeredUri.isEmpty()) {
+ redirectUri = registeredUri;
+ }
+ else {
+ throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
+ "redirect_uri is required",
+ OAuthError.CodeResponse.INVALID_REQUEST);
+ }
+ }
+
+ return redirectUri;
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
index 4072cf7..1089c45 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
@@ -8,14 +8,12 @@
import org.apache.commons.validator.routines.UrlValidator;
import org.apache.log4j.Logger;
+import org.apache.oltu.oauth2.as.request.OAuthRequest;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import de.ids_mannheim.korap.authentication.http.AuthorizationData;
-import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
import de.ids_mannheim.korap.config.FullConfiguration;
-import de.ids_mannheim.korap.constant.AuthenticationScheme;
import de.ids_mannheim.korap.constant.OAuth2ClientType;
import de.ids_mannheim.korap.dao.AdminDao;
import de.ids_mannheim.korap.dao.OAuth2ClientDao;
@@ -57,8 +55,6 @@
@Autowired
private EncryptionIface encryption;
@Autowired
- private HttpAuthorizationHandler authorizationHandler;
- @Autowired
private FullConfiguration config;
public OAuth2ClientDto registerClient (OAuth2ClientJson clientJson,
@@ -101,7 +97,7 @@
clientDao.registerClient(id, secretHashcode, clientJson.getName(),
clientJson.getType(), isNative, clientJson.getUrl(),
clientJson.getUrl().hashCode(), clientJson.getRedirectURI(),
- registeredBy);
+ registeredBy, clientJson.getDescription());
}
catch (Exception e) {
Throwable cause = e;
@@ -140,7 +136,8 @@
}
catch (URISyntaxException e) {
throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
- "Invalid redirectURI: "+e.getMessage(), OAuthError.TokenResponse.INVALID_REQUEST);
+ "Invalid redirectURI: " + e.getMessage(),
+ OAuthError.TokenResponse.INVALID_REQUEST);
}
boolean isNative =
urlHost.equals(nativeHost) && uriHost.equals(nativeHost);
@@ -152,7 +149,7 @@
public void deregisterPublicClient (String clientId, String username)
throws KustvaktException {
- OAuth2Client client = retrieveClientById(clientId);
+ OAuth2Client client = clientDao.retrieveClientById(clientId);
if (adminDao.isAdmin(username)) {
clientDao.deregisterClient(client);
}
@@ -174,98 +171,46 @@
}
- public void deregisterConfidentialClient (String authorization,
- String clientId) throws KustvaktException {
- OAuth2Client client =
- authenticateClientByBasicAuthorization(authorization, clientId);
+ public void deregisterConfidentialClient (OAuthRequest oAuthRequest)
+ throws KustvaktException {
+
+ OAuth2Client client = authenticateClient(oAuthRequest.getClientId(),
+ oAuthRequest.getClientSecret());
clientDao.deregisterClient(client);
}
- public OAuth2Client authenticateClient (String authorization,
- String clientId) throws KustvaktException {
- OAuth2Client client;
- if (authorization == null || authorization.isEmpty()) {
- client = authenticateClientById(clientId);
- if (client.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
- throw new KustvaktException(
- StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Client authentication using authorization header is required.",
- OAuthError.TokenResponse.INVALID_CLIENT);
- }
- }
- else {
- client = authenticateClientByBasicAuthorization(authorization,
- clientId);
- }
- return client;
- }
+ public OAuth2Client authenticateClient (String clientId,
+ String clientSecret) throws KustvaktException {
- public OAuth2Client authenticateClientById (String clientId)
- throws KustvaktException {
- if (clientId == null || clientId.equals("null") || clientId.isEmpty()) {
+ if (clientId == null || clientId.isEmpty()) {
throw new KustvaktException(
StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "client_id is missing",
- OAuthError.TokenResponse.INVALID_REQUEST);
+ "Missing parameters: client id", "invalid_request");
}
- else {
- return retrieveClientById(clientId);
- }
- }
- public OAuth2Client authenticateClientByBasicAuthorization (
- String authorization, String clientId) throws KustvaktException {
-
- if (authorization == null || authorization.isEmpty()) {
- throw new KustvaktException(
- StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Authorization header is not found.",
- OAuthError.TokenResponse.INVALID_CLIENT);
- }
- else {
- AuthorizationData authData = authorizationHandler
- .parseAuthorizationHeaderValue(authorization);
- if (authData.getAuthenticationScheme()
- .equals(AuthenticationScheme.BASIC)) {
- authorizationHandler.parseBasicToken(authData);
- return verifyClientCredentials(clientId, authData);
- }
- else {
+ OAuth2Client client = clientDao.retrieveClientById(clientId);
+ if (clientSecret == null || clientSecret.isEmpty()) {
+ if (client.getSecret() != null
+ || client.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
throw new KustvaktException(
StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Client authentication with " + authData
- .getAuthenticationScheme().displayName()
- + "is not supported",
- "invalid_client");
+ "Missing parameters: client_secret", "invalid_request");
+ }
+ else
+ return client;
+ }
+ else {
+ if (client.getSecret() != null) {
+ if (encryption.checkHash(clientSecret, client.getSecret(),
+ config.getPasscodeSaltField())) {
+ return client;
+ }
}
}
+
+ throw new KustvaktException(StatusCodes.CLIENT_AUTHENTICATION_FAILED,
+ "Invalid client credentials",
+ OAuthError.TokenResponse.INVALID_CLIENT);
}
- private OAuth2Client verifyClientCredentials (String clientId,
- AuthorizationData authData) throws KustvaktException {
-
- OAuth2Client client = retrieveClientById(authData.getUsername());
- // EM: not sure if this is necessary
- if (clientId != null && !clientId.isEmpty()) {
- if (!client.getId().equals(clientId)) {
- throw new KustvaktException(
- StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Invalid client credentials.",
- OAuthError.TokenResponse.INVALID_CLIENT);
- }
- }
- if (!encryption.checkHash(authData.getPassword(), client.getSecret(),
- config.getPasscodeSaltField())) {
- throw new KustvaktException(
- StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Invalid client credentials.",
- OAuthError.TokenResponse.INVALID_CLIENT);
- }
- return client;
- }
-
- public OAuth2Client retrieveClientById (String clientId)
- throws KustvaktException {
- return clientDao.retrieveClientById(clientId);
- }
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java
index 4ec5dac..9e8092b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java
@@ -4,15 +4,12 @@
import java.util.Map;
import java.util.Set;
-import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response.Status;
-import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
-import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
-import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
+import org.apache.oltu.oauth2.as.request.AbstractOAuthTokenRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.error.OAuthError;
-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.types.GrantType;
@@ -36,12 +33,27 @@
private FullConfiguration config;
@Autowired
private AuthenticationManagerIface authenticationManager;
+ @Autowired
+ private OAuthIssuer oauthIssuer;
/**
- * RFC 6749:
+ * OAuth2 describes various ways for requesting an access token. Kustvakt
+ * supports:
+ * <ul>
+ * <li> Authorization code grant: obtains authorization from a third party
+ * application.
+ * </li>
+ * <li> Resource owner password grant: strictly for clients that are parts
+ * of KorAP. Clients use user credentials, e.g. Kalamar (front-end) with
+ * login form.
+ * </li>
+ * <li> Client credentials grant: strictly for clients that are parts
+ * of KorAP. Clients access their own resources, not on behalf of a
+ * user.
+ * </li>
+ * </ul>
*
- * If the client type is confidential or the client was issued client
- * credentials, the client MUST authenticate with the authorization server.
+ *
* @param request
*
* @param oAuthRequest
@@ -50,24 +62,25 @@
* @throws KustvaktException
* @throws OAuthSystemException
*/
- public OAuthResponse requestAccessToken (OAuthTokenRequest oAuthRequest,
- String authorization)
+ public OAuthResponse requestAccessToken (
+ AbstractOAuthTokenRequest oAuthRequest)
throws KustvaktException, OAuthSystemException {
String grantType = oAuthRequest.getGrantType();
if (grantType.equals(GrantType.AUTHORIZATION_CODE.toString())) {
- return requestAccessTokenWithAuthorizationCode(authorization,
+ return requestAccessTokenWithAuthorizationCode(
oAuthRequest.getCode(), oAuthRequest.getRedirectURI(),
- oAuthRequest.getClientId());
+ oAuthRequest.getClientId(), oAuthRequest.getClientSecret());
}
else if (grantType.equals(GrantType.PASSWORD.toString())) {
- return requestAccessTokenWithPassword(authorization,
- oAuthRequest.getUsername(), oAuthRequest.getPassword(),
- oAuthRequest.getScopes(), oAuthRequest.getClientId());
+ return requestAccessTokenWithPassword(oAuthRequest.getUsername(),
+ oAuthRequest.getPassword(), oAuthRequest.getScopes(),
+ oAuthRequest.getClientId(), oAuthRequest.getClientSecret());
}
else if (grantType.equals(GrantType.CLIENT_CREDENTIALS.toString())) {
- return requestAccessTokenWithClientCredentials(authorization,
+ return requestAccessTokenWithClientCredentials(
+ oAuthRequest.getClientId(), oAuthRequest.getClientSecret(),
oAuthRequest.getScopes());
}
else {
@@ -78,25 +91,31 @@
}
- /** Confidential clients must authenticate
+ /**
+ * RFC 6749:
+ * If the client type is confidential or the client was issued client
+ * credentials, the client MUST authenticate with the authorization server.
*
- * @param authorization
* @param authorizationCode
- * @param redirectURI
+ * @param redirectURI required if included in the authorization request
* @param clientId required if there is no authorization header
+ * @param clientSecret clilent_secret, required if client_secret was issued
+ * for the client in client registration.
* @return
* @throws OAuthSystemException
* @throws KustvaktException
- * @throws OAuthProblemException
*/
private OAuthResponse requestAccessTokenWithAuthorizationCode (
- String authorization, String authorizationCode, String redirectURI,
- String clientId) throws KustvaktException {
- OAuth2Client client =
- clientService.authenticateClient(authorization, clientId);
+ String authorizationCode, String redirectURI, String clientId,
+ String clientSecret)
+ throws KustvaktException, OAuthSystemException {
+
+ clientService.authenticateClient(clientId, clientSecret);
// TODO
- return null;
+ // check authorization code
+ // check redirectURI
+ return createsAccessTokenResponse();
}
@@ -104,30 +123,32 @@
/** Third party apps must not be allowed to use password grant.
* MH: password grant is only allowed for trusted clients (korap frontend)
*
- * A similar rule to that of authorization code grant is additionally
- * applied, namely client_id is required when authorization header is not
- * available.
+ * According to RFC 6749, client authentication is only required for
+ * confidential clients and whenever client credentials are provided.
+ * Moreover, client_id is optional for password grant, but without it,
+ * the authentication server cannot check the client type.
*
- * According to RFC 6749, client_id is optional for password grant,
- * but without it, server would not be able to check the client
- * type, thus cannot make sure that confidential clients authenticate.
+ * To make sure that confidential clients authenticate, client_id is made
+ * required (similar to authorization code grant).
*
- * @param authorization
- * @param username
- * @param password
+ *
+ * @param username username, required
+ * @param password user password, required
* @param scopes
- * @param clientId
+ * @param clientId client_id, required
+ * @param clientSecret clilent_secret, required if client_secret was issued
+ * for the client in client registration.
* @return
* @throws KustvaktException
- * @throws OAuthSystemException
+ * @throws OAuthSystemException
*/
- private OAuthResponse requestAccessTokenWithPassword (String authorization,
- String username, String password, Set<String> scopes,
- String clientId) throws KustvaktException, OAuthSystemException {
+ private OAuthResponse requestAccessTokenWithPassword (String username,
+ String password, Set<String> scopes, String clientId,
+ String clientSecret)
+ throws KustvaktException, OAuthSystemException {
OAuth2Client client =
- clientService.authenticateClient(authorization, clientId);
-
+ clientService.authenticateClient(clientId, clientSecret);
if (!client.isNative()) {
throw new KustvaktException(StatusCodes.CLIENT_AUTHORIZATION_FAILED,
"Password grant is not allowed for third party clients",
@@ -138,7 +159,7 @@
return createsAccessTokenResponse();
}
- private void authenticateUser (String username, String password,
+ public void authenticateUser (String username, String password,
Set<String> scopes) throws KustvaktException {
if (username == null || username.isEmpty()) {
throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
@@ -162,50 +183,46 @@
/** Clients must authenticate
*
- * @param authorization
+ * @param clientId client_id parameter, required
+ * @param clientSecret client_secret parameter, required
* @param scopes
- * @param request
* @return
- * @throws KustvaktException
- * @throws OAuthSystemException
+ * @throws KustvaktException
+ * @throws OAuthSystemException
*/
private OAuthResponse requestAccessTokenWithClientCredentials (
- String authorization, Set<String> scopes)
+ String clientId, String clientSecret, Set<String> scopes)
throws KustvaktException, OAuthSystemException {
- if (authorization == null || authorization.isEmpty()) {
+ if (clientSecret == null || clientSecret.isEmpty()) {
throw new KustvaktException(
StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Client authentication using authorization header is required.",
- OAuthError.TokenResponse.INVALID_CLIENT);
+ "Missing parameters: client_secret", "invalid_request");
}
- else {
- clientService.authenticateClientByBasicAuthorization(authorization,
- null);
- return createsAccessTokenResponse();
- }
+
+ clientService.authenticateClient(clientId, clientSecret);
+ return createsAccessTokenResponse();
}
- /**
- * @param request
- * @return
- * @throws OAuthSystemException
+
+ /** Creates an OAuthResponse containing an access token and a refresh token
+ * with type Bearer.
*
+ * @return an OAuthResponse containing an access token
+ * @throws OAuthSystemException
*/
private OAuthResponse createsAccessTokenResponse ()
throws OAuthSystemException {
- OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
- OAuthResponse r = null;
+ String accessToken = oauthIssuer.accessToken();
+ String refreshToken = oauthIssuer.refreshToken();
- String accessToken = oauthIssuerImpl.accessToken();
- String refreshToken = oauthIssuerImpl.refreshToken();
-
- r = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK)
- .setAccessToken(accessToken)
- .setTokenType(TokenType.BEARER.toString())
- .setExpiresIn(String.valueOf(config.getTokenTTL()))
- .setRefreshToken(refreshToken).buildJSONMessage();
+ OAuthResponse r =
+ OAuthASResponse.tokenResponse(Status.OK.getStatusCode())
+ .setAccessToken(accessToken)
+ .setTokenType(TokenType.BEARER.toString())
+ .setExpiresIn(String.valueOf(config.getTokenTTL()))
+ .setRefreshToken(refreshToken).buildJSONMessage();
// scope
return r;
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/user/ShibbolethUser.java b/full/src/main/java/de/ids_mannheim/korap/user/ShibbolethUser.java
new file mode 100644
index 0000000..80d01f5
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/user/ShibbolethUser.java
@@ -0,0 +1,90 @@
+package de.ids_mannheim.korap.user;
+
+/**
+ * User: hanl
+ * Date: 10/16/13
+ * Time: 2:02 PM
+ *
+ * @author margaretha
+ * @last-update 18/04/2018
+ */
+public class ShibbolethUser extends User {
+
+ /**
+ * Auto generated serial Id
+ */
+ private static final long serialVersionUID = -4008236368010397075L;
+ private String mail;
+ private String affiliation;
+ // EM: common name
+ private String commonName;
+
+
+ protected ShibbolethUser () {
+ super(1);
+ }
+
+
+ private ShibbolethUser (String eduPersonID, String mail, String cn,
+ String affiliation) {
+ this(eduPersonID);
+ this.setUsername(eduPersonID);
+ this.setMail(mail);
+ this.setAffiliation(affiliation);
+ this.setCommonName(cn);
+ }
+
+
+ public ShibbolethUser (String username) {
+ super(username, 1);
+
+ }
+
+
+ @Override
+ public String toString () {
+ final StringBuffer sb = new StringBuffer("ShibbolethUser{");
+ sb.append(", mail='").append(getMail()).append('\'');
+ sb.append(", affiliation='").append(getAffiliation()).append('\'');
+ sb.append(", common-name='").append(getCommonName()).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+
+
+ @Override
+ protected User clone () {
+ return new ShibbolethUser(this.getUsername(), this.getMail(), this.getCommonName(),
+ this.getAffiliation());
+ }
+
+
+ public String getMail () {
+ return mail;
+ }
+
+
+ public void setMail (String mail) {
+ this.mail = mail;
+ }
+
+
+ public String getAffiliation () {
+ return affiliation;
+ }
+
+
+ public void setAffiliation (String affiliation) {
+ this.affiliation = affiliation;
+ }
+
+
+ public String getCommonName () {
+ return commonName;
+ }
+
+
+ public void setCommonName (String commonName) {
+ this.commonName = commonName;
+ }
+}
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 5df68b2..0d31236 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
@@ -1,5 +1,8 @@
package de.ids_mannheim.korap.web;
+import java.net.URI;
+import java.net.URISyntaxException;
+
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
@@ -92,7 +95,9 @@
OAuthResponse oAuthResponse = null;
String errorCode = e.getEntity();
try {
- if (errorCode.equals(OAuthError.TokenResponse.INVALID_CLIENT)) {
+ if (errorCode.equals(OAuthError.TokenResponse.INVALID_CLIENT)
+ || errorCode.equals(
+ OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)) {
oAuthResponse = createOAuthResponse(e,
Status.UNAUTHORIZED.getStatusCode());
}
@@ -100,8 +105,6 @@
|| errorCode
.equals(OAuthError.TokenResponse.INVALID_REQUEST)
|| errorCode.equals(OAuthError.TokenResponse.INVALID_SCOPE)
- || errorCode
- .equals(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
|| errorCode.equals(
OAuthError.TokenResponse.UNSUPPORTED_GRANT_TYPE)) {
oAuthResponse = createOAuthResponse(e,
@@ -142,4 +145,16 @@
}
return builder.build();
}
+
+ public Response sendRedirect (String locationUri) throws KustvaktException {
+ try {
+ ResponseBuilder builder =
+ Response.temporaryRedirect(new URI(locationUri));
+ return builder.build();
+ }
+ catch (URISyntaxException e) {
+ throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+ e.getMessage(), OAuthError.CodeResponse.INVALID_REQUEST);
+ }
+ }
}
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 ece03f2..b0699b1 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
@@ -2,6 +2,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -10,16 +11,20 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.SecurityContext;
+import org.apache.oltu.oauth2.as.request.AbstractOAuthTokenRequest;
+import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
+import org.apache.oltu.oauth2.as.request.OAuthUnauthenticatedTokenRequest;
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.types.GrantType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.service.OAuth2AuthorizationService;
import de.ids_mannheim.korap.service.OAuth2Service;
import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
@@ -31,7 +36,50 @@
@Autowired
private OAuth2ResponseHandler responseHandler;
@Autowired
- private OAuth2Service oauth2Service;
+ private OAuth2Service oAuth2Service;
+ @Autowired
+ private OAuth2AuthorizationService authorizationService;
+
+ /** Kustvakt supports authorization only with Kalamar as the authorization
+ * web-frontend or user interface. Thus authorization code request requires
+ * user credentials in the request body, similar to access token request in
+ * resource owner password grant request.
+ *
+ * @param request
+ * @param authorization
+ * @param form
+ * @return
+ */
+ @POST
+ @Path("authorize")
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public Response requestAuthorizationCode (
+ @Context HttpServletRequest request,
+ @HeaderParam("Authorization") String authorization,
+ MultivaluedMap<String, String> form) {
+
+ try {
+ HttpServletRequest requestWithForm =
+ new FormRequestWrapper(request, form);
+ OAuthAuthzRequest authzRequest =
+ new OAuthAuthzRequest(requestWithForm);
+ OAuthResponse authResponse =
+ authorizationService.requestAuthorizationCode(
+ requestWithForm, authzRequest, authorization);
+ return responseHandler.sendRedirect(authResponse.getLocationUri());
+ }
+ catch (OAuthSystemException e) {
+ throw responseHandler.throwit(e);
+ }
+ catch (OAuthProblemException e) {
+ throw responseHandler.throwit(e);
+ }
+ catch (KustvaktException e) {
+ throw responseHandler.throwit(e);
+ }
+ }
+
/** Grants a client an access token, namely a string used in authenticated
* requests representing user authorization for the client to access user
@@ -49,27 +97,32 @@
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response requestAccessToken (@Context HttpServletRequest request,
- @HeaderParam("Authorization") String authorization,
+ @FormParam("grant_type") String grantType,
MultivaluedMap<String, String> form) {
try {
- OAuthTokenRequest oAuthRequest = null;
- try {
+ AbstractOAuthTokenRequest oAuthRequest = null;
+ if (grantType != null && !grantType.isEmpty() && grantType
+ .equals(GrantType.CLIENT_CREDENTIALS.toString())) {
oAuthRequest = new OAuthTokenRequest(
new FormRequestWrapper(request, form));
}
- catch (OAuthProblemException e) {
- throw responseHandler.throwit(e);
+ else {
+ oAuthRequest = new OAuthUnauthenticatedTokenRequest(
+ new FormRequestWrapper(request, form));
}
- OAuthResponse oAuthResponse = oauth2Service
- .requestAccessToken(oAuthRequest, authorization);
+ OAuthResponse oAuthResponse =
+ oAuth2Service.requestAccessToken(oAuthRequest);
return responseHandler.createResponse(oAuthResponse);
}
catch (KustvaktException e) {
throw responseHandler.throwit(e);
}
+ catch (OAuthProblemException e) {
+ throw responseHandler.throwit(e);
+ }
catch (OAuthSystemException e) {
throw responseHandler.throwit(e);
}
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 9c4834c..39b93b7 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
@@ -1,17 +1,21 @@
package de.ids_mannheim.korap.web.controller;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
-import javax.ws.rs.HeaderParam;
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.SecurityContext;
+import org.apache.oltu.oauth2.as.request.OAuthRequest;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@@ -19,12 +23,14 @@
import de.ids_mannheim.korap.dto.OAuth2ClientDto;
import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth.OAuthDeregisterClientRequest;
import de.ids_mannheim.korap.security.context.TokenContext;
import de.ids_mannheim.korap.service.OAuth2ClientService;
import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
import de.ids_mannheim.korap.web.filter.BlockingFilter;
import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
+import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
/** Defines controllers for OAuth2 clients, namely applications attempting
@@ -111,14 +117,25 @@
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response deregisterConfidentialClient (
@Context SecurityContext securityContext,
- @HeaderParam("Authorization") String authorization,
- @FormParam("client_id") String clientId) {
+ // @HeaderParam("Authorization") String authorization,
+ // @FormParam("client_id") String clientId
+ @Context HttpServletRequest request,
+ MultivaluedMap<String, String> form) {
try {
- clientService.deregisterConfidentialClient(authorization, clientId);
+ OAuthRequest oAuthRequest = new OAuthDeregisterClientRequest(
+ new FormRequestWrapper(request, form));
+
+ clientService.deregisterConfidentialClient(oAuthRequest);
return Response.ok().build();
}
catch (KustvaktException e) {
throw responseHandler.throwit(e);
}
+ catch (OAuthSystemException e) {
+ throw responseHandler.throwit(e);
+ }
+ catch (OAuthProblemException e) {
+ throw responseHandler.throwit(e);
+ }
}
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index e64bcfe..c6a3a97 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -233,7 +233,7 @@
* @param pageLength number of results per page
* @param pageIndex
* @param startPage
- * @param cq collection query
+ * @param cq corpus query
* @return
*/
// ref query parameter removed!
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
index 2dc4034..99705e8 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
@@ -20,4 +20,5 @@
// redirect URI determines where the OAuth 2.0 service will return the user to
// after they have authorized a client. It must be https.
private String redirectURI;
+ private String description;
}
diff --git a/full/src/main/resources/db/insert/V3.5__insert_oauth2_clients.sql b/full/src/main/resources/db/insert/V3.5__insert_oauth2_clients.sql
index 3cc2999..f9cd171 100644
--- a/full/src/main/resources/db/insert/V3.5__insert_oauth2_clients.sql
+++ b/full/src/main/resources/db/insert/V3.5__insert_oauth2_clients.sql
@@ -2,21 +2,33 @@
-- plain secret value is "secret"
INSERT INTO oauth2_client(id,name,secret,type,native, url,url_hashcode,
- redirect_uri,registered_by)
-VALUES ("fCBbQkAyYzI4NzUxMg==","test confidential client",
+ redirect_uri,registered_by, description)
+VALUES ("fCBbQkAyYzI4NzUxMg","test confidential client",
"$2a$08$vi1FbuN3p6GcI1tSxMAoeuIYL8Yw3j6A8wJthaN8ZboVnrQaTwLPq",
"CONFIDENTIAL", 1, "http://korap.ids-mannheim.de/confidential", 2087150261,
- "https://korap.ids-mannheim.de/confidential/redirect", "system");
+ "https://korap.ids-mannheim.de/confidential/redirect", "system",
+ "This is a test native confidential client.");
+
+-- plain secret value is "secret"
+INSERT INTO oauth2_client(id,name,secret,type,native, url,url_hashcode,
+ redirect_uri,registered_by, description)
+VALUES ("9aHsGW6QflV13ixNpez","test non native confidential client",
+ "$2a$08$vi1FbuN3p6GcI1tSxMAoeuIYL8Yw3j6A8wJthaN8ZboVnrQaTwLPq",
+ "CONFIDENTIAL", 0, "http://third.party.com/confidential", 1712550103,
+ "https://third.party.com/confidential/redirect", "system",
+ "This is a test nonnative confidential client.");
INSERT INTO oauth2_client(id,name,secret,type,url,url_hashcode,
- redirect_uri, registered_by)
-VALUES ("8bIDtZnH6NvRkW2Fq==","third party client",null,
+ redirect_uri, registered_by, description)
+VALUES ("8bIDtZnH6NvRkW2Fq","third party client",null,
"PUBLIC","http://third.party.client.com", -2137275617,
- "https://third.party.client.com/redirect","system");
+ "https://third.party.client.com/redirect","system",
+ "This is a test nonnative public client.");
INSERT INTO oauth2_client(id,name,secret,type,native,url,url_hashcode,
- redirect_uri, registered_by)
+ redirect_uri, registered_by, description)
VALUES ("iBr3LsTCxOj7D2o0A5m","test public client",null,
"PUBLIC", 1, "http://korap.ids-mannheim.de/public", 1360724310,
- "https://korap.ids-mannheim.de/public/redirect","system");
+ "https://korap.ids-mannheim.de/public/redirect","system",
+ "This is a test native public client.");
\ No newline at end of file
diff --git a/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql b/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql
index c55ef43..81b0d92 100644
--- a/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql
+++ b/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql
@@ -10,7 +10,8 @@
url TEXT NOT NULL,
url_hashcode UNIQUE INTEGER NOT NULL,
redirect_uri TEXT NOT NULL,
- registered_by VARCHAR(100) NOT NULL
+ registered_by VARCHAR(100) NOT NULL,
+ description VARCHAR(250) NOT NULL
);
--
diff --git a/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql b/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
index 89014f2..c055f4d 100644
--- a/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
+++ b/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
@@ -10,7 +10,8 @@
url TEXT NOT NULL,
url_hashcode INTEGER NOT NULL,
redirect_uri TEXT NOT NULL,
- registered_by VARCHAR(100) NOT NULL
+ registered_by VARCHAR(100) NOT NULL,
+ description VARCHAR(250) NOT NULL
);
CREATE UNIQUE INDEX client_id_index on oauth2_client(id);
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index feef295..57f65ae 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -184,10 +184,17 @@
<bean id="kustvaktResponseHandler" class="de.ids_mannheim.korap.web.KustvaktExceptionHandler">
<constructor-arg index="0" name="iface" ref="kustvakt_auditing" />
</bean>
- <bean id="oauth2_exception" class="de.ids_mannheim.korap.web.OAuth2ExceptionHandler">
+
+ <!-- OAuth -->
+ <bean id="oauth2ResponseHandler" class="de.ids_mannheim.korap.web.OAuth2ResponseHandler">
<constructor-arg index="0" name="iface" ref="kustvakt_auditing" />
</bean>
-
+
+ <bean id="mdGenerator" class="org.apache.oltu.oauth2.as.issuer.MD5Generator">
+ </bean>
+ <bean id="oauthIssuer" class="org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl">
+ <constructor-arg index="0" ref="mdGenerator" />
+ </bean>
<bean id="kustvakt_userdb" class="de.ids_mannheim.korap.handlers.EntityDao">
<constructor-arg ref="kustvakt_db" />
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
index 66d610f..b194e08 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
@@ -62,6 +62,7 @@
json.setType(OAuth2ClientType.CONFIDENTIAL);
json.setUrl("http://example.client.com");
json.setRedirectURI("https://example.client.com/redirect");
+ json.setDescription("This is a confidential test client.");
return resource().path("oauth2").path("client").path("register")
.header(Attributes.AUTHORIZATION,
@@ -89,8 +90,9 @@
assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
node.at("/error").asText());
+ testDeregisterConfidentialClientMissingParameters();
testDeregisterClientIncorrectCredentials(clientId);
- testDeregisterConfidentialClient(clientId, clientSecret);
+ testDeregisterConfidentialClient(clientId,clientSecret);
}
@Test
@@ -101,6 +103,7 @@
json.setType(OAuth2ClientType.PUBLIC);
json.setUrl("http://test.public.client.com");
json.setRedirectURI("https://test.public.client.com/redirect");
+ json.setDescription("This is a public test client.");
ClientResponse response = resource().path("oauth2").path("client")
.path("register")
@@ -129,6 +132,7 @@
json.setType(OAuth2ClientType.PUBLIC);
json.setUrl("http://korap.ids-mannheim.de/native");
json.setRedirectURI("https://korap.ids-mannheim.de/native/redirect");
+ json.setDescription("This is a native test client.");
ClientResponse response = resource().path("oauth2").path("client")
.path("register")
@@ -140,7 +144,7 @@
.entity(json).post(ClientResponse.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
+
//EM: need to check native
}
@@ -167,8 +171,6 @@
private void testDeregisterConfidentialClient (String clientId,
String clientSecret) throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
- MultivaluedMap<String, String> form = new MultivaluedMapImpl();
- form.add("client_id", clientId);
ClientResponse response = resource().path("oauth2").path("client")
.path("deregister").path("confidential")
@@ -178,16 +180,34 @@
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.header(HttpHeaders.CONTENT_TYPE,
ContentType.APPLICATION_FORM_URLENCODED)
- .entity(form).delete(ClientResponse.class);
+ .delete(ClientResponse.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
}
+ private void testDeregisterConfidentialClientMissingParameters ()
+ throws KustvaktException {
+
+ ClientResponse response = resource().path("oauth2").path("client")
+ .path("deregister").path("confidential")
+ .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .delete(ClientResponse.class);
+
+ 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());
+ assertEquals("Missing parameters: client_secret client_id",
+ node.at("/error_description").asText());
+ }
+
private void testDeregisterClientIncorrectCredentials (String clientId)
throws UniformInterfaceException, ClientHandlerException,
KustvaktException {
- MultivaluedMap<String, String> form = new MultivaluedMapImpl();
- form.add("client_id", clientId);
ClientResponse response = resource().path("oauth2").path("client")
.path("deregister").path("confidential")
@@ -197,7 +217,7 @@
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.header(HttpHeaders.CONTENT_TYPE,
ContentType.APPLICATION_FORM_URLENCODED)
- .entity(form).delete(ClientResponse.class);
+ .delete(ClientResponse.class);
String entity = response.getEntity(String.class);
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
@@ -205,7 +225,7 @@
JsonNode node = JsonUtils.readTree(entity);
assertEquals(OAuthError.TokenResponse.INVALID_CLIENT,
node.at("/error").asText());
- assertEquals("Invalid client credentials.",
+ assertEquals("Invalid client credentials",
node.at("/error_description").asText());
checkWWWAuthenticateHeader(response);
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 956e3ed..3214fda 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
@@ -2,6 +2,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response.Status;
@@ -14,9 +17,7 @@
import com.fasterxml.jackson.databind.JsonNode;
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;
@@ -34,24 +35,99 @@
@Autowired
private HttpAuthorizationHandler handler;
- private ClientResponse testRequestTokenConfidentialClient (
- MultivaluedMap<String, String> form)
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
- return resource().path("oauth2").path("token")
+ private ClientResponse requestAuthorizationConfidentialClient (
+ MultivaluedMap<String, String> form) throws KustvaktException {
+
+ return resource().path("oauth2").path("authorize")
.header(Attributes.AUTHORIZATION,
handler.createBasicAuthorizationHeaderValue(
- "fCBbQkAyYzI4NzUxMg==", "secret"))
+ "fCBbQkAyYzI4NzUxMg", "secret"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.header(HttpHeaders.CONTENT_TYPE,
ContentType.APPLICATION_FORM_URLENCODED)
.entity(form).post(ClientResponse.class);
}
- private ClientResponse testRequestTokenPublicClient (
- MultivaluedMap<String, String> form)
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ @Test
+ public void testAuthorizeConfidentialClient () 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");
+ ClientResponse response = requestAuthorizationConfidentialClient(form);
+
+ assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
+ response.getStatus());
+ URI redirectUri = response.getLocation();
+ assertTrue(redirectUri.getQuery().startsWith("code"));
+ }
+
+ @Test
+ public void testAuthorizeInvalidRedirectUri () throws KustvaktException {
+ String redirectUri = "https://different.uri/redirect";
+
+ 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("redirect_uri", redirectUri);
+ ClientResponse response = requestAuthorizationConfidentialClient(form);
+
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
+ node.at("/error").asText());
+ assertEquals(redirectUri + " is unknown",
+ node.at("/error_description").asText());
+ }
+
+ @Test
+ public void testAuthorizeMissingRequiredParameters ()
+ throws KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ // missing code
+ ClientResponse response = requestAuthorizationConfidentialClient(form);
+
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
+ node.at("/error").asText());
+ assertEquals("Missing response_type parameter value",
+ node.at("/error_description").asText());
+
+ // missing client_id
+ form.add("response_type", "code");
+ response = requestAuthorizationConfidentialClient(form);
+ entity = response.getEntity(String.class);
+ node = JsonUtils.readTree(entity);
+ assertEquals("Missing parameters: client_id",
+ node.at("/error_description").asText());
+ }
+
+ @Test
+ public void testAuthorizeInvalidResponseType () throws KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("response_type", "string");
+
+ ClientResponse response = requestAuthorizationConfidentialClient(form);
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
+ node.at("/error").asText());
+ assertEquals("Invalid response_type parameter value",
+ node.at("/error_description").asText());
+ }
+
+ private ClientResponse requestToken (MultivaluedMap<String, String> form)
+ throws KustvaktException {
return resource().path("oauth2").path("token")
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.header(HttpHeaders.CONTENT_TYPE,
@@ -61,12 +137,15 @@
@Test
public void testRequestTokenPasswordGrantConfidential ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("grant_type", "password");
+ form.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ form.add("client_secret", "secret");
+ form.add("username", "dory");
+ form.add("password", "password");
- ClientResponse response = testRequestTokenConfidentialClient(form);
+ ClientResponse response = requestToken(form);
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
@@ -78,71 +157,80 @@
}
@Test
- public void testRequestTokenConfidentialMissingSecret ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ public void testRequestTokenPasswordGrantMissingClientSecret ()
+ throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("grant_type", "password");
- form.add("client_id", "fCBbQkAyYzI4NzUxMg==");
+ form.add("username", "dory");
+ form.add("password", "password");
+ form.add("client_id", "fCBbQkAyYzI4NzUxMg");
- ClientResponse response = testRequestTokenPublicClient(form);
- assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+ ClientResponse response = requestToken(form);
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
- assertEquals(OAuthError.TokenResponse.INVALID_CLIENT,
+ assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
node.at("/error").asText());
- }
-
- @Test
- public void testRequestTokenPasswordGrantPublic ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
- MultivaluedMap<String, String> form = new MultivaluedMapImpl();
- form.add("grant_type", "password");
- form.add("client_id", "iBr3LsTCxOj7D2o0A5m");
-
- ClientResponse response = testRequestTokenPublicClient(form);
- String entity = response.getEntity(String.class);
-
- JsonNode node = JsonUtils.readTree(entity);
- 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("Missing parameters: client_secret",
+ node.at("/error_description").asText());
}
@Test
public void testRequestTokenPasswordGrantMissingClientId ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("grant_type", "password");
+ form.add("username", "dory");
+ form.add("password", "password");
+ form.add("client_secret", "secret");
- ClientResponse response = testRequestTokenPublicClient(form);
+ 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_REQUEST,
node.at("/error").asText());
- assertEquals("client_id is missing",
+ assertEquals("Missing parameters: client_id",
node.at("/error_description").asText());
}
+
+ @Test
+ public void testRequestTokenPasswordGrantPublic ()
+ throws KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("grant_type", "password");
+ form.add("username", "dory");
+ form.add("password", "password");
+ form.add("client_id", "iBr3LsTCxOj7D2o0A5m");
+
+ ClientResponse response = requestToken(form);
+ String entity = response.getEntity(String.class);
+
+ JsonNode node = JsonUtils.readTree(entity);
+ 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());
+ }
@Test
public void testRequestTokenPasswordGrantNonNative ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("grant_type", "password");
- form.add("client_id", "8bIDtZnH6NvRkW2Fq==");
+ form.add("username", "dory");
+ form.add("password", "password");
+ // confidential nonnative
+ form.add("client_id", "9aHsGW6QflV13ixNpez");
+ form.add("client_secret", "secret");
- ClientResponse response = testRequestTokenPublicClient(form);
+ ClientResponse response = requestToken(form);
String entity = response.getEntity(String.class);
- assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
JsonNode node = JsonUtils.readTree(entity);
assertEquals(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT,
@@ -153,13 +241,13 @@
@Test
public void testRequestTokenClientCredentialsGrant ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("grant_type", "client_credentials");
-
- ClientResponse response = testRequestTokenConfidentialClient(form);
+ form.add("client_id", "fCBbQkAyYzI4NzUxMg");
+ form.add("client_secret", "secret");
+ ClientResponse response = requestToken(form);
String entity = response.getEntity(String.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -173,11 +261,9 @@
}
@Test
- public void testRequestTokenMissingGrantType ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ public void testRequestTokenMissingGrantType () throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
- ClientResponse response = testRequestTokenConfidentialClient(form);
+ ClientResponse response = requestToken(form);
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
String entity = response.getEntity(String.class);
@@ -187,9 +273,7 @@
}
@Test
- public void testRequestTokenUnsupportedGrant ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ public void testRequestTokenUnsupportedGrant () throws KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("grant_type", "blahblah");
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index 0445d65..c0f7a2e 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -167,10 +167,10 @@
<!-- URLValidator -->
<bean id="urlValidator" class="org.apache.commons.validator.routines.UrlValidator">
- <constructor-arg value="http,https"/>
+ <constructor-arg value="http,https" />
</bean>
<bean id="httpsValidator" class="org.apache.commons.validator.routines.UrlValidator">
- <constructor-arg value="https"/>
+ <constructor-arg value="https" />
</bean>
<bean id="kustvakt_rewrite" class="de.ids_mannheim.korap.rewrite.FullRewriteHandler">
@@ -184,10 +184,18 @@
<bean id="kustvaktExceptionHandler" class="de.ids_mannheim.korap.web.KustvaktExceptionHandler">
<constructor-arg index="0" name="iface" ref="kustvakt_auditing" />
</bean>
+
+ <!-- OAuth -->
<bean id="oauth2ResponseHandler" class="de.ids_mannheim.korap.web.OAuth2ResponseHandler">
<constructor-arg index="0" name="iface" ref="kustvakt_auditing" />
</bean>
+ <bean id="mdGenerator" class="org.apache.oltu.oauth2.as.issuer.MD5Generator">
+ </bean>
+ <bean id="oauthIssuer" class="org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl">
+ <constructor-arg index="0" ref="mdGenerator" />
+ </bean>
+
<bean id="kustvakt_userdb" class="de.ids_mannheim.korap.handlers.EntityDao">
<constructor-arg ref="kustvakt_db" />
</bean>
@@ -200,8 +208,7 @@
<constructor-arg ref="kustvakt_db" />
</bean>
- <bean name="kustvakt_encryption"
- class="de.ids_mannheim.korap.encryption.KustvaktEncryption">
+ <bean name="kustvakt_encryption" class="de.ids_mannheim.korap.encryption.KustvaktEncryption">
<constructor-arg ref="kustvakt_config" />
</bean>
@@ -267,8 +274,8 @@
<!-- specify type for constructor argument -->
<bean id="kustvakt_authenticationmanager"
class="de.ids_mannheim.korap.authentication.KustvaktAuthenticationManager">
- <constructor-arg
- type="de.ids_mannheim.korap.interfaces.EntityHandlerIface" ref="kustvakt_userdb" />
+ <constructor-arg type="de.ids_mannheim.korap.interfaces.EntityHandlerIface"
+ ref="kustvakt_userdb" />
<constructor-arg type="de.ids_mannheim.korap.interfaces.EncryptionIface"
ref="kustvakt_encryption" />
<constructor-arg ref="kustvakt_config" />
@@ -309,8 +316,8 @@
<!-- mail -->
<bean id="authenticator" class="de.ids_mannheim.korap.service.MailAuthenticator">
- <constructor-arg index="0" value="${mail.username}"/>
- <constructor-arg index="1" value="${mail.password}"/>
+ <constructor-arg index="0" value="${mail.username}" />
+ <constructor-arg index="1" value="${mail.password}" />
</bean>
<bean id="smtpSession" class="javax.mail.Session" factory-method="getInstance">
<constructor-arg index="0">
@@ -323,7 +330,7 @@
<prop key="mail.smtp.connectiontimeout">${mail.connectiontimeout}</prop>
</props>
</constructor-arg>
- <constructor-arg index="1" ref="authenticator"/>
+ <constructor-arg index="1" ref="authenticator" />
</bean>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="session" ref="smtpSession" />