Fleshed out nonce service classes, added code to token service impl to check for and store nonces. Added JodaTime library for working with dates.
parent
c7ae315e98
commit
a4637ec395
|
@ -19,13 +19,15 @@ import javax.persistence.Temporal;
|
|||
@NamedQueries({
|
||||
@NamedQuery(name = "Nonce.getAll", query = "select n from Nonce n"),
|
||||
@NamedQuery(name = "Nonce.getByClientId", query = "select n from Nonce n where n.clientId = :clientId"),
|
||||
@NamedQuery(name = "Nonce.getExpired", query = "select n from Nonce n where n.expireDate < now()")
|
||||
@NamedQuery(name = "Nonce.getExpired", query = "select n from Nonce n where n.expireDate is not null and n.expireDate < current_timestamp")
|
||||
})
|
||||
public class Nonce {
|
||||
|
||||
|
||||
private Long id; //the ID of this Nonce
|
||||
|
||||
private String value; //the value of this Nonce
|
||||
|
||||
private String clientId;//The id of the client who used this Nonce
|
||||
|
||||
private Date useDate; //the date this Nonce was used
|
||||
|
@ -48,6 +50,22 @@ public class Nonce {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="value")
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value to set
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientId
|
||||
*/
|
||||
|
|
|
@ -59,5 +59,10 @@ public interface NonceService {
|
|||
* @return the set of nonces registered to the client
|
||||
*/
|
||||
public Collection<Nonce> getByClientId(String clientId);
|
||||
|
||||
/**
|
||||
* Clear expired nonces from the database
|
||||
*/
|
||||
void clearExpiredNonces();
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
<artifactId>hsqldb</artifactId>
|
||||
<version>2.2.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<description>Reference implementation of OpenID Connect spec (http://openid.net/connect/).
|
||||
</description>
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
*/
|
||||
package org.mitre.oauth2.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Period;
|
||||
import org.mitre.oauth2.exception.NonceReuseException;
|
||||
import org.mitre.oauth2.model.AuthenticationHolderEntity;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
|
@ -31,6 +35,8 @@ import org.mitre.oauth2.repository.AuthenticationHolderRepository;
|
|||
import org.mitre.oauth2.repository.OAuth2TokenRepository;
|
||||
import org.mitre.oauth2.service.ClientDetailsEntityService;
|
||||
import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
||||
import org.mitre.openid.connect.model.Nonce;
|
||||
import org.mitre.openid.connect.service.NonceService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -65,6 +71,12 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
|||
@Autowired
|
||||
private ClientDetailsEntityService clientDetailsService;
|
||||
|
||||
@Autowired
|
||||
private NonceService nonceService;
|
||||
|
||||
//TODO how to specify this?
|
||||
private Period nonceStorageDuration = new Period(1, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
@Autowired
|
||||
private TokenEnhancer tokenEnhancer;
|
||||
|
||||
|
@ -80,6 +92,28 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
|||
throw new InvalidClientException("Client not found: " + clientAuth.getClientId());
|
||||
}
|
||||
|
||||
String requestNonce = clientAuth.getAuthorizationParameters().get("nonce");
|
||||
|
||||
//Check request nonce for reuse
|
||||
Collection<Nonce> clientNonces = nonceService.getByClientId(client.getClientId());
|
||||
for (Nonce nonce : clientNonces) {
|
||||
if (nonce.getValue().equals(requestNonce)) {
|
||||
throw new NonceReuseException(client.getClientId(), nonce);
|
||||
}
|
||||
}
|
||||
|
||||
//Store nonce
|
||||
Nonce nonce = new Nonce();
|
||||
nonce.setClientId(client.getClientId());
|
||||
nonce.setValue(requestNonce);
|
||||
DateTime now = new DateTime(new Date());
|
||||
DateTime expDate = now.plus(nonceStorageDuration);
|
||||
Date expirationJdkDate = expDate.toDate();
|
||||
nonce.setExpireDate(expirationJdkDate);
|
||||
|
||||
nonceService.save(nonce);
|
||||
|
||||
|
||||
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();//accessTokenFactory.createNewAccessToken();
|
||||
|
||||
// attach the client
|
||||
|
@ -394,5 +428,19 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
|||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
return tokenRepository.getAccessTokenForIdToken(idToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nonceStorageDuration
|
||||
*/
|
||||
public Period getNonceStorageDuration() {
|
||||
return nonceStorageDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nonceStorageDuration the nonceStorageDuration to set
|
||||
*/
|
||||
public void setNonceStorageDuration(Period nonceStorageDuration) {
|
||||
this.nonceStorageDuration = nonceStorageDuration;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,46 +1,71 @@
|
|||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.mitre.openid.connect.model.Nonce;
|
||||
import org.mitre.openid.connect.repository.NonceRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Repository
|
||||
public class JpaNonceRepository implements NonceRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Nonce getById(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return manager.find(Nonce.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(Nonce nonce) {
|
||||
// TODO Auto-generated method stub
|
||||
Nonce found = manager.find(Nonce.class, nonce.getId());
|
||||
|
||||
if (found != null) {
|
||||
manager.remove(found);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Nonce reporitory remove: Nonce with id " + nonce.getId() + " could not be found.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Nonce save(Nonce nonce) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return saveOrUpdate(nonce.getId(), manager, nonce);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<Nonce> getAll() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
TypedQuery<Nonce> query = manager.createNamedQuery("Nonce.getAll", Nonce.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<Nonce> getExpired() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
TypedQuery<Nonce> query = manager.createNamedQuery("Nonce.getExpired", Nonce.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<Nonce> getByClientId(String clientId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
TypedQuery<Nonce> query = manager.createNamedQuery("Nonce.getByClientId", Nonce.class);
|
||||
query.setParameter("clientId", clientId);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,44 +3,64 @@ package org.mitre.openid.connect.service.impl;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.mitre.openid.connect.model.Nonce;
|
||||
import org.mitre.openid.connect.repository.NonceRepository;
|
||||
import org.mitre.openid.connect.service.NonceService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DefaultNonceService implements NonceService {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(NonceService.class);
|
||||
|
||||
@Autowired
|
||||
NonceRepository repository;
|
||||
|
||||
@Override
|
||||
public Nonce getById(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return repository.getById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Nonce nonce) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
repository.remove(nonce);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nonce save(Nonce nonce) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return repository.save(nonce);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Nonce> getAll() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return repository.getAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Nonce> getExpired() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return repository.getExpired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Nonce> getByClientId(String clientId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return repository.getByClientId(clientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes
|
||||
public void clearExpiredNonces() {
|
||||
|
||||
logger.info("Clearing expired nonces");
|
||||
|
||||
Collection<Nonce> expired = repository.getExpired();
|
||||
logger.info("Found " + expired.size() + " expired nonces");
|
||||
|
||||
for (Nonce nonce : expired) {
|
||||
remove(nonce);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue