Implemented mapping of LDAP username to email.
Change-Id: Ifb1d2969c6dfafe768b99524de8303277184a94d
diff --git a/full/Changes b/full/Changes
index 200fc74..b74fca3 100644
--- a/full/Changes
+++ b/full/Changes
@@ -1,5 +1,9 @@
# version 0.67.1
+2022-05-12
+ - Implemented mapping of LDAP username to email
+
+
# version 0.67
2022-05-09
@@ -8,6 +12,7 @@
2022-05-11
- Changed the SQL script updating oauth2_client table
+
# version 0.66
2022-03-31
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 c135506..fefa17c 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
@@ -438,9 +438,9 @@
User unknown = null;
// just to make sure that the plain password does not appear anywhere in
// the logs!
-
- System.out.printf("Debug: authenticateIdM: entering for '%s'...\n", username);
-
+ if (DEBUG){
+ jlog.debug("Debug: authenticateIdM: entering for '%s'...\n", username);
+ }
/**
* wozu Apache Validatoren für User/Passwort für IdM/LDAP? siehe
* validation.properties. Abgeschaltet 21.04.17/FB try {
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuTokenService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuTokenService.java
index c4dd257..786398f 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuTokenService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/oltu/service/OltuTokenService.java
@@ -21,7 +21,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import com.unboundid.ldap.sdk.LDAPException;
+
+import de.ids_mannheim.korap.authentication.LdapAuth3;
import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
import de.ids_mannheim.korap.encryption.RandomCodeGenerator;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.exceptions.StatusCodes;
@@ -262,6 +266,18 @@
Set<AccessScope> accessScopes =
scopeService.convertToAccessScope(scopes);
+
+ if (config.getOAuth2passwordAuthentication()
+ .equals(AuthenticationMethod.LDAP)) {
+ try {
+ username = LdapAuth3.getEmail(username, config.getLdapConfig());
+ }
+ catch (LDAPException e) {
+ throw new KustvaktException(StatusCodes.LDAP_BASE_ERRCODE,
+ e.getExceptionMessage());
+ }
+ }
+
return createsAccessTokenResponse(scopes, accessScopes, clientId,
username, authenticationTime,
false);
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java
index c926579..65322d9 100644
--- a/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java
@@ -53,7 +53,7 @@
}
@AfterClass
- public static void ShutDownDirectoryServer() {
+ public static void shutDownDirectoryServer() {
server.shutDown(true);
}
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/LdapOAuth2Test.java b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapOAuth2Test.java
new file mode 100644
index 0000000..48f6193
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapOAuth2Test.java
@@ -0,0 +1,198 @@
+package de.ids_mannheim.korap.authentication;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.URI;
+import java.security.GeneralSecurityException;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.http.entity.ContentType;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.util.UriComponentsBuilder;
+
+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.unboundid.ldap.sdk.LDAPException;
+
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.FullConfiguration;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.constant.OAuth2ClientType;
+import de.ids_mannheim.korap.oauth2.dao.AccessTokenDao;
+import de.ids_mannheim.korap.oauth2.dao.OAuth2ClientDao;
+import de.ids_mannheim.korap.oauth2.dao.RefreshTokenDao;
+import de.ids_mannheim.korap.oauth2.entity.AccessToken;
+import de.ids_mannheim.korap.oauth2.entity.OAuth2Client;
+import de.ids_mannheim.korap.oauth2.entity.RefreshToken;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.web.controller.OAuth2TestBase;
+import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
+
+public class LdapOAuth2Test extends OAuth2TestBase {
+
+ @Autowired
+ private FullConfiguration config;
+ @Autowired
+ private AccessTokenDao accessDao;
+ @Autowired
+ private RefreshTokenDao refreshDao;
+ @Autowired
+ private OAuth2ClientDao clientDao;
+
+ private String testUserEmail = "testuser@example.com";
+ private String redirectUri = "https://client.com/redirect";
+
+ @BeforeClass
+ public static void startTestLDAPServer ()
+ throws LDAPException, GeneralSecurityException {
+ LdapAuth3Test.startDirectoryServer();
+
+ }
+
+ @AfterClass
+ public static void stopTestLDAPServer () {
+ LdapAuth3Test.shutDownDirectoryServer();
+ }
+
+ @Before
+ public void setLDAPAuthentication () {
+ config.setOAuth2passwordAuthentication(AuthenticationMethod.LDAP);
+ }
+
+ @After
+ public void resetAuthenticationMethod () {
+ config.setOAuth2passwordAuthentication(AuthenticationMethod.TEST);
+ }
+
+ @Test
+ public void testRequestTokenPasswordUnknownUser ()
+ throws KustvaktException {
+
+ ClientResponse response = requestTokenWithPassword(superClientId,
+ clientSecret, "unknown", "password");
+
+ assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+
+ assertEquals(2023, node.at("/errors/0/0").asInt());
+ assertEquals(
+ "LDAP Authentication failed due to unknown user or password!",
+ node.at("/errors/0/1").asText());
+ }
+
+ @Test
+ public void testMapUsernameToEmail () throws KustvaktException {
+ ClientResponse response = requestTokenWithPassword(superClientId,
+ clientSecret, "testUser", "password");
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+
+ String accessToken = node.at("/access_token").asText();
+ AccessToken accessTokenObj = accessDao.retrieveAccessToken(accessToken);
+ assertEquals(testUserEmail, accessTokenObj.getUserId());
+
+ String refreshToken = node.at("/refresh_token").asText();
+ RefreshToken rt = refreshDao.retrieveRefreshToken(refreshToken);
+ assertEquals(testUserEmail, rt.getUserId());
+
+ testRegisterPublicClient(accessToken);
+ node = testRegisterConfidentialClient(accessToken);
+ String clientId = node.at("/client_id").asText();
+ String clientSecret = node.at("/client_secret").asText();
+
+ testRequestTokenWithAuthorization(clientId, clientSecret, accessToken);
+ }
+
+ private void testRegisterPublicClient (String accessToken)
+ throws ClientHandlerException, UniformInterfaceException,
+ KustvaktException {
+ OAuth2ClientJson json = new OAuth2ClientJson();
+ json.setName("LDAP test client");
+ json.setType(OAuth2ClientType.PUBLIC);
+ json.setDescription(
+ "Test registering a public client with LDAP authentication");
+
+ ClientResponse response = resource().path(API_VERSION).path("oauth2")
+ .path("client").path("register")
+ .header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
+ .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+ .entity(json).post(ClientResponse.class);
+
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+ String clientId = node.at("/client_id").asText();
+ OAuth2Client client = clientDao.retrieveClientById(clientId);
+ assertEquals(testUserEmail, client.getRegisteredBy());
+ }
+
+ private JsonNode testRegisterConfidentialClient (String accessToken)
+ throws ClientHandlerException, UniformInterfaceException,
+ KustvaktException {
+ OAuth2ClientJson json = new OAuth2ClientJson();
+ json.setName("LDAP test client");
+ json.setType(OAuth2ClientType.CONFIDENTIAL);
+ json.setRedirectURI(redirectUri);
+ json.setDescription(
+ "Test registering a confidential client with LDAP authentication");
+
+ ClientResponse response = resource().path(API_VERSION).path("oauth2")
+ .path("client").path("register")
+ .header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
+ .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+ .entity(json).post(ClientResponse.class);
+
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+ String clientId = node.at("/client_id").asText();
+ OAuth2Client client = clientDao.retrieveClientById(clientId);
+ assertEquals(testUserEmail, client.getRegisteredBy());
+ return node;
+ }
+
+ private void testRequestTokenWithAuthorization (String clientId,
+ String clientSecret, String accessToken) throws KustvaktException {
+ String authHeader = "Bearer " + accessToken;
+ ClientResponse response = resource().path(API_VERSION).path("oauth2")
+ .path("authorize")
+ .queryParam("response_type", "code")
+ .queryParam("client_id", clientId)
+ .queryParam("client_secret", clientSecret)
+ .header(Attributes.AUTHORIZATION, authHeader)
+ .get(ClientResponse.class);
+
+ assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
+ response.getStatus());
+ URI redirectUri = response.getLocation();
+
+ MultiValueMap<String, String> params = UriComponentsBuilder
+ .fromUri(redirectUri).build().getQueryParams();
+ String code = params.getFirst("code");
+
+ response = requestTokenWithAuthorizationCodeAndForm(clientId, clientSecret, code);
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+
+ String at = node.at("/access_token").asText();
+ AccessToken accessTokenObj = accessDao.retrieveAccessToken(at);
+ assertEquals(testUserEmail, accessTokenObj.getUserId());
+
+ String refreshToken = node.at("/refresh_token").asText();
+ RefreshToken rt = refreshDao.retrieveRefreshToken(refreshToken);
+ assertEquals(testUserEmail, rt.getUserId());
+ }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/LdapTest.java b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapTest.java
deleted file mode 100644
index 8ddb5d8..0000000
--- a/full/src/test/java/de/ids_mannheim/korap/authentication/LdapTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package de.ids_mannheim.korap.authentication;
-
-import static org.junit.Assert.assertEquals;
-
-import javax.ws.rs.core.Response.Status;
-
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.sun.jersey.api.client.ClientResponse;
-
-import de.ids_mannheim.korap.config.FullConfiguration;
-import de.ids_mannheim.korap.constant.AuthenticationMethod;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.web.controller.OAuth2TestBase;
-
-public class LdapTest extends OAuth2TestBase {
-
- @Autowired
- private FullConfiguration config;
-
- @Test
- public void testRequestTokenPasswordUnknownUser ()
- throws KustvaktException {
-
- config.setOAuth2passwordAuthentication(AuthenticationMethod.LDAP);
- ClientResponse response = requestTokenWithPassword(superClientId,
- clientSecret, "unknown", "password");
-
- assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-
- String entity = response.getEntity(String.class);
- JsonNode node = JsonUtils.readTree(entity);
- assertEquals(2022, node.at("/errors/0/0").asInt());
- assertEquals(
- "LDAP Authentication failed due to unknown user or password!",
- node.at("/errors/0/1").asText());
- config.setOAuth2passwordAuthentication(AuthenticationMethod.TEST);
- }
-}