Moved nonce processing stuff into nonce service and out of ConnectAuthorizationRequestManager
parent
d38c5b4200
commit
fcc95f8a0a
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
Loading…
Reference in New Issue