Added a ConfigurationPropertiesBean.java to hold configuration properties. Fixed up CheckIDEndpoint.java a bit - it works, but is outputting the wrong thing.
parent
c59d3fe963
commit
ae9b5e792a
|
@ -1,18 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
|
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
|
||||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
|
||||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
|
|
||||||
<attributes>
|
|
||||||
<attribute name="owner.project.facets" value="java"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -33,9 +33,13 @@ public abstract class AbstractJwtSigner implements JwtSigner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the 'alg' of the given JWT matches the {@link #algorithm} of this signer
|
* Ensures that the 'alg' of the given JWT matches the {@link #algorithm} of this signer
|
||||||
|
* and signs the jwt.
|
||||||
|
*
|
||||||
|
* @param jwt the jwt to sign
|
||||||
|
* @return the signed jwt
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void sign(Jwt jwt) {
|
public Jwt sign(Jwt jwt) {
|
||||||
if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) {
|
if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) {
|
||||||
// algorithm type doesn't match
|
// algorithm type doesn't match
|
||||||
// TODO: should this be an error or should we just fix it in the incoming jwt?
|
// TODO: should this be an error or should we just fix it in the incoming jwt?
|
||||||
|
@ -46,6 +50,8 @@ public abstract class AbstractJwtSigner implements JwtSigner {
|
||||||
String sig = generateSignature(jwt.getSignatureBase());
|
String sig = generateSignature(jwt.getSignatureBase());
|
||||||
|
|
||||||
jwt.setSignature(sig);
|
jwt.setSignature(sig);
|
||||||
|
|
||||||
|
return jwt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.mitre.jwt.model.Jwt;
|
||||||
|
|
||||||
public interface JwtSigner {
|
public interface JwtSigner {
|
||||||
|
|
||||||
public void sign(Jwt jwt);
|
public Jwt sign(Jwt jwt);
|
||||||
|
|
||||||
public boolean verify(String jwtString);
|
public boolean verify(String jwtString);
|
||||||
|
|
||||||
|
|
|
@ -45,4 +45,28 @@ public interface JwtSigningAndValidationService {
|
||||||
* @return true if the signature is valid, false if not
|
* @return true if the signature is valid, false if not
|
||||||
*/
|
*/
|
||||||
public boolean validateSignature(String jwtString);
|
public boolean validateSignature(String jwtString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to sign a jwt for a client that hasn't registered a preferred signing algorithm.
|
||||||
|
* Use the default algorithm to sign.
|
||||||
|
*
|
||||||
|
* @param jwt the jwt to sign
|
||||||
|
* @return the signed jwt
|
||||||
|
*/
|
||||||
|
public Jwt signJwt(Jwt jwt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a jwt using the selected algorithm. The algorithm is selected using the String parameter values specified
|
||||||
|
* in the JWT spec, section 6. I.E., "HS256" means HMAC with SHA-256 and corresponds to our HmacSigner class.
|
||||||
|
*
|
||||||
|
* @param jwt the jwt to sign
|
||||||
|
* @param alg the name of the algorithm to use, as specified in JWS s.6
|
||||||
|
* @return the signed jwt
|
||||||
|
*/
|
||||||
|
//TODO: implement later; only need signJwt(Jwt jwt) for now
|
||||||
|
//public Jwt signJwt(Jwt jwt, String alg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: method to sign a jwt using a specified algorithm and a key id
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,15 @@ import org.mitre.jwt.signer.JwtSigner;
|
||||||
import org.mitre.jwt.signer.impl.EcdsaSigner;
|
import org.mitre.jwt.signer.impl.EcdsaSigner;
|
||||||
import org.mitre.jwt.signer.impl.RsaSigner;
|
import org.mitre.jwt.signer.impl.RsaSigner;
|
||||||
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||||
|
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
public class JwtSigningAndValidationServiceDefault implements
|
public class JwtSigningAndValidationServiceDefault implements
|
||||||
JwtSigningAndValidationService, InitializingBean {
|
JwtSigningAndValidationService, InitializingBean {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationPropertiesBean configBean;
|
||||||
|
|
||||||
private List<? extends JwtSigner> signers = new ArrayList<JwtSigner>();
|
private List<? extends JwtSigner> signers = new ArrayList<JwtSigner>();
|
||||||
|
|
||||||
|
@ -153,7 +157,9 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
@Override
|
@Override
|
||||||
public boolean validateIssuedJwt(Jwt jwt, String expectedIssuer) {
|
public boolean validateIssuedJwt(Jwt jwt, String expectedIssuer) {
|
||||||
|
|
||||||
if (jwt.getClaims().getIssuer() == expectedIssuer)
|
String iss = jwt.getClaims().getIssuer();
|
||||||
|
|
||||||
|
if (iss.equals(expectedIssuer))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -176,4 +182,29 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jwt signJwt(Jwt jwt) {
|
||||||
|
String signerId = configBean.getDefaultJwtSigner();
|
||||||
|
|
||||||
|
//JwtSigner signer = map.get(signerId);
|
||||||
|
|
||||||
|
//signer.sign(jwt);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the configBean
|
||||||
|
*/
|
||||||
|
public ConfigurationPropertiesBean getConfigBean() {
|
||||||
|
return configBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param configBean the configBean to set
|
||||||
|
*/
|
||||||
|
public void setConfigBean(ConfigurationPropertiesBean configBean) {
|
||||||
|
this.configBean = configBean;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.mitre.openid.connect.config;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean to hold configuration information that must be injected into various parts
|
||||||
|
* of our application. Set all of the properties here, and autowire a reference
|
||||||
|
* to this bean if you need access to any configuration properties.
|
||||||
|
*
|
||||||
|
* @author AANGANES
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ConfigurationPropertiesBean {
|
||||||
|
|
||||||
|
private String issuer;
|
||||||
|
|
||||||
|
private String defaultJwtSigner;
|
||||||
|
|
||||||
|
public ConfigurationPropertiesBean() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the defaultJwtSigner
|
||||||
|
*/
|
||||||
|
public String getDefaultJwtSigner() {
|
||||||
|
return defaultJwtSigner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultJwtSigner(String signer) {
|
||||||
|
defaultJwtSigner = signer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the baseUrl
|
||||||
|
*/
|
||||||
|
public String getIssuer() {
|
||||||
|
return issuer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iss the issuer to set
|
||||||
|
*/
|
||||||
|
public void setIssuer(String iss) {
|
||||||
|
issuer = iss;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,9 +7,11 @@ import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||||
import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
||||||
import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService;
|
import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService;
|
||||||
|
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
||||||
import org.mitre.openid.connect.model.IdToken;
|
import org.mitre.openid.connect.model.IdToken;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
@ -48,7 +50,8 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ClientCredentialsChecker clientCredentialsChecker;
|
private ClientCredentialsChecker clientCredentialsChecker;
|
||||||
|
|
||||||
private String issuer;
|
@Autowired
|
||||||
|
private ConfigurationPropertiesBean configBean;
|
||||||
|
|
||||||
//TODO: Do we need to modify/update this?
|
//TODO: Do we need to modify/update this?
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -57,6 +60,9 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IdTokenGeneratorService idTokenService;
|
private IdTokenGeneratorService idTokenService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JwtSigningAndValidationService jwtService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default empty constructor
|
* Default empty constructor
|
||||||
*/
|
*/
|
||||||
|
@ -141,7 +147,7 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
|
|
||||||
//TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have
|
//TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have
|
||||||
//See github issue #1
|
//See github issue #1
|
||||||
token.getJwt().getClaims().setIssuer(issuer);
|
token.getJwt().getClaims().setIssuer(configBean.getIssuer());
|
||||||
|
|
||||||
token.getJwt().getClaims().setIssuedAt(new Date());
|
token.getJwt().getClaims().setIssuedAt(new Date());
|
||||||
// handle expiration
|
// handle expiration
|
||||||
|
@ -156,13 +162,19 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
|
|
||||||
String userId = userAuth.getName();
|
String userId = userAuth.getName();
|
||||||
|
|
||||||
//TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have
|
IdToken idToken = idTokenService.generateIdToken(userId, configBean.getIssuer());
|
||||||
//See github issue #1
|
|
||||||
IdToken idToken = idTokenService.generateIdToken(userId, issuer);
|
|
||||||
idToken.getClaims().setAudience(clientId);
|
idToken.getClaims().setAudience(clientId);
|
||||||
idToken.getClaims().setIssuedAt(new Date());
|
idToken.getClaims().setIssuedAt(new Date());
|
||||||
|
idToken.getClaims().setIssuer(configBean.getIssuer());
|
||||||
// TODO: expiration? other fields?
|
// TODO: expiration? other fields?
|
||||||
|
|
||||||
|
//Sign
|
||||||
|
|
||||||
|
//TODO: check client to see if they have a preferred alg, attempt to use that
|
||||||
|
|
||||||
|
//TODO: uncomment line below once RsaSigner bean has been set up and added to the configBean
|
||||||
|
//idToken = (IdToken) jwtService.signJwt(idToken);
|
||||||
|
|
||||||
token.setIdToken(idToken);
|
token.setIdToken(idToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,18 +219,28 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
this.tokenServices = tokenServices;
|
this.tokenServices = tokenServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public ConfigurationPropertiesBean getConfigBean() {
|
||||||
* @return the issuer
|
return configBean;
|
||||||
*/
|
}
|
||||||
public String getIssuer() {
|
|
||||||
return issuer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public void setConfigBean(ConfigurationPropertiesBean configBean) {
|
||||||
* @param issuer the issuer to set
|
this.configBean = configBean;
|
||||||
*/
|
}
|
||||||
public void setIssuer(String issuer) {
|
|
||||||
this.issuer = issuer;
|
public IdTokenGeneratorService getIdTokenService() {
|
||||||
}
|
return idTokenService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdTokenService(IdTokenGeneratorService idTokenService) {
|
||||||
|
this.idTokenService = idTokenService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JwtSigningAndValidationService getJwtService() {
|
||||||
|
return jwtService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJwtService(JwtSigningAndValidationService jwtService) {
|
||||||
|
this.jwtService = jwtService;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.mitre.openid.connect.web;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||||
|
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
||||||
import org.mitre.openid.connect.exception.ExpiredTokenException;
|
import org.mitre.openid.connect.exception.ExpiredTokenException;
|
||||||
import org.mitre.openid.connect.exception.InvalidJwtIssuerException;
|
import org.mitre.openid.connect.exception.InvalidJwtIssuerException;
|
||||||
import org.mitre.openid.connect.exception.InvalidJwtSignatureException;
|
import org.mitre.openid.connect.exception.InvalidJwtSignatureException;
|
||||||
|
@ -20,6 +21,9 @@ public class CheckIDEndpoint {
|
||||||
@Autowired
|
@Autowired
|
||||||
JwtSigningAndValidationService jwtSignerService;
|
JwtSigningAndValidationService jwtSignerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationPropertiesBean configBean;
|
||||||
|
|
||||||
@RequestMapping("/checkid")
|
@RequestMapping("/checkid")
|
||||||
public ModelAndView checkID(@RequestParam("id_token") String tokenString, ModelAndView mav, HttpServletRequest request) {
|
public ModelAndView checkID(@RequestParam("id_token") String tokenString, ModelAndView mav, HttpServletRequest request) {
|
||||||
|
|
||||||
|
@ -38,11 +42,27 @@ public class CheckIDEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the issuer (sanity check)
|
// check the issuer (sanity check)
|
||||||
if (!jwtSignerService.validateIssuedJwt(token, Utility.findBaseUrl(request))) {
|
if (!jwtSignerService.validateIssuedJwt(token, configBean.getIssuer())) {
|
||||||
throw new InvalidJwtIssuerException(); // TODO: create a view for this exception
|
throw new InvalidJwtIssuerException(); // TODO: create a view for this exception
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ModelAndView("jsonIdTokenView", "checkId", token); // TODO: create a view for this
|
return new ModelAndView("jsonIdTokenView", "checkId", token); // TODO: create a view for this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JwtSigningAndValidationService getJwtSignerService() {
|
||||||
|
return jwtSignerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJwtSignerService(JwtSigningAndValidationService jwtSignerService) {
|
||||||
|
this.jwtSignerService = jwtSignerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationPropertiesBean getConfigBean() {
|
||||||
|
return configBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfigBean(ConfigurationPropertiesBean configBean) {
|
||||||
|
this.configBean = configBean;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<beans:bean id="jsonSwdResponseView" class="org.mitre.swd.view.SwdResponse" />
|
<beans:bean id="jsonSwdResponseView" class="org.mitre.swd.view.SwdResponse" />
|
||||||
<beans:bean id="jwkKeyList" class="org.mitre.openid.connect.view.JwkKeyListView" />
|
<beans:bean id="jwkKeyList" class="org.mitre.openid.connect.view.JwkKeyListView" />
|
||||||
|
|
||||||
<!-- <beans:bean id="jsonUserInfoView" class="org.mitre.openid.connect.view.JSONUserInfoView"/> -->
|
<beans:bean id="jsonUserInfoView" class="org.mitre.openid.connect.view.JSONUserInfoView"/>
|
||||||
<!-- <beans:bean id="jsonIdTokenView" class="org.mitre.openid.connect.view.JSONIdTokenView"/> -->
|
<beans:bean id="jsonIdTokenView" class="org.mitre.openid.connect.view.JSONIdTokenView"/>
|
||||||
|
|
||||||
<beans:import resource="controllers.xml" />
|
<beans:import resource="controllers.xml" />
|
||||||
|
|
||||||
|
@ -53,8 +53,5 @@
|
||||||
<oauth:authorization-code authorization-code-services-ref="authCodeServices"/>
|
<oauth:authorization-code authorization-code-services-ref="authCodeServices"/>
|
||||||
</oauth:authorization-server>
|
</oauth:authorization-server>
|
||||||
|
|
||||||
<beans:bean id="connectAuthCodeTokenGranter" class="org.mitre.openid.connect.token.ConnectAuthCodeTokenGranter">
|
|
||||||
<beans:property name="issuer" value="http://localhost/" />
|
|
||||||
</beans:bean>
|
|
||||||
|
|
||||||
</beans:beans>
|
</beans:beans>
|
||||||
|
|
|
@ -81,6 +81,16 @@
|
||||||
<property name="showSql" value="true" />
|
<property name="showSql" value="true" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- TODO: get signer set up -->
|
||||||
|
<!-- <bean id="rsaSigner1" class="org.mitre.jwt.signer.impl.RsaSigner"/> -->
|
||||||
|
|
||||||
|
<bean id="configBean" class="org.mitre.openid.connect.config.ConfigurationPropertiesBean">
|
||||||
|
<property name="issuer" value="http://localhost/" />
|
||||||
|
<!-- TODO: plug in default signer -->
|
||||||
|
<!-- <property name="defaultJwtSigner" value="rsaSigner1"/> -->
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Map our custom exception classes to named views -->
|
<!-- Map our custom exception classes to named views -->
|
||||||
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
|
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
|
||||||
<property name="exceptionMappings">
|
<property name="exceptionMappings">
|
||||||
|
|
Loading…
Reference in New Issue