refactored JWKs, updated signing servier to use them

pull/105/merge
Justin Richer 2012-06-25 17:19:25 -04:00
parent adb8499bee
commit 1127a7cfbc
6 changed files with 26 additions and 56 deletions

View File

@ -489,7 +489,6 @@ public class AbstractOIDCAuthenticationFilter extends
if(jwtValidator.validateSignature(jsonRoot.getAsJsonObject().get("id_token").getAsString()) if(jwtValidator.validateSignature(jsonRoot.getAsJsonObject().get("id_token").getAsString())
&& idToken.getClaims().getIssuer() != null && idToken.getClaims().getIssuer() != null
&& idToken.getClaims().getIssuer().equals(serverConfig.getIssuer()) && idToken.getClaims().getIssuer().equals(serverConfig.getIssuer())
&& idToken.getClaims().getIssuer().equals(serverConfig.getClientId())
&& !jwtValidator.isJwtExpired(idToken) && !jwtValidator.isJwtExpired(idToken)
&& jwtValidator.validateIssuedAt(idToken)){ && jwtValidator.validateIssuedAt(idToken)){

View File

@ -20,6 +20,7 @@ import java.security.PublicKey;
import java.util.Map; import java.util.Map;
import org.mitre.jwt.model.Jwt; import org.mitre.jwt.model.Jwt;
import org.mitre.jwt.signer.JwtSigner;
public interface JwtSigningAndValidationService { public interface JwtSigningAndValidationService {
@ -28,7 +29,7 @@ public interface JwtSigningAndValidationService {
* *
* @return * @return
*/ */
public Map<String, PublicKey> getAllPublicKeys(); public Map<String, JwtSigner> getAllSigners();
/** /**
* Check to see if this JWT has expired or not * Check to see if this JWT has expired or not

View File

@ -50,7 +50,8 @@ public abstract class AbstractJwtSigningAndValidationService implements JwtSigni
Date issuedAt = jwt.getClaims().getIssuedAt(); Date issuedAt = jwt.getClaims().getIssuedAt();
if (issuedAt != null) { if (issuedAt != null) {
return new Date().before(issuedAt); // make sure the token was issued in the past
return new Date().after(issuedAt);
} else { } else {
return false; return false;
} }

View File

@ -77,34 +77,20 @@ public class JwtSigningAndValidationServiceDefault extends AbstractJwtSigningAnd
} }
/* /**
* (non-Javadoc) *
* Returns a copy of the collection of signers.
* *
* @see * @see
* org.mitre.jwt.signer.service.JwtSigningAndValidationService#getAllPublicKeys * org.mitre.jwt.signer.service.JwtSigningAndValidationService#getAllPublicKeys
* () * ()
*/ */
@Override @Override
public Map<String, PublicKey> getAllPublicKeys() { public Map<String, JwtSigner> getAllSigners() {
Map<String, PublicKey> map = new HashMap<String, PublicKey>(); Map<String, JwtSigner> map = new HashMap<String, JwtSigner>();
for (String signerId : signers.keySet()) { map.putAll(signers);
JwtSigner signer = signers.get(signerId);
if (signer instanceof RsaSigner) {
RsaSigner rsa = (RsaSigner)signer;
PublicKey publicKey = rsa.getPublicKey();
if (publicKey != null) {
map.put(signerId, publicKey);
}
}
}
return map; return map;
} }
@ -165,23 +151,4 @@ public class JwtSigningAndValidationServiceDefault extends AbstractJwtSigningAnd
return signers; return signers;
} }
@Override
public boolean validateIssuedAt(Jwt jwt) {
Date issuedAt = jwt.getClaims().getIssuedAt();
if (issuedAt != null)
return new Date().before(issuedAt);
else
return false;
}
@Override
public boolean validateNonce(Jwt jwt, String nonce) {
if(nonce.equals(jwt.getClaims().getNonce())){
return true;
}
else{
return false;
}
}
} }

View File

@ -30,6 +30,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.mitre.jwt.signer.JwtSigner;
import org.mitre.jwt.signer.impl.RsaSigner;
import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.web.servlet.view.AbstractView; import org.springframework.web.servlet.view.AbstractView;
@ -77,19 +79,22 @@ public class JwkKeyListView extends AbstractView {
Writer out = response.getWriter(); Writer out = response.getWriter();
BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys"); //BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys");
Map<String, JwtSigner> signers = (Map<String, JwtSigner>) model.get("signers");
JsonObject obj = new JsonObject(); JsonObject obj = new JsonObject();
JsonArray keys = new JsonArray(); JsonArray keys = new JsonArray();
obj.add("keys", keys); obj.add("keys", keys);
for (String keyId : keyMap.keySet()) { for (String keyId : signers.keySet()) {
PublicKey src = keyMap.get(keyId); JwtSigner src = signers.get(keyId);
if (src instanceof RSAPublicKey) { if (src instanceof RsaSigner) {
RSAPublicKey rsa = (RSAPublicKey)src; RsaSigner rsaSigner = (RsaSigner) src;
RSAPublicKey rsa = (RSAPublicKey) rsaSigner.getPublicKey(); // we're sure this is an RSAPublicKey b/c this is an RsaSigner
BigInteger mod = rsa.getModulus(); BigInteger mod = rsa.getModulus();
@ -101,13 +106,13 @@ public class JwkKeyListView extends AbstractView {
JsonObject o = new JsonObject(); JsonObject o = new JsonObject();
o.addProperty("use", "sig"); // since we don't do encryption yet o.addProperty("use", "sig"); // since we don't do encryption yet
o.addProperty("alg", "RS" + rsa.getModulus().bitLength()); // we know this is RSA o.addProperty("alg", rsaSigner.getAlgorithm()); // we know this is RSA
o.addProperty("mod", m64); o.addProperty("mod", m64);
o.addProperty("exp", e64); o.addProperty("exp", e64);
o.addProperty("kid", keyId); o.addProperty("kid", keyId);
keys.add(o); keys.add(o);
} } // TODO: deal with non-RSA key types
} }
gson.toJson(obj, out); gson.toJson(obj, out);

View File

@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.mitre.jwt.signer.JwtSigner;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -40,16 +41,12 @@ public class JsonWebKeyEndpoint {
@RequestMapping("/jwk") @RequestMapping("/jwk")
public ModelAndView getJwk() { public ModelAndView getJwk() {
// get all public keys for display // map from key id to signer
// map from key id to public key for that signer Map<String, JwtSigner> signers = jwtService.getAllSigners();
Map<String, PublicKey> keys = jwtService.getAllPublicKeys();
// put them into a bidirectional map to get at key IDs
BiMap<String, PublicKey> biKeys = HashBiMap.create(keys);
// TODO: check if keys are empty, return a 404 here or just an empty list? // TODO: check if keys are empty, return a 404 here or just an empty list?
return new ModelAndView("jwkKeyList", "keys", biKeys); return new ModelAndView("jwkKeyList", "signers", signers);
} }
} }