Upgraded to nimbus 4.2, closes #934

pull/943/head
Justin Richer 2015-10-13 04:40:01 -04:00
parent c67611e975
commit ebb4f2c3d4
16 changed files with 153 additions and 155 deletions

View File

@ -31,7 +31,7 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
/** /**
* *
@ -56,7 +56,7 @@ public class NamedAdminAuthoritiesMapper implements OIDCAuthoritiesMapper {
Set<GrantedAuthority> out = new HashSet<>(); Set<GrantedAuthority> out = new HashSet<>();
try { try {
ReadOnlyJWTClaimsSet claims = idToken.getJWTClaimsSet(); JWTClaimsSet claims = idToken.getJWTClaimsSet();
SubjectIssuerGrantedAuthority authority = new SubjectIssuerGrantedAuthority(claims.getSubject(), claims.getIssuer()); SubjectIssuerGrantedAuthority authority = new SubjectIssuerGrantedAuthority(claims.getSubject(), claims.getIssuer());
out.add(authority); out.add(authority);

View File

@ -16,6 +16,10 @@
*******************************************************************************/ *******************************************************************************/
package org.mitre.openid.connect.client; package org.mitre.openid.connect.client;
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.PRIVATE_KEY;
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_BASIC;
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_JWT;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URI; import java.net.URI;
@ -75,13 +79,8 @@ import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.JWTParser; import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.PlainJWT; import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.PRIVATE_KEY;
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_BASIC;
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_JWT;
/** /**
* OpenID Connect Authentication Filter class * OpenID Connect Authentication Filter class
* *
@ -374,25 +373,25 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
throw new AuthenticationServiceException("Couldn't find required signer service for use with private key auth."); throw new AuthenticationServiceException("Couldn't find required signer service for use with private key auth.");
} }
JWTClaimsSet claimsSet = new JWTClaimsSet(); JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder();
claimsSet.setIssuer(clientConfig.getClientId()); claimsSet.issuer(clientConfig.getClientId());
claimsSet.setSubject(clientConfig.getClientId()); claimsSet.subject(clientConfig.getClientId());
claimsSet.setAudience(Lists.newArrayList(serverConfig.getTokenEndpointUri())); claimsSet.audience(Lists.newArrayList(serverConfig.getTokenEndpointUri()));
claimsSet.setJWTID(UUID.randomUUID().toString()); claimsSet.jwtID(UUID.randomUUID().toString());
// TODO: make this configurable // TODO: make this configurable
Date exp = new Date(System.currentTimeMillis() + (60 * 1000)); // auth good for 60 seconds Date exp = new Date(System.currentTimeMillis() + (60 * 1000)); // auth good for 60 seconds
claimsSet.setExpirationTime(exp); claimsSet.expirationTime(exp);
Date now = new Date(System.currentTimeMillis()); Date now = new Date(System.currentTimeMillis());
claimsSet.setIssueTime(now); claimsSet.issueTime(now);
claimsSet.setNotBeforeTime(now); claimsSet.notBeforeTime(now);
JWSHeader header = new JWSHeader(alg, null, null, null, null, null, null, null, null, null, JWSHeader header = new JWSHeader(alg, null, null, null, null, null, null, null, null, null,
signer.getDefaultSignerKeyId(), signer.getDefaultSignerKeyId(),
null, null); null, null);
SignedJWT jwt = new SignedJWT(header, claimsSet); SignedJWT jwt = new SignedJWT(header, claimsSet.build());
signer.signJwt(jwt, alg); signer.signJwt(jwt, alg);
@ -472,7 +471,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
JWT idToken = JWTParser.parse(idTokenValue); JWT idToken = JWTParser.parse(idTokenValue);
// validate our ID Token over a number of tests // validate our ID Token over a number of tests
ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet(); JWTClaimsSet idClaims = idToken.getJWTClaimsSet();
// check the signature // check the signature
JWTSigningAndValidationService jwtValidator = null; JWTSigningAndValidationService jwtValidator = null;

View File

@ -58,33 +58,33 @@ public class EncryptedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) { public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) {
// create our signed JWT for the request object // create our signed JWT for the request object
JWTClaimsSet claims = new JWTClaimsSet(); JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder();
//set parameters to JwtClaims //set parameters to JwtClaims
claims.setClaim("response_type", "code"); claims.claim("response_type", "code");
claims.setClaim("client_id", clientConfig.getClientId()); claims.claim("client_id", clientConfig.getClientId());
claims.setClaim("scope", Joiner.on(" ").join(clientConfig.getScope())); claims.claim("scope", Joiner.on(" ").join(clientConfig.getScope()));
// build our redirect URI // build our redirect URI
claims.setClaim("redirect_uri", redirectUri); claims.claim("redirect_uri", redirectUri);
// this comes back in the id token // this comes back in the id token
claims.setClaim("nonce", nonce); claims.claim("nonce", nonce);
// this comes back in the auth request return // this comes back in the auth request return
claims.setClaim("state", state); claims.claim("state", state);
// Optional parameters // Optional parameters
for (Entry<String, String> option : options.entrySet()) { for (Entry<String, String> option : options.entrySet()) {
claims.setClaim(option.getKey(), option.getValue()); claims.claim(option.getKey(), option.getValue());
} }
// if there's a login hint, send it // if there's a login hint, send it
if (!Strings.isNullOrEmpty(loginHint)) { if (!Strings.isNullOrEmpty(loginHint)) {
claims.setClaim("login_hint", loginHint); claims.claim("login_hint", loginHint);
} }
EncryptedJWT jwt = new EncryptedJWT(new JWEHeader(alg, enc), claims); EncryptedJWT jwt = new EncryptedJWT(new JWEHeader(alg, enc), claims.build());
JWTEncryptionAndDecryptionService encryptor = encrypterService.getEncrypter(serverConfig.getJwksUri()); JWTEncryptionAndDecryptionService encryptor = encrypterService.getEncrypter(serverConfig.getJwksUri());

View File

@ -52,30 +52,30 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) { public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) {
// create our signed JWT for the request object // create our signed JWT for the request object
JWTClaimsSet claims = new JWTClaimsSet(); JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder();
//set parameters to JwtClaims //set parameters to JwtClaims
claims.setClaim("response_type", "code"); claims.claim("response_type", "code");
claims.setClaim("client_id", clientConfig.getClientId()); claims.claim("client_id", clientConfig.getClientId());
claims.setClaim("scope", Joiner.on(" ").join(clientConfig.getScope())); claims.claim("scope", Joiner.on(" ").join(clientConfig.getScope()));
// build our redirect URI // build our redirect URI
claims.setClaim("redirect_uri", redirectUri); claims.claim("redirect_uri", redirectUri);
// this comes back in the id token // this comes back in the id token
claims.setClaim("nonce", nonce); claims.claim("nonce", nonce);
// this comes back in the auth request return // this comes back in the auth request return
claims.setClaim("state", state); claims.claim("state", state);
// Optional parameters // Optional parameters
for (Entry<String, String> option : options.entrySet()) { for (Entry<String, String> option : options.entrySet()) {
claims.setClaim(option.getKey(), option.getValue()); claims.claim(option.getKey(), option.getValue());
} }
// if there's a login hint, send it // if there's a login hint, send it
if (!Strings.isNullOrEmpty(loginHint)) { if (!Strings.isNullOrEmpty(loginHint)) {
claims.setClaim("login_hint", loginHint); claims.claim("login_hint", loginHint);
} }
JWSAlgorithm alg = clientConfig.getRequestObjectSigningAlg(); JWSAlgorithm alg = clientConfig.getRequestObjectSigningAlg();
@ -83,7 +83,7 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
alg = signingAndValidationService.getDefaultSigningAlgorithm(); alg = signingAndValidationService.getDefaultSigningAlgorithm();
} }
SignedJWT jwt = new SignedJWT(new JWSHeader(alg), claims); SignedJWT jwt = new SignedJWT(new JWSHeader(alg), claims.build());
signingAndValidationService.signJwt(jwt, alg); signingAndValidationService.signJwt(jwt, alg);

View File

@ -43,7 +43,7 @@ import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.KeyUse; import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.util.Base64URL; import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -130,7 +130,7 @@ public class TestSignedAuthRequestUrlBuilder {
UriComponents components = builder.build(); UriComponents components = builder.build();
String jwtString = components.getQueryParams().get("request").get(0); String jwtString = components.getQueryParams().get("request").get(0);
ReadOnlyJWTClaimsSet claims = null; JWTClaimsSet claims = null;
try { try {
SignedJWT jwt = SignedJWT.parse(jwtString); SignedJWT jwt = SignedJWT.parse(jwtString);
@ -169,7 +169,7 @@ public class TestSignedAuthRequestUrlBuilder {
UriComponents components = builder.build(); UriComponents components = builder.build();
String jwtString = components.getQueryParams().get("request").get(0); String jwtString = components.getQueryParams().get("request").get(0);
ReadOnlyJWTClaimsSet claims = null; JWTClaimsSet claims = null;
try { try {
SignedJWT jwt = SignedJWT.parse(jwtString); SignedJWT jwt = SignedJWT.parse(jwtString);

View File

@ -272,11 +272,11 @@ public class DefaultJWTEncryptionAndDecryptionService implements JWTEncryptionAn
Set<JWEAlgorithm> algs = new HashSet<>(); Set<JWEAlgorithm> algs = new HashSet<>();
for (JWEEncrypter encrypter : encrypters.values()) { for (JWEEncrypter encrypter : encrypters.values()) {
algs.addAll(encrypter.supportedAlgorithms()); algs.addAll(encrypter.supportedJWEAlgorithms());
} }
for (JWEDecrypter decrypter : decrypters.values()) { for (JWEDecrypter decrypter : decrypters.values()) {
algs.addAll(decrypter.supportedAlgorithms()); algs.addAll(decrypter.supportedJWEAlgorithms());
} }
return algs; return algs;

View File

@ -17,6 +17,8 @@
package org.mitre.jwt.signer.service.impl; package org.mitre.jwt.signer.service.impl;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -160,41 +162,45 @@ public class DefaultJWTSigningAndValidationService implements JWTSigningAndValid
String id = jwkEntry.getKey(); String id = jwkEntry.getKey();
JWK jwk = jwkEntry.getValue(); JWK jwk = jwkEntry.getValue();
if (jwk instanceof RSAKey) { try {
// build RSA signers & verifiers if (jwk instanceof RSAKey) {
// build RSA signers & verifiers
if (jwk.isPrivate()) { // only add the signer if there's a private key
RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey()); if (jwk.isPrivate()) { // only add the signer if there's a private key
signers.put(id, signer); RSASSASigner signer = new RSASSASigner((RSAKey) jwk);
signers.put(id, signer);
}
RSASSAVerifier verifier = new RSASSAVerifier((RSAKey) jwk);
verifiers.put(id, verifier);
} else if (jwk instanceof ECKey) {
// build EC signers & verifiers
if (jwk.isPrivate()) {
ECDSASigner signer = new ECDSASigner((ECKey) jwk);
signers.put(id, signer);
}
ECDSAVerifier verifier = new ECDSAVerifier((ECKey) jwk);
verifiers.put(id, verifier);
} else if (jwk instanceof OctetSequenceKey) {
// build HMAC signers & verifiers
if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private
MACSigner signer = new MACSigner((OctetSequenceKey) jwk);
signers.put(id, signer);
}
MACVerifier verifier = new MACVerifier((OctetSequenceKey) jwk);
verifiers.put(id, verifier);
} else {
logger.warn("Unknown key type: " + jwk);
} }
} catch (JOSEException e) {
RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey()); logger.warn("Exception loading signer/verifier", e);
verifiers.put(id, verifier);
} else if (jwk instanceof ECKey) {
// build EC signers & verifiers
if (jwk.isPrivate()) {
ECDSASigner signer = new ECDSASigner(((ECKey) jwk).getD().decodeToBigInteger());
signers.put(id, signer);
}
ECDSAVerifier verifier = new ECDSAVerifier(((ECKey) jwk).getX().decodeToBigInteger(), ((ECKey) jwk).getY().decodeToBigInteger());
verifiers.put(id, verifier);
} else if (jwk instanceof OctetSequenceKey) {
// build HMAC signers & verifiers
if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private
MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray());
signers.put(id, signer);
}
MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray());
verifiers.put(id, verifier);
} else {
logger.warn("Unknown key type: " + jwk);
} }
} }
@ -230,7 +236,7 @@ public class DefaultJWTSigningAndValidationService implements JWTSigningAndValid
JWSSigner signer = null; JWSSigner signer = null;
for (JWSSigner s : signers.values()) { for (JWSSigner s : signers.values()) {
if (s.supportedAlgorithms().contains(alg)) { if (s.supportedJWSAlgorithms().contains(alg)) {
signer = s; signer = s;
break; break;
} }
@ -292,11 +298,11 @@ public class DefaultJWTSigningAndValidationService implements JWTSigningAndValid
Set<JWSAlgorithm> algs = new HashSet<>(); Set<JWSAlgorithm> algs = new HashSet<>();
for (JWSSigner signer : signers.values()) { for (JWSSigner signer : signers.values()) {
algs.addAll(signer.supportedAlgorithms()); algs.addAll(signer.supportedJWSAlgorithms());
} }
for (JWSVerifier verifier : verifiers.values()) { for (JWSVerifier verifier : verifiers.values()) {
algs.addAll(verifier.supportedAlgorithms()); algs.addAll(verifier.supportedJWSAlgorithms());
} }
return algs; return algs;

View File

@ -42,7 +42,6 @@ import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.util.JSONObjectUtils; import com.nimbusds.jose.util.JSONObjectUtils;
import com.nimbusds.jwt.EncryptedJWT; import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.CoreMatchers.nullValue;
@ -63,7 +62,7 @@ public class TestDefaultJWTEncryptionAndDecryptionService {
private String issuer = "www.example.net"; private String issuer = "www.example.net";
private String subject = "example_user"; private String subject = "example_user";
private JWTClaimsSet claimsSet = new JWTClaimsSet(); private JWTClaimsSet claimsSet = null;
// Example data taken from Mike Jones's draft-ietf-jose-json-web-encryption-14 appendix examples // Example data taken from Mike Jones's draft-ietf-jose-json-web-encryption-14 appendix examples
private String compactSerializedJwe = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ." + private String compactSerializedJwe = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ." +
@ -152,8 +151,10 @@ public class TestDefaultJWTEncryptionAndDecryptionService {
service_3 = new DefaultJWTEncryptionAndDecryptionService(keys_3); service_3 = new DefaultJWTEncryptionAndDecryptionService(keys_3);
service_4 = new DefaultJWTEncryptionAndDecryptionService(keys_4); service_4 = new DefaultJWTEncryptionAndDecryptionService(keys_4);
claimsSet.setIssuer(issuer); claimsSet = new JWTClaimsSet.Builder()
claimsSet.setSubject(subject); .issuer(issuer)
.subject(subject)
.build();
// Key Store // Key Store
@ -203,7 +204,7 @@ public class TestDefaultJWTEncryptionAndDecryptionService {
assertThat(encryptedJwt.getJWTClaimsSet(), nullValue()); assertThat(encryptedJwt.getJWTClaimsSet(), nullValue());
service.decryptJwt(encryptedJwt); service.decryptJwt(encryptedJwt);
ReadOnlyJWTClaimsSet resultClaims = encryptedJwt.getJWTClaimsSet(); JWTClaimsSet resultClaims = encryptedJwt.getJWTClaimsSet();
assertEquals(claimsSet.getIssuer(), resultClaims.getIssuer()); assertEquals(claimsSet.getIssuer(), resultClaims.getIssuer());
assertEquals(claimsSet.getSubject(), resultClaims.getSubject()); assertEquals(claimsSet.getSubject(), resultClaims.getSubject());
@ -231,7 +232,7 @@ public class TestDefaultJWTEncryptionAndDecryptionService {
assertThat(encryptedJwt.getJWTClaimsSet(), nullValue()); assertThat(encryptedJwt.getJWTClaimsSet(), nullValue());
service.decryptJwt(encryptedJwt); service.decryptJwt(encryptedJwt);
ReadOnlyJWTClaimsSet resultClaims = encryptedJwt.getJWTClaimsSet(); JWTClaimsSet resultClaims = encryptedJwt.getJWTClaimsSet();
assertEquals(claimsSet.getIssuer(), resultClaims.getIssuer()); assertEquals(claimsSet.getIssuer(), resultClaims.getIssuer());
assertEquals(claimsSet.getSubject(), resultClaims.getSubject()); assertEquals(claimsSet.getSubject(), resultClaims.getSubject());

View File

@ -206,22 +206,22 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
private OAuth2RefreshTokenEntity createRefreshToken(ClientDetailsEntity client, AuthenticationHolderEntity authHolder) { private OAuth2RefreshTokenEntity createRefreshToken(ClientDetailsEntity client, AuthenticationHolderEntity authHolder) {
OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken(); OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken();
JWTClaimsSet refreshClaims = new JWTClaimsSet(); JWTClaimsSet.Builder refreshClaims = new JWTClaimsSet.Builder();
// make it expire if necessary // make it expire if necessary
if (client.getRefreshTokenValiditySeconds() != null) { if (client.getRefreshTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L)); Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L));
refreshToken.setExpiration(expiration); refreshToken.setExpiration(expiration);
refreshClaims.setExpirationTime(expiration); refreshClaims.expirationTime(expiration);
} }
// set a random identifier // set a random identifier
refreshClaims.setJWTID(UUID.randomUUID().toString()); refreshClaims.jwtID(UUID.randomUUID().toString());
// TODO: add issuer fields, signature to JWT // TODO: add issuer fields, signature to JWT
PlainJWT refreshJwt = new PlainJWT(refreshClaims); PlainJWT refreshJwt = new PlainJWT(refreshClaims.build());
refreshToken.setJwt(refreshJwt); refreshToken.setJwt(refreshJwt);
//Add the authentication //Add the authentication

View File

@ -103,7 +103,7 @@ public class JWTAssertionTokenGranter extends AbstractTokenGranter {
OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity(); OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity();
// copy over all existing claims // copy over all existing claims
JWTClaimsSet claims = new JWTClaimsSet(idToken.getJWTClaimsSet()); JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder(idToken.getJWTClaimsSet());
if (client instanceof ClientDetailsEntity) { if (client instanceof ClientDetailsEntity) {
@ -112,7 +112,7 @@ public class JWTAssertionTokenGranter extends AbstractTokenGranter {
// update expiration and issued-at claims // update expiration and issued-at claims
if (clientEntity.getIdTokenValiditySeconds() != null) { if (clientEntity.getIdTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (clientEntity.getIdTokenValiditySeconds() * 1000L)); Date expiration = new Date(System.currentTimeMillis() + (clientEntity.getIdTokenValiditySeconds() * 1000L));
claims.setExpirationTime(expiration); claims.expirationTime(expiration);
newIdTokenEntity.setExpiration(expiration); newIdTokenEntity.setExpiration(expiration);
} }
@ -122,11 +122,11 @@ public class JWTAssertionTokenGranter extends AbstractTokenGranter {
throw new BadCredentialsException("SEVERE: Client is not an instance of ClientDetailsEntity; JwtAssertionTokenGranter cannot process this request."); throw new BadCredentialsException("SEVERE: Client is not an instance of ClientDetailsEntity; JwtAssertionTokenGranter cannot process this request.");
} }
claims.setIssueTime(new Date()); claims.issueTime(new Date());
claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it claims.jwtID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it
SignedJWT newIdToken = new SignedJWT((JWSHeader) idToken.getHeader(), claims); SignedJWT newIdToken = new SignedJWT((JWSHeader) idToken.getHeader(), claims.build());
jwtService.signJwt(newIdToken); jwtService.signJwt(newIdToken);
newIdTokenEntity.setJwt(newIdToken); newIdTokenEntity.setJwt(newIdToken);

View File

@ -44,7 +44,7 @@ import org.springframework.security.oauth2.common.exceptions.InvalidClientExcept
import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
/** /**
@ -88,7 +88,7 @@ public class JWTBearerAuthenticationProvider implements AuthenticationProvider {
ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId()); ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId());
JWT jwt = jwtAuth.getJwt(); JWT jwt = jwtAuth.getJwt();
ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet(); JWTClaimsSet jwtClaims = jwt.getJWTClaimsSet();
// check the signature with nimbus // check the signature with nimbus
if (jwt instanceof SignedJWT) { if (jwt instanceof SignedJWT) {

View File

@ -17,11 +17,23 @@
package org.mitre.openid.connect.request; package org.mitre.openid.connect.request;
import static org.mitre.openid.connect.request.ConnectRequestParameters.CLAIMS;
import static org.mitre.openid.connect.request.ConnectRequestParameters.CLIENT_ID;
import static org.mitre.openid.connect.request.ConnectRequestParameters.DISPLAY;
import static org.mitre.openid.connect.request.ConnectRequestParameters.LOGIN_HINT;
import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.NONCE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT;
import static org.mitre.openid.connect.request.ConnectRequestParameters.REDIRECT_URI;
import static org.mitre.openid.connect.request.ConnectRequestParameters.REQUEST;
import static org.mitre.openid.connect.request.ConnectRequestParameters.RESPONSE_TYPE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.SCOPE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.STATE;
import java.text.ParseException; import java.text.ParseException;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import org.mitre.jwt.encryption.service.JWTEncryptionAndDecryptionService; import org.mitre.jwt.encryption.service.JWTEncryptionAndDecryptionService;
import org.mitre.jwt.signer.service.JWTSigningAndValidationService; import org.mitre.jwt.signer.service.JWTSigningAndValidationService;
@ -48,24 +60,11 @@ import com.nimbusds.jose.JWEObject.State;
import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jwt.EncryptedJWT; import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.JWTParser; import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.PlainJWT; import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
import static org.mitre.openid.connect.request.ConnectRequestParameters.CLAIMS;
import static org.mitre.openid.connect.request.ConnectRequestParameters.CLIENT_ID;
import static org.mitre.openid.connect.request.ConnectRequestParameters.DISPLAY;
import static org.mitre.openid.connect.request.ConnectRequestParameters.LOGIN_HINT;
import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.NONCE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT;
import static org.mitre.openid.connect.request.ConnectRequestParameters.REDIRECT_URI;
import static org.mitre.openid.connect.request.ConnectRequestParameters.REQUEST;
import static org.mitre.openid.connect.request.ConnectRequestParameters.RESPONSE_TYPE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.SCOPE;
import static org.mitre.openid.connect.request.ConnectRequestParameters.STATE;
@Component("connectOAuth2RequestFactory") @Component("connectOAuth2RequestFactory")
public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
@ -260,7 +259,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
// now that we've got the JWT, and it's been parsed, validated, and/or decrypted, we can process the claims // now that we've got the JWT, and it's been parsed, validated, and/or decrypted, we can process the claims
ReadOnlyJWTClaimsSet claims = jwt.getJWTClaimsSet(); JWTClaimsSet claims = jwt.getJWTClaimsSet();
Set<String> responseTypes = OAuth2Utils.parseParameterList(claims.getStringClaim(RESPONSE_TYPE)); Set<String> responseTypes = OAuth2Utils.parseParameterList(claims.getStringClaim(RESPONSE_TYPE));
if (responseTypes != null && !responseTypes.isEmpty()) { if (responseTypes != null && !responseTypes.isEmpty()) {

View File

@ -102,7 +102,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
OAuth2AccessTokenEntity idTokenEntity = new OAuth2AccessTokenEntity(); OAuth2AccessTokenEntity idTokenEntity = new OAuth2AccessTokenEntity();
JWTClaimsSet idClaims = new JWTClaimsSet(); JWTClaimsSet.Builder idClaims = new JWTClaimsSet.Builder();
// if the auth time claim was explicitly requested OR if the client always wants the auth time, put it in // if the auth time claim was explicitly requested OR if the client always wants the auth time, put it in
if (request.getExtensions().containsKey("max_age") if (request.getExtensions().containsKey("max_age")
@ -113,7 +113,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
Long authTimestamp = Long.parseLong((String) request.getExtensions().get(AuthenticationTimeStamper.AUTH_TIMESTAMP)); Long authTimestamp = Long.parseLong((String) request.getExtensions().get(AuthenticationTimeStamper.AUTH_TIMESTAMP));
if (authTimestamp != null) { if (authTimestamp != null) {
idClaims.setClaim("auth_time", authTimestamp / 1000L); idClaims.claim("auth_time", authTimestamp / 1000L);
} }
} else { } else {
// we couldn't find the timestamp! // we couldn't find the timestamp!
@ -121,22 +121,22 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
} }
} }
idClaims.setIssueTime(issueTime); idClaims.issueTime(issueTime);
if (client.getIdTokenValiditySeconds() != null) { if (client.getIdTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getIdTokenValiditySeconds() * 1000L)); Date expiration = new Date(System.currentTimeMillis() + (client.getIdTokenValiditySeconds() * 1000L));
idClaims.setExpirationTime(expiration); idClaims.expirationTime(expiration);
idTokenEntity.setExpiration(expiration); idTokenEntity.setExpiration(expiration);
} }
idClaims.setIssuer(configBean.getIssuer()); idClaims.issuer(configBean.getIssuer());
idClaims.setSubject(sub); idClaims.subject(sub);
idClaims.setAudience(Lists.newArrayList(client.getClientId())); idClaims.audience(Lists.newArrayList(client.getClientId()));
idClaims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it idClaims.jwtID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it
String nonce = (String)request.getExtensions().get("nonce"); String nonce = (String)request.getExtensions().get("nonce");
if (!Strings.isNullOrEmpty(nonce)) { if (!Strings.isNullOrEmpty(nonce)) {
idClaims.setCustomClaim("nonce", nonce); idClaims.claim("nonce", nonce);
} }
Set<String> responseTypes = request.getResponseTypes(); Set<String> responseTypes = request.getResponseTypes();
@ -144,7 +144,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
if (responseTypes.contains("token")) { if (responseTypes.contains("token")) {
// calculate the token hash // calculate the token hash
Base64URL at_hash = IdTokenHashUtils.getAccessTokenHash(signingAlg, accessToken); Base64URL at_hash = IdTokenHashUtils.getAccessTokenHash(signingAlg, accessToken);
idClaims.setClaim("at_hash", at_hash); idClaims.claim("at_hash", at_hash);
} }
if (client.getIdTokenEncryptedResponseAlg() != null && !client.getIdTokenEncryptedResponseAlg().equals(Algorithm.NONE) if (client.getIdTokenEncryptedResponseAlg() != null && !client.getIdTokenEncryptedResponseAlg().equals(Algorithm.NONE)
@ -155,7 +155,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
if (encrypter != null) { if (encrypter != null) {
EncryptedJWT idToken = new EncryptedJWT(new JWEHeader(client.getIdTokenEncryptedResponseAlg(), client.getIdTokenEncryptedResponseEnc()), idClaims); EncryptedJWT idToken = new EncryptedJWT(new JWEHeader(client.getIdTokenEncryptedResponseAlg(), client.getIdTokenEncryptedResponseEnc()), idClaims.build());
encrypter.encryptJwt(idToken); encrypter.encryptJwt(idToken);
@ -171,7 +171,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
if (signingAlg.equals(Algorithm.NONE)) { if (signingAlg.equals(Algorithm.NONE)) {
// unsigned ID token // unsigned ID token
idToken = new PlainJWT(idClaims); idToken = new PlainJWT(idClaims.build());
} else { } else {
@ -184,20 +184,20 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null,
jwtService.getDefaultSignerKeyId(), jwtService.getDefaultSignerKeyId(),
null, null); null, null);
idToken = new SignedJWT(header, idClaims); idToken = new SignedJWT(header, idClaims.build());
JWTSigningAndValidationService signer = symmetricCacheService.getSymmetricValidtor(client); JWTSigningAndValidationService signer = symmetricCacheService.getSymmetricValidtor(client);
// sign it with the client's secret // sign it with the client's secret
signer.signJwt((SignedJWT) idToken); signer.signJwt((SignedJWT) idToken);
} else { } else {
idClaims.setCustomClaim("kid", jwtService.getDefaultSignerKeyId()); idClaims.claim("kid", jwtService.getDefaultSignerKeyId());
JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null,
jwtService.getDefaultSignerKeyId(), jwtService.getDefaultSignerKeyId(),
null, null); null, null);
idToken = new SignedJWT(header, idClaims); idToken = new SignedJWT(header, idClaims.build());
// sign it with the server's key // sign it with the server's key
jwtService.signJwt((SignedJWT) idToken); jwtService.signJwt((SignedJWT) idToken);
@ -282,13 +282,13 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
authHolder = authenticationHolderRepository.save(authHolder); authHolder = authenticationHolderRepository.save(authHolder);
token.setAuthenticationHolder(authHolder); token.setAuthenticationHolder(authHolder);
JWTClaimsSet claims = new JWTClaimsSet(); JWTClaimsSet claims = new JWTClaimsSet.Builder()
.audience(Lists.newArrayList(client.getClientId()))
claims.setAudience(Lists.newArrayList(client.getClientId())); .issuer(configBean.getIssuer())
claims.setIssuer(configBean.getIssuer()); .issueTime(new Date())
claims.setIssueTime(new Date()); .expirationTime(token.getExpiration())
claims.setExpirationTime(token.getExpiration()); .jwtID(UUID.randomUUID().toString()) // set a random NONCE in the middle of it
claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it .build();
JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm();
JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null,

View File

@ -88,17 +88,13 @@ public class ConnectTokenEnhancer implements TokenEnhancer {
String clientId = originalAuthRequest.getClientId(); String clientId = originalAuthRequest.getClientId();
ClientDetailsEntity client = clientService.loadClientByClientId(clientId); ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
JWTClaimsSet claims = new JWTClaimsSet(); JWTClaimsSet claims = new JWTClaimsSet.Builder()
.audience(Lists.newArrayList(clientId))
claims.setAudience(Lists.newArrayList(clientId)); .issuer(configBean.getIssuer())
.issueTime(new Date())
claims.setIssuer(configBean.getIssuer()); .expirationTime(token.getExpiration())
.jwtID(UUID.randomUUID().toString()) // set a random NONCE in the middle of it
claims.setIssueTime(new Date()); .build();
claims.setExpirationTime(token.getExpiration());
claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it
JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm();
JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null,

View File

@ -98,15 +98,12 @@ public class UserInfoJWTView extends UserInfoView {
response.setContentType(JOSE_MEDIA_TYPE_VALUE); response.setContentType(JOSE_MEDIA_TYPE_VALUE);
JWTClaimsSet claims = JWTClaimsSet.parse(writer.toString()); JWTClaimsSet claims = new JWTClaimsSet.Builder(JWTClaimsSet.parse(writer.toString()))
.audience(Lists.newArrayList(client.getClientId()))
claims.setAudience(Lists.newArrayList(client.getClientId())); .issuer(config.getIssuer())
.issueTime(new Date())
claims.setIssuer(config.getIssuer()); .jwtID(UUID.randomUUID().toString()) // set a random NONCE in the middle of it
.build();
claims.setIssueTime(new Date());
claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it
if (client.getUserInfoEncryptedResponseAlg() != null && !client.getUserInfoEncryptedResponseAlg().equals(Algorithm.NONE) if (client.getUserInfoEncryptedResponseAlg() != null && !client.getUserInfoEncryptedResponseAlg().equals(Algorithm.NONE)

View File

@ -470,7 +470,7 @@
<dependency> <dependency>
<groupId>com.nimbusds</groupId> <groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId> <artifactId>nimbus-jose-jwt</artifactId>
<version>3.9</version> <version>4.2</version>
</dependency> </dependency>
<dependency> <dependency>