mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
DS-3542 Reuse salt if not expired
This commit is contained in:
@@ -92,6 +92,9 @@ public class EPerson extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
@Transient
|
||||
protected transient EPersonService ePersonService;
|
||||
|
||||
@Transient
|
||||
private Date previousActive;
|
||||
|
||||
/**
|
||||
* Protected constructor, create object using:
|
||||
* {@link org.dspace.eperson.service.EPersonService#create(Context)}
|
||||
@@ -373,6 +376,7 @@ public class EPerson extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
*/
|
||||
public void setLastActive(Date when)
|
||||
{
|
||||
this.previousActive = lastActive;
|
||||
this.lastActive = when;
|
||||
}
|
||||
|
||||
@@ -444,4 +448,12 @@ public class EPerson extends DSpaceObject implements DSpaceObjectLegacySupport
|
||||
public void setSessionSalt(String sessionSalt) {
|
||||
this.sessionSalt = sessionSalt;
|
||||
}
|
||||
|
||||
public Date getPreviousActive() {
|
||||
if (previousActive == null) {
|
||||
return new Date(0);
|
||||
}
|
||||
return previousActive;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -7,19 +7,29 @@
|
||||
*/
|
||||
package org.dspace.app.rest.security;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class DSpaceAuthentication implements Authentication {
|
||||
|
||||
|
||||
private EPerson ePerson;
|
||||
private String username;
|
||||
private String password;
|
||||
private List<GrantedAuthority> authorities;
|
||||
private boolean authenticated = true;
|
||||
|
||||
|
||||
public DSpaceAuthentication (EPerson ePerson, List<GrantedAuthority> authorities) {
|
||||
this.ePerson = ePerson;
|
||||
this.username = ePerson.getEmail();
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
public DSpaceAuthentication (String username, String password, List<GrantedAuthority> authorities) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
@@ -57,4 +67,8 @@ public class DSpaceAuthentication implements Authentication {
|
||||
public String getName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public EPerson getEPerson() {
|
||||
return ePerson;
|
||||
}
|
||||
}
|
||||
|
@@ -118,7 +118,7 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
|
||||
//Pass the eperson ID to the request service
|
||||
requestService.setCurrentUserId(ePerson.getID());
|
||||
|
||||
return new DSpaceAuthentication(ePerson.getEmail(), password, getGrantedAuthorities(context, ePerson));
|
||||
return new DSpaceAuthentication(ePerson, getGrantedAuthorities(context, ePerson));
|
||||
|
||||
} else {
|
||||
log.info(LogManager.getHeader(context, "failed_login", "No eperson with an non-blank e-mail address found"));
|
||||
|
@@ -27,9 +27,11 @@ import com.nimbusds.jwt.JWTClaimsSet;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
import com.nimbusds.jwt.util.DateUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.servicemanager.config.DSpaceConfigurationService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
@@ -59,6 +61,9 @@ public class JWTTokenHandler {
|
||||
@Autowired
|
||||
private EPersonClaimProvider ePersonClaimProvider;
|
||||
|
||||
@Autowired
|
||||
private EPersonService ePersonService;
|
||||
|
||||
|
||||
public JWTTokenHandler() {
|
||||
//TODO move properties to authentication module
|
||||
@@ -118,25 +123,21 @@ public class JWTTokenHandler {
|
||||
* Create a jwt with the EPerson details in it
|
||||
* @param context
|
||||
* @param request
|
||||
* @param ePerson
|
||||
* @param detachedEPerson
|
||||
* @param groups
|
||||
* @return
|
||||
* @throws JOSEException
|
||||
*/
|
||||
public String createTokenForEPerson(Context context, HttpServletRequest request, EPerson ePerson, List<Group> groups) throws JOSEException {
|
||||
createNewSessionSalt(ePerson);
|
||||
context.setCurrentUser(ePerson);
|
||||
public String createTokenForEPerson(Context context, HttpServletRequest request, EPerson detachedEPerson, List<Group> groups) throws JOSEException {
|
||||
|
||||
//This has to be set before createNewSessionSalt, otherwise authorizeException is thrown
|
||||
context.setCurrentUser(detachedEPerson);
|
||||
|
||||
EPerson ePerson = createNewSessionSalt(context, detachedEPerson);
|
||||
|
||||
|
||||
|
||||
JWSSigner signer = new MACSigner(buildSigningKey(request, ePerson));
|
||||
|
||||
|
||||
try {
|
||||
context.commit();
|
||||
} catch (SQLException e) {
|
||||
//TODO FREDERIC throw exception and fail fast
|
||||
log.error("Error while committing salt to eperson", e);
|
||||
}
|
||||
|
||||
JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
|
||||
|
||||
for (JWTClaimProvider jwtClaimProvider: jwtClaimProviders) {
|
||||
@@ -182,10 +183,35 @@ public class JWTTokenHandler {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
private void createNewSessionSalt(EPerson ePerson) {
|
||||
StringKeyGenerator stringKeyGenerator = KeyGenerators.string();
|
||||
String salt = stringKeyGenerator.generateKey();
|
||||
ePerson.setSessionSalt(salt);
|
||||
private EPerson createNewSessionSalt(Context context, EPerson detached) {
|
||||
EPerson ePerson = null;
|
||||
try {
|
||||
//Reloading doesn't seem to work
|
||||
// ePerson = context.reloadEntity(detached);
|
||||
|
||||
//This does work, even still has the previousActive
|
||||
ePerson = ePersonService.find(context, detached.getID());
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (detached.getLastActive().getTime() - detached.getPreviousActive().getTime() > expirationTime) {
|
||||
|
||||
|
||||
StringKeyGenerator stringKeyGenerator = KeyGenerators.string();
|
||||
String salt = stringKeyGenerator.generateKey();
|
||||
ePerson.setSessionSalt(salt);
|
||||
|
||||
try {
|
||||
ePersonService.update(context, ePerson);
|
||||
context.commit();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (AuthorizeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return ePerson;
|
||||
}
|
||||
|
||||
public List<JWTClaimProvider> getJwtClaimProviders() {
|
||||
|
@@ -55,10 +55,10 @@ public class JWTTokenRestAuthenticationServiceImpl implements RestAuthentication
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAuthenticationDataForUser(HttpServletRequest request, HttpServletResponse response, String email) {
|
||||
public void addAuthenticationDataForUser(HttpServletRequest request, HttpServletResponse response, EPerson ePerson) {
|
||||
try {
|
||||
Context context = ContextUtil.obtainContext(request);
|
||||
EPerson ePerson = ePersonService.findByEmail(context, email);
|
||||
// EPerson ePerson = ePersonService.findByEmail(context, email);
|
||||
List<Group> groups = authenticationService.getSpecialGroups(context, request);
|
||||
String token = jwtTokenHandler.createTokenForEPerson(context, request, ePerson, groups);
|
||||
|
||||
|
@@ -20,7 +20,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
@Service
|
||||
public interface RestAuthenticationService {
|
||||
|
||||
void addAuthenticationDataForUser(HttpServletRequest request, HttpServletResponse response, String email);
|
||||
void addAuthenticationDataForUser(HttpServletRequest request, HttpServletResponse response, EPerson ePerson);
|
||||
|
||||
EPerson getAuthenticatedEPerson(HttpServletRequest request, Context context);
|
||||
|
||||
|
@@ -7,8 +7,6 @@
|
||||
*/
|
||||
package org.dspace.app.rest.security;
|
||||
|
||||
import org.dspace.app.rest.utils.ContextUtil;
|
||||
import org.dspace.core.Context;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
@@ -57,6 +55,7 @@ public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter
|
||||
Authentication auth) throws IOException, ServletException {
|
||||
|
||||
//TODO every time we log in a new token and salt is created, might need to change this
|
||||
restAuthenticationService.addAuthenticationDataForUser(req, res, auth.getName());
|
||||
DSpaceAuthentication dSpaceAuthentication = (DSpaceAuthentication) auth;
|
||||
restAuthenticationService.addAuthenticationDataForUser(req, res, dSpaceAuthentication.getEPerson());
|
||||
}
|
||||
}
|
||||
|
@@ -53,4 +53,4 @@ plugin.sequence.org.dspace.authenticate.AuthenticationMethod = org.dspace.authen
|
||||
# Partial key that is used to sign the authentication tokens
|
||||
jwt.token.secret = thisisatestsecretkeyforjwttokens
|
||||
# Expiration time of a token in minutes
|
||||
jwt.token.expiration = 30
|
||||
jwt.token.expiration = 1
|
Reference in New Issue
Block a user