refactored JWKs, updated signing servier to use them
parent
adb8499bee
commit
1127a7cfbc
|
@ -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)){
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue