pulled client key publication into its own class to help deal with bean processors

pull/306/merge
Justin Richer 2013-02-27 17:54:31 -05:00
parent 42ea2468c9
commit 2a855a1952
3 changed files with 166 additions and 120 deletions

View File

@ -0,0 +1,164 @@
/**
*
*/
package org.mitre.openid.connect.client;
import java.security.PublicKey;
import java.util.Map;
import java.util.UUID;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.mitre.openid.connect.view.JwkKeyListView;
import org.mitre.openid.connect.view.X509CertificateView;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.web.servlet.ModelAndView;
import com.google.common.base.Strings;
/**
* @author jricher
*
*/
public class ClientKeyPublisher implements BeanDefinitionRegistryPostProcessor {
private JwtSigningAndValidationService signingAndValidationService;
private String jwkPublishUrl;
private String x509PublishUrl;
private BeanDefinitionRegistry registry;
private String jwkViewName = "jwkKeyList";
private String x509ViewName;
/**
* If either the jwkPublishUrl or x509PublishUrl fields are set on this bean, set up a listener on that URL to publish keys.
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (!Strings.isNullOrEmpty(getJwkPublishUrl()) || !Strings.isNullOrEmpty(getX509PublishUrl())) {
// add a mapping to this class
BeanDefinitionBuilder clientKeyMapping = BeanDefinitionBuilder.rootBeanDefinition(ClientKeyPublisherMapping.class);
// custom view resolver
BeanDefinitionBuilder viewResolver = BeanDefinitionBuilder.rootBeanDefinition(JwkViewResolver.class);
if (!Strings.isNullOrEmpty(getJwkPublishUrl())) {
clientKeyMapping.addPropertyValue("jwkPublishUrl", getJwkPublishUrl());
// randomize view name to make sure it doesn't conflict with local views
jwkViewName = "jwkKeyList-" + UUID.randomUUID().toString();
viewResolver.addPropertyValue("jwkViewName", jwkViewName);
// view bean
BeanDefinitionBuilder jwkView = BeanDefinitionBuilder.rootBeanDefinition(JwkKeyListView.class);
registry.registerBeanDefinition("jwkKeyList", jwkView.getBeanDefinition());
viewResolver.addPropertyReference("jwk", "jwkKeyList");
}
if (!Strings.isNullOrEmpty(getX509PublishUrl())) {
clientKeyMapping.addPropertyValue("x509PublishUrl", getX509PublishUrl());
// randomize view name to make sure it doesn't conflict with local views
x509ViewName = "x509certs-" + UUID.randomUUID().toString();
viewResolver.addPropertyValue("x509ViewName", x509ViewName);
// view bean
BeanDefinitionBuilder x509View = BeanDefinitionBuilder.rootBeanDefinition(X509CertificateView.class);
registry.registerBeanDefinition("x509certs", x509View.getBeanDefinition());
viewResolver.addPropertyReference("x509", "x509certs");
}
registry.registerBeanDefinition("clientKeyMapping", clientKeyMapping.getBeanDefinition());
registry.registerBeanDefinition("jwkViewResolver", viewResolver.getBeanDefinition());
}
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
this.registry = registry;
}
/**
* Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set.
* @return
*/
public ModelAndView publishClientJwk() {
// map from key id to key
Map<String, PublicKey> keys = signingAndValidationService.getAllPublicKeys();
// TODO: check if keys are empty, return a 404 here or just an empty list?
return new ModelAndView(jwkViewName, "keys", keys);
}
/**
* Return a view to publish all keys in x509 format. Only used if x509publishUrl is set.
* @return
*/
public ModelAndView publishClientx509() {
// map from key id to key
Map<String, PublicKey> keys = signingAndValidationService.getAllPublicKeys();
// TODO: check if keys are empty, return a 404 here or just an empty list?
return new ModelAndView(x509ViewName, "keys", keys);
}
/**
* @return the jwkPublishUrl
*/
public String getJwkPublishUrl() {
return jwkPublishUrl;
}
/**
* @param jwkPublishUrl the jwkPublishUrl to set
*/
public void setJwkPublishUrl(String jwkPublishUrl) {
this.jwkPublishUrl = jwkPublishUrl;
}
/**
* @return the x509PublishUrl
*/
public String getX509PublishUrl() {
return x509PublishUrl;
}
/**
* @param x509PublishUrl the x509PublishUrl to set
*/
public void setX509PublishUrl(String x509PublishUrl) {
this.x509PublishUrl = x509PublishUrl;
}
/**
* @return the signingAndValidationService
*/
public JwtSigningAndValidationService getSigningAndValidationService() {
return signingAndValidationService;
}
/**
* @param signingAndValidationService the signingAndValidationService to set
*/
public void setSigningAndValidationService(JwtSigningAndValidationService signingAndValidationService) {
this.signingAndValidationService = signingAndValidationService;
}
}

View File

@ -25,7 +25,7 @@ public class ClientKeyPublisherMapping extends RequestMappingInfoHandlerMapping
*/ */
@Override @Override
protected boolean isHandler(Class<?> beanType) { protected boolean isHandler(Class<?> beanType) {
return beanType.equals(OIDCSignedRequestFilter.class); return beanType.equals(ClientKeyPublisher.class);
} }
/** /**

View File

@ -32,23 +32,12 @@ import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
public class OIDCSignedRequestFilter extends AbstractOIDCAuthenticationFilter implements BeanDefinitionRegistryPostProcessor { public class OIDCSignedRequestFilter extends AbstractOIDCAuthenticationFilter {
private OIDCServerConfiguration oidcServerConfig; private OIDCServerConfiguration oidcServerConfig;
private JwtSigningAndValidationService signingAndValidationService; private JwtSigningAndValidationService signingAndValidationService;
private String jwkPublishUrl;
private String x509PublishUrl;
private BeanDefinitionRegistry registry;
private String jwkViewName = "jwkKeyList";
private String x509ViewName;
protected OIDCSignedRequestFilter() { protected OIDCSignedRequestFilter() {
super(); super();
@ -255,34 +244,6 @@ public class OIDCSignedRequestFilter extends AbstractOIDCAuthenticationFilter im
} }
/** /**
* @return the jwkPublishUrl
*/
public String getJwkPublishUrl() {
return jwkPublishUrl;
}
/**
* @param jwkPublishUrl the jwkPublishUrl to set
*/
public void setJwkPublishUrl(String jwkPublishUrl) {
this.jwkPublishUrl = jwkPublishUrl;
}
/**
* @return the x509PublishUrl
*/
public String getX509PublishUrl() {
return x509PublishUrl;
}
/**
* @param x509PublishUrl the x509PublishUrl to set
*/
public void setX509PublishUrl(String x509PublishUrl) {
this.x509PublishUrl = x509PublishUrl;
}
/**
* @param algorithmName * @param algorithmName
* @see org.mitre.openid.connect.config.OIDCServerConfiguration#setAlgorithmName(java.lang.String) * @see org.mitre.openid.connect.config.OIDCServerConfiguration#setAlgorithmName(java.lang.String)
*/ */
@ -290,85 +251,6 @@ public class OIDCSignedRequestFilter extends AbstractOIDCAuthenticationFilter im
oidcServerConfig.setAlgorithmName(algorithmName); oidcServerConfig.setAlgorithmName(algorithmName);
} }
/**
* Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set.
* @return
*/
public ModelAndView publishClientJwk() {
// map from key id to key
Map<String, PublicKey> keys = signingAndValidationService.getAllPublicKeys();
// TODO: check if keys are empty, return a 404 here or just an empty list?
return new ModelAndView(jwkViewName, "keys", keys);
}
/**
* Return a view to publish all keys in x509 format. Only used if x509publishUrl is set.
* @return
*/
public ModelAndView publishClientx509() {
// map from key id to key
Map<String, PublicKey> keys = signingAndValidationService.getAllPublicKeys();
// TODO: check if keys are empty, return a 404 here or just an empty list?
return new ModelAndView(x509ViewName, "keys", keys);
}
/**
* If either the jwkPublishUrl or x509PublishUrl fields are set on this bean, set up a listener on that URL to publish keys.
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (!Strings.isNullOrEmpty(getJwkPublishUrl()) || !Strings.isNullOrEmpty(getX509PublishUrl())) {
// add a mapping to this class
BeanDefinitionBuilder clientKeyMapping = BeanDefinitionBuilder.rootBeanDefinition(ClientKeyPublisherMapping.class);
// custom view resolver
BeanDefinitionBuilder viewResolver = BeanDefinitionBuilder.rootBeanDefinition(JwkViewResolver.class);
if (!Strings.isNullOrEmpty(getJwkPublishUrl())) {
clientKeyMapping.addPropertyValue("jwkPublishUrl", getJwkPublishUrl());
// randomize view name to make sure it doesn't conflict with local views
jwkViewName = "jwkKeyList-" + UUID.randomUUID().toString();
viewResolver.addPropertyValue("jwkViewName", jwkViewName);
// view bean
BeanDefinitionBuilder jwkView = BeanDefinitionBuilder.rootBeanDefinition(JwkKeyListView.class);
registry.registerBeanDefinition("jwkKeyList", jwkView.getBeanDefinition());
viewResolver.addPropertyReference("jwk", "jwkKeyList");
}
if (!Strings.isNullOrEmpty(getX509PublishUrl())) {
clientKeyMapping.addPropertyValue("x509PublishUrl", getX509PublishUrl());
// randomize view name to make sure it doesn't conflict with local views
x509ViewName = "x509certs-" + UUID.randomUUID().toString();
viewResolver.addPropertyValue("x509ViewName", x509ViewName);
// view bean
BeanDefinitionBuilder x509View = BeanDefinitionBuilder.rootBeanDefinition(X509CertificateView.class);
registry.registerBeanDefinition("x509certs", x509View.getBeanDefinition());
viewResolver.addPropertyReference("x509", "x509certs");
}
registry.registerBeanDefinition("clientKeyMapping", clientKeyMapping.getBeanDefinition());
registry.registerBeanDefinition("jwkViewResolver", viewResolver.getBeanDefinition());
}
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
this.registry = registry;
}
} }