Moved nonce processing stuff into nonce service and out of ConnectAuthorizationRequestManager

pull/306/merge
Amanda Anganes 2013-03-22 14:38:37 -04:00
parent d38c5b4200
commit fcc95f8a0a
5 changed files with 94 additions and 62 deletions

View File

@ -14,7 +14,25 @@ import org.mitre.openid.connect.model.Nonce;
*/ */
public interface NonceService { public interface NonceService {
/**
* Create a new nonce.
*
* @param clientId the ID of the client
* @param value the value of the Nonce
* @return the saved Nonce
*/
public Nonce create(String clientId, String value);
/**
* Check whether a given nonce value has been previously used and stored
* by the client.
*
* @param clientId the ID of the client
* @param value the value of the nonce
* @return true if the nonce has already been used, false otherwise
*/
public boolean alreadyUsed(String clientId, String value);
/** /**
* Return the nonce with the given ID * Return the nonce with the given ID
* *

View File

@ -1,14 +1,13 @@
package org.mitre.oauth2.exception; package org.mitre.oauth2.exception;
import org.mitre.openid.connect.model.Nonce;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
public class NonceReuseException extends OAuth2Exception { public class NonceReuseException extends OAuth2Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public NonceReuseException(String clientId, Nonce alreadyUsed) { public NonceReuseException(String clientId, String nonce) {
super("Client " + clientId + " attempted to use reuse nonce " + alreadyUsed.getValue()); super("Client " + clientId + " attempted to use reuse nonce " + nonce);
} }
} }

View File

@ -1,17 +1,13 @@
package org.mitre.openid.connect; package org.mitre.openid.connect;
import java.text.ParseException; import java.text.ParseException;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import net.minidev.json.JSONObject; import net.minidev.json.JSONObject;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.mitre.jwt.signer.service.impl.JWKSetSigningAndValidationServiceCacheService; import org.mitre.jwt.signer.service.impl.JWKSetSigningAndValidationServiceCacheService;
import org.mitre.oauth2.exception.NonceReuseException; import org.mitre.oauth2.exception.NonceReuseException;
@ -21,11 +17,10 @@ import org.mitre.openid.connect.model.Nonce;
import org.mitre.openid.connect.service.NonceService; import org.mitre.openid.connect.service.NonceService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.InvalidScopeException; import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.security.oauth2.common.util.OAuth2Utils;
@ -40,7 +35,7 @@ import com.nimbusds.jose.util.JSONObjectUtils;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
@Component("authorizationRequestManager") @Component("authorizationRequestManager")
public class ConnectAuthorizationRequestManager implements AuthorizationRequestManager, InitializingBean { public class ConnectAuthorizationRequestManager implements AuthorizationRequestManager {
private static Logger logger = LoggerFactory.getLogger(ConnectAuthorizationRequestManager.class); private static Logger logger = LoggerFactory.getLogger(ConnectAuthorizationRequestManager.class);
@ -52,8 +47,6 @@ public class ConnectAuthorizationRequestManager implements AuthorizationRequestM
@Autowired @Autowired
private JWKSetSigningAndValidationServiceCacheService validators; private JWKSetSigningAndValidationServiceCacheService validators;
private Period nonceStorageDuration;
/** /**
* Constructor with arguments * Constructor with arguments
@ -72,15 +65,6 @@ public class ConnectAuthorizationRequestManager implements AuthorizationRequestM
public ConnectAuthorizationRequestManager() { public ConnectAuthorizationRequestManager() {
} }
/**
* Make sure that the nonce storage duration was set
*/
public void afterPropertiesSet() throws Exception {
if (nonceStorageDuration == null) {
logger.error("Nonce storage duration must be set!");
}
}
@Override @Override
public AuthorizationRequest createAuthorizationRequest(Map<String, String> inputParams) { public AuthorizationRequest createAuthorizationRequest(Map<String, String> inputParams) {
@ -100,28 +84,15 @@ public class ConnectAuthorizationRequestManager implements AuthorizationRequestM
//to the auth endpoint. //to the auth endpoint.
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (requestNonce != null && principal != null && principal instanceof Authentication) { if (requestNonce != null && principal != null && principal instanceof User) {
//Check request nonce for reuse if (!nonceService.alreadyUsed(clientId, requestNonce)) {
Collection<Nonce> clientNonces = nonceService.getByClientId(client.getClientId()); Nonce nonce = nonceService.create(clientId, requestNonce);
for (Nonce nonce : clientNonces) { nonceService.save(nonce);
String nonceVal = nonce.getValue(); }
if (nonceVal.equals(requestNonce)) { else {
throw new NonceReuseException(client.getClientId(), nonce); throw new NonceReuseException(client.getClientId(), requestNonce);
}
} }
//Store nonce
Nonce nonce = new Nonce();
nonce.setClientId(client.getClientId());
nonce.setValue(requestNonce);
DateTime now = new DateTime(new Date());
nonce.setUseDate(now.toDate());
DateTime expDate = now.plus(nonceStorageDuration);
Date expirationJdkDate = expDate.toDate();
nonce.setExpireDate(expirationJdkDate);
nonceService.save(nonce);
} }
@ -263,20 +234,5 @@ public class ConnectAuthorizationRequestManager implements AuthorizationRequestM
} }
} }
} }
/**
* @return the nonceStorageDuration
*/
public Period getNonceStorageDuration() {
return nonceStorageDuration;
}
/**
* @param nonceStorageDuration the nonceStorageDuration to set
*/
public void setNonceStorageDuration(Period nonceStorageDuration) {
this.nonceStorageDuration = nonceStorageDuration;
}
} }

View File

@ -1,23 +1,67 @@
package org.mitre.openid.connect.service.impl; package org.mitre.openid.connect.service.impl;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.mitre.openid.connect.model.Nonce; import org.mitre.openid.connect.model.Nonce;
import org.mitre.openid.connect.repository.NonceRepository; import org.mitre.openid.connect.repository.NonceRepository;
import org.mitre.openid.connect.service.NonceService; import org.mitre.openid.connect.service.NonceService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service("defaultNonceService") @Service("defaultNonceService")
public class DefaultNonceService implements NonceService { public class DefaultNonceService implements NonceService, InitializingBean {
private static Logger logger = LoggerFactory.getLogger(NonceService.class); private static Logger logger = LoggerFactory.getLogger(NonceService.class);
@Autowired @Autowired
NonceRepository repository; private NonceRepository repository;
@Autowired
private Period nonceStorageDuration;
/**
* Make sure that the nonce storage duration was set
*/
public void afterPropertiesSet() throws Exception {
if (nonceStorageDuration == null) {
logger.error("Nonce storage duration must be set!");
}
}
@Override
public Nonce create(String clientId, String value) {
//Store nonce
Nonce nonce = new Nonce();
nonce.setClientId(clientId);
nonce.setValue(value);
DateTime now = new DateTime(new Date());
nonce.setUseDate(now.toDate());
DateTime expDate = now.plus(nonceStorageDuration);
Date expirationJdkDate = expDate.toDate();
nonce.setExpireDate(expirationJdkDate);
return nonce;
}
@Override
public boolean alreadyUsed(String clientId, String value) {
Collection<Nonce> clientNonces = getByClientId(clientId);
for (Nonce nonce : clientNonces) {
String nonceVal = nonce.getValue();
if (nonceVal.equals(value)) {
return true;
}
}
return false;
}
@Override @Override
public Nonce getById(Long id) { public Nonce getById(Long id) {
@ -63,4 +107,21 @@ public class DefaultNonceService implements NonceService {
} }
} }
public NonceRepository getRepository() {
return repository;
}
public void setRepository(NonceRepository repository) {
this.repository = repository;
}
public Period getNonceStorageDuration() {
return nonceStorageDuration;
}
public void setNonceStorageDuration(Period nonceStorageDuration) {
this.nonceStorageDuration = nonceStorageDuration;
}
} }

View File

@ -145,9 +145,7 @@
<constructor-arg type="int" index="3" value="0"/> <constructor-arg type="int" index="3" value="0"/>
</bean> </bean>
<bean id="authorizationRequestManager" class="org.mitre.openid.connect.ConnectAuthorizationRequestManager"> <bean id="authorizationRequestManager" class="org.mitre.openid.connect.ConnectAuthorizationRequestManager" />
<property name="nonceStorageDuration" ref="nonceStorageDurationPeriod" />
</bean>
<bean id="clientAssertiontokenEndpointFilter" class="org.mitre.openid.connect.assertion.JwtBearerClientAssertionTokenEndpointFilter"> <bean id="clientAssertiontokenEndpointFilter" class="org.mitre.openid.connect.assertion.JwtBearerClientAssertionTokenEndpointFilter">
<property name="authenticationManager" ref="clientAssertionAuthenticationManager" /> <property name="authenticationManager" ref="clientAssertionAuthenticationManager" />