
org.dspace.authenticate.AuthenticationServiceImpl Maven / Gradle / Ivy
Show all versions of dspace-api Show documentation
/**
* 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.authenticate;
import java.sql.SQLException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.authenticate.service.AuthenticationService;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.core.factory.CoreServiceFactory;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.EPersonService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Access point for the stackable authentication methods.
*
* This class initializes the "stack" from the DSpace configuration,
* and then invokes methods in the appropriate order on behalf of clients.
*
* See the AuthenticationMethod interface for details about what each
* function does.
*
* Configuration
* The stack of authentication methods is defined by one property in the DSpace configuration:
*
* plugin.sequence.org.dspace.eperson.AuthenticationMethod = a list of method class names
* e.g.
* plugin.sequence.org.dspace.eperson.AuthenticationMethod = \
* org.dspace.eperson.X509Authentication, \
* org.dspace.eperson.PasswordAuthentication
*
*
* The "stack" is always traversed in order, with the methods
* specified first (in the configuration) thus getting highest priority.
*
* @author Larry Stone
* @see AuthenticationMethod
*/
public class AuthenticationServiceImpl implements AuthenticationService {
/**
* Logging category
*/
private final Logger log = LogManager.getLogger();
@Autowired(required = true)
protected EPersonService ePersonService;
protected AuthenticationServiceImpl() {
}
public List getAuthenticationMethodStack() {
return Arrays.asList((AuthenticationMethod[]) CoreServiceFactory.getInstance().getPluginService()
.getPluginSequence(AuthenticationMethod.class));
}
@Override
public int authenticate(Context context,
String username,
String password,
String realm,
HttpServletRequest request) {
return authenticateInternal(context, username, password, realm,
request, false);
}
@Override
public int authenticateImplicit(Context context,
String username,
String password,
String realm,
HttpServletRequest request) {
return authenticateInternal(context, username, password, realm,
request, true);
}
protected int authenticateInternal(Context context,
String username,
String password,
String realm,
HttpServletRequest request,
boolean implicitOnly) {
// better is lowest, so start with the highest.
int bestRet = AuthenticationMethod.BAD_ARGS;
// return on first success, otherwise "best" outcome.
for (AuthenticationMethod aMethodStack : getAuthenticationMethodStack()) {
if (!implicitOnly || aMethodStack.isImplicit()) {
int ret = 0;
try {
ret = aMethodStack.authenticate(context, username, password, realm, request);
} catch (SQLException e) {
ret = AuthenticationMethod.NO_SUCH_USER;
}
if (ret == AuthenticationMethod.SUCCESS) {
updateLastActiveDate(context);
return ret;
}
if (ret < bestRet) {
bestRet = ret;
}
}
}
return bestRet;
}
@Override
public void updateLastActiveDate(Context context) {
EPerson me = context.getCurrentUser();
if (me != null) {
me.setLastActive(Instant.now());
try {
ePersonService.update(context, me);
} catch (SQLException ex) {
log.error("Could not update last-active stamp", ex);
} catch (AuthorizeException ex) {
log.error("Could not update last-active stamp", ex);
}
}
}
@Override
public boolean canSelfRegister(Context context,
HttpServletRequest request,
String username)
throws SQLException {
for (AuthenticationMethod method : getAuthenticationMethodStack()) {
if (method.canSelfRegister(context, request, username)) {
return true;
}
}
return false;
}
@Override
public boolean allowSetPassword(Context context,
HttpServletRequest request,
String username)
throws SQLException {
for (AuthenticationMethod method : getAuthenticationMethodStack()) {
if (method.allowSetPassword(context, request, username)) {
return true;
}
}
return false;
}
@Override
public void initEPerson(Context context,
HttpServletRequest request,
EPerson eperson)
throws SQLException {
for (AuthenticationMethod method : getAuthenticationMethodStack()) {
method.initEPerson(context, request, eperson);
}
}
@Override
public List getSpecialGroups(Context context,
HttpServletRequest request)
throws SQLException {
List result = new ArrayList<>();
int totalLen = 0;
for (AuthenticationMethod method : getAuthenticationMethodStack()) {
if (method.areSpecialGroupsApplicable(context, request)) {
List gl = method.getSpecialGroups(context, request);
if (gl.size() > 0) {
result.addAll(gl);
totalLen += gl.size();
}
}
}
return result;
}
@Override
public Iterator authenticationMethodIterator() {
return getAuthenticationMethodStack().iterator();
}
@Override
public String getAuthenticationMethod(final Context context, final HttpServletRequest request) {
final Iterator authenticationMethodIterator = authenticationMethodIterator();
while (authenticationMethodIterator.hasNext()) {
final AuthenticationMethod authenticationMethod = authenticationMethodIterator.next();
if (authenticationMethod.isUsed(context, request)) {
return authenticationMethod.getName();
}
}
return null;
}
@Override
public boolean canChangePassword(Context context, EPerson ePerson, String currentPassword) {
for (AuthenticationMethod method : getAuthenticationMethodStack()) {
if (method.getName().equals(context.getAuthenticationMethod())) {
return method.canChangePassword(context, ePerson, currentPassword);
}
}
return false;
}
}