mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
[Task 70131] added support for the login as feature and added simple test
This commit is contained in:
@@ -8,18 +8,27 @@
|
||||
package org.dspace.app.rest.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||
import org.dspace.app.rest.utils.ContextUtil;
|
||||
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.services.RequestService;
|
||||
import org.dspace.util.UUIDUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
@@ -37,12 +46,19 @@ public class StatelessAuthenticationFilter extends BasicAuthenticationFilter {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(StatelessAuthenticationFilter.class);
|
||||
|
||||
private static final String ON_BEHALF_OF_REQUEST_PARAM = "X-On-Behalf-Of";
|
||||
private static final String ADMIN = "ADMIN";
|
||||
|
||||
private RestAuthenticationService restAuthenticationService;
|
||||
|
||||
private EPersonRestAuthenticationProvider authenticationProvider;
|
||||
|
||||
private RequestService requestService;
|
||||
|
||||
private AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||
|
||||
private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||
|
||||
public StatelessAuthenticationFilter(AuthenticationManager authenticationManager,
|
||||
RestAuthenticationService restAuthenticationService,
|
||||
EPersonRestAuthenticationProvider authenticationProvider,
|
||||
@@ -81,6 +97,10 @@ public class StatelessAuthenticationFilter extends BasicAuthenticationFilter {
|
||||
|
||||
//Get the Spring authorities for this eperson
|
||||
List<GrantedAuthority> authorities = authenticationProvider.getGrantedAuthorities(context, eperson);
|
||||
String onBehalfOfParameterValue = request.getHeader(ON_BEHALF_OF_REQUEST_PARAM);
|
||||
if (onBehalfOfParameterValue != null) {
|
||||
return getOnBehalfOfAuthentication(context, onBehalfOfParameterValue);
|
||||
}
|
||||
|
||||
//Return the Spring authentication object
|
||||
return new DSpaceAuthentication(eperson.getEmail(), authorities);
|
||||
@@ -92,4 +112,33 @@ public class StatelessAuthenticationFilter extends BasicAuthenticationFilter {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Authentication getOnBehalfOfAuthentication(Context context, String onBehalfOfParameterValue) {
|
||||
UUID epersonUuid = UUIDUtils.fromString(onBehalfOfParameterValue);
|
||||
if (epersonUuid == null) {
|
||||
throw new DSpaceBadRequestException("The parameter value of " + ON_BEHALF_OF_REQUEST_PARAM +
|
||||
" was not a proper UUID");
|
||||
}
|
||||
try {
|
||||
EPerson onBehalfOfEPerson = ePersonService.find(context, epersonUuid);
|
||||
if (onBehalfOfEPerson == null) {
|
||||
throw new DSpaceBadRequestException("The parameter value of " + ON_BEHALF_OF_REQUEST_PARAM +
|
||||
" was not a proper EPerson UUID");
|
||||
}
|
||||
if (authorizeService.isAdmin(context)) {
|
||||
requestService.setCurrentUserId(epersonUuid);
|
||||
context.switchContextUser(onBehalfOfEPerson);
|
||||
return new DSpaceAuthentication(onBehalfOfEPerson.getEmail(),
|
||||
authenticationProvider.getGrantedAuthorities(context,
|
||||
onBehalfOfEPerson));
|
||||
} else {
|
||||
throw new AccessDeniedException("The current EPerson was not an admin and " +
|
||||
"cannot use the on behalf of functionality");
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.dspace.app.rest.matcher.EPersonMatcher;
|
||||
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LoginAsEPersonIT extends AbstractControllerIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void loggedInUserRetrievalTest() throws Exception {
|
||||
|
||||
String token = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(token).perform(get("/api/authn/status")
|
||||
.param("projection", "full"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson", EPersonMatcher.matchEPersonOnEmail(admin.getEmail())));
|
||||
|
||||
|
||||
}
|
||||
@Test
|
||||
public void loggedInAsOtherUserRetrievalTest() throws Exception {
|
||||
|
||||
String token = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(token).perform(get("/api/authn/status")
|
||||
.param("projection", "full")
|
||||
.header("X-On-Behalf-Of", eperson.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson",
|
||||
EPersonMatcher.matchEPersonOnEmail(eperson.getEmail())));
|
||||
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user