added system default signing algorithm, converted token provider and enhancer to use nimbus-jose

pull/306/merge
Justin Richer 2013-02-19 16:56:52 -05:00
parent c01e873019
commit e5732da857
6 changed files with 84 additions and 30 deletions

View File

@ -96,7 +96,7 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
* Create a new, blank access token
*/
public OAuth2AccessTokenEntity() {
setJwt(new PlainJWT(new JWTClaimsSet())); // give us a blank jwt to work with at least
}
/**

View File

@ -73,7 +73,7 @@ public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken {
*
*/
public OAuth2RefreshTokenEntity() {
setJwt(new PlainJWT(new JWTClaimsSet())); // start with a blank JWT value
}
/**

View File

@ -15,6 +15,8 @@
******************************************************************************/
package org.mitre.openid.connect.config;
import com.nimbusds.jose.JWSAlgorithm;
/**
* Bean to hold configuration information that must be injected into various parts
@ -30,6 +32,8 @@ public class ConfigurationPropertiesBean {
private String defaultJwtSigner;
private JWSAlgorithm defaultAlgorithm;
public ConfigurationPropertiesBean() {
}
@ -57,4 +61,23 @@ public class ConfigurationPropertiesBean {
public void setIssuer(String iss) {
issuer = iss;
}
/**
* @return
*/
public JWSAlgorithm getDefaultSigningAlgorithm() {
return defaultAlgorithm;
}
public void setDefaultSigningAlgorithmName(String algName) {
defaultAlgorithm = JWSAlgorithm.parse(algName);
}
public String getDefaultSigningAlgorithmName() {
if (defaultAlgorithm != null) {
return defaultAlgorithm.getName();
} else {
return null;
}
}
}

View File

@ -23,6 +23,7 @@ import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.Period;
@ -51,6 +52,8 @@ import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.stereotype.Service;
import com.google.common.collect.Sets;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
/**
@ -114,17 +117,31 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
// TODO: tie this to some kind of scope service
if (client.isAllowRefresh() && scopes.contains("offline_access")) {
OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken();
JWTClaimsSet refreshClaims = new JWTClaimsSet();
// make it expire if necessary
if (client.getRefreshTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L));
refreshToken.setExpiration(expiration);
// FIXME: nimbus date fields
refreshClaims.setExpirationTimeClaim(expiration.getTime());
}
// set a random identifier
refreshClaims.setJWTIDClaim(UUID.randomUUID().toString());
// TODO: add issuer fields, signature to JWT
PlainJWT refreshJwt = new PlainJWT(refreshClaims);
refreshToken.setJwt(refreshJwt);
//Add the authentication
refreshToken.setAuthenticationHolder(authHolder);
refreshToken.setClient(client);
// save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?)
tokenRepository.saveRefreshToken(refreshToken);

View File

@ -17,7 +17,6 @@ package org.mitre.openid.connect.token;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@ -26,8 +25,6 @@ import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.model.IdToken;
import org.mitre.openid.connect.model.IdTokenClaims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -38,6 +35,9 @@ import org.springframework.stereotype.Service;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
@Service
public class ConnectTokenEnhancer implements TokenEnhancer {
@ -60,26 +60,31 @@ public class ConnectTokenEnhancer implements TokenEnhancer {
String clientId = authentication.getAuthorizationRequest().getClientId();
token.getJwt().getClaims().setAudience(clientId);
JWTClaimsSet claims = new JWTClaimsSet();
token.getJwt().getClaims().setIssuer(configBean.getIssuer());
// FIXME: Nimbus should do collections
claims.setAudienceClaim(new String[] {clientId});
claims.setIssuerClaim(configBean.getIssuer());
token.getJwt().getClaims().setIssuedAt(new Date());
// FIXME: Nimbus Dates
claims.setIssuedAtClaim(new Date().getTime());
token.getJwt().getClaims().setExpiration(token.getExpiration());
// FIXME: Nimbus dates
claims.setExpirationTimeClaim(token.getExpiration().getTime());
token.getJwt().getClaims().setNonce(UUID.randomUUID().toString()); // set a random NONCE in the middle of it
claims.setJWTIDClaim(UUID.randomUUID().toString()); // set a random NONCE in the middle of it
if (token.getRefreshToken() != null && Strings.isNullOrEmpty(token.getRefreshToken().getJwt().getClaims().getNonce())) {
token.getRefreshToken().getJwt().getClaims().setNonce(UUID.randomUUID().toString()); // set a random nonce in the middle of it
}
SignedJWT signed = new SignedJWT(new JWSHeader(configBean.getDefaultSigningAlgorithm()), claims);
try {
jwtService.signJwt(token.getJwt());
} catch (NoSuchAlgorithmException e) {
// couldn't sign token
logger.warn("Couldn't sign access token", e);
try {
jwtService.signJwt(signed);
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
token.setJwt(signed);
/**
* Authorization request scope MUST include "openid" in OIDC, but access token request
@ -94,37 +99,45 @@ public class ConnectTokenEnhancer implements TokenEnhancer {
String userId = authentication.getName();
OAuth2AccessTokenEntity idTokenEntity = new OAuth2AccessTokenEntity();
IdToken idToken = new IdToken();
IdTokenClaims claims = new IdTokenClaims();
claims.setAuthTime(new Date());
claims.setIssuedAt(new Date());
// FIXME: extend the "claims" section for id tokens
JWTClaimsSet idClaims = new JWTClaimsSet();
idClaims.setCustomClaim("auth_time", new Date().getTime());
// FIXME: nimbus date fields
idClaims.setIssuedAtClaim(new Date().getTime());
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
if (client.getIdTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getIdTokenValiditySeconds() * 1000L));
claims.setExpiration(expiration);
// FIXME: nimbus date fields
idClaims.setExpirationTimeClaim(expiration.getTime());
idTokenEntity.setExpiration(expiration);
}
claims.setIssuer(configBean.getIssuer());
claims.setSubject(userId);
claims.setAudience(clientId);
idClaims.setIssuerClaim(configBean.getIssuer());
idClaims.setSubjectClaim(userId);
// FIXME: Nimbus audience as collection
idClaims.setAudienceClaim(new String[] { clientId });
idToken.setClaims(claims);
String nonce = authentication.getAuthorizationRequest().getAuthorizationParameters().get("nonce");
if (!Strings.isNullOrEmpty(nonce)) {
idToken.getClaims().setNonce(nonce);
idClaims.setCustomClaim("nonce", nonce);
}
SignedJWT idToken = new SignedJWT(new JWSHeader(configBean.getDefaultSigningAlgorithm()), idClaims);
//TODO: check for client's preferred signer alg and use that
try {
try {
jwtService.signJwt(idToken);
} catch (NoSuchAlgorithmException e) {
logger.warn("Couldn't sign id token", e);
// TODO Auto-generated catch block
e.printStackTrace();
}

View File

@ -15,6 +15,7 @@
<bean id="configBean" class="org.mitre.openid.connect.config.ConfigurationPropertiesBean">
<property name="issuer" value="http://localhost/" />
<property name="defaultJwtSigner" value="rsa1"/>
<property name="defaultSigningAlgorithmName" value="RS256" />
</bean>
</beans>