diff --git a/pom.xml b/pom.xml
index 1a02dfcaf..9b0d9b3ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,8 +5,11 @@
org.mitre
openid
OpenIdConnect
- war
+ pom
0.1
+
+ spring-security-oauth/spring-security-oauth2
+
1.6
3.0.6.RELEASE
@@ -304,7 +307,7 @@
- pushEE
+ openid-connect-server
true
diff --git a/src/main/java/org/mitre/jwt/model/ClaimSet.java b/src/main/java/org/mitre/jwt/model/ClaimSet.java
new file mode 100644
index 000000000..9107afea7
--- /dev/null
+++ b/src/main/java/org/mitre/jwt/model/ClaimSet.java
@@ -0,0 +1,117 @@
+package org.mitre.jwt.model;
+
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+public class ClaimSet {
+
+ private Map claims = new LinkedHashMap();
+
+ /**
+ * Get an extension claim
+ */
+ public Object getClaim(String key) {
+ return claims.get(key);
+ }
+
+ /**
+ * Get a claim as a string
+ */
+ public String getClaimAsString(String key) {
+ Object v = claims.get(key);
+ if (v != null) {
+ return v.toString();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get a claim as a Date
+ */
+ public Date getClaimAsDate(String key) {
+ Object v = claims.get(key);
+ if (v != null) {
+ if (v instanceof Date) {
+ return (Date) v;
+ } else if (v instanceof Long) {
+ return new Date((Long) v);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set an extension claim
+ */
+ public void setClaim(String key, Object value) {
+ claims.put(key, value);
+ }
+
+ /**
+ * Set a primitive claim
+ */
+ public void setClaim(String key, JsonPrimitive prim) {
+ if (prim.isBoolean()) {
+ claims.put(key, prim.getAsBoolean());
+ } else if (prim.isNumber()) {
+ claims.put(key, prim.getAsNumber());
+ } else if (prim.isString()) {
+ claims.put(key, prim.getAsString());
+ }
+ }
+
+ /**
+ * Remove an extension claim
+ */
+ public Object removeClaim(String key) {
+ return claims.remove(key);
+ }
+
+
+ /**
+ * Get a copy of this claim set as a JsonObject. The JsonObject is not
+ * backed by a live copy of this ClaimSet.
+ * @return a copy of the data in this header in a JsonObject
+ */
+ public JsonObject getAsJsonObject() {
+ JsonObject o = new JsonObject();
+
+ if (this.claims != null) {
+ for (Map.Entry claim : this.claims.entrySet()) {
+ if (claim.getValue() instanceof JsonElement) {
+ o.add(claim.getKey(), (JsonElement)claim.getValue());
+ } else if (claim.getValue() instanceof String) {
+ o.addProperty(claim.getKey(), (String)claim.getValue());
+ } else if (claim.getValue() instanceof Number) {
+ o.addProperty(claim.getKey(), (Number)claim.getValue());
+ } else if (claim.getValue() instanceof Boolean) {
+ o.addProperty(claim.getKey(), (Boolean)claim.getValue());
+ } else if (claim.getValue() instanceof Character) {
+ o.addProperty(claim.getKey(), (Character)claim.getValue());
+ } else if (claim.getValue() instanceof Date) {
+ // dates get serialized out as integers
+ o.addProperty(claim.getKey(), ((Date)claim.getValue()).getTime() / 1000L);
+ } else if (claim.getValue() != null) {
+ // try to put it in as a string
+ o.addProperty(claim.getKey(), claim.getValue().toString());
+ } else {
+ // otherwise add in as a null
+ o.add(claim.getKey(), null);
+ }
+ }
+ }
+
+ return o;
+ }
+
+
+}
diff --git a/src/main/java/org/mitre/jwt/model/JwtClaims.java b/src/main/java/org/mitre/jwt/model/JwtClaims.java
index ef2136183..c98a5a726 100644
--- a/src/main/java/org/mitre/jwt/model/JwtClaims.java
+++ b/src/main/java/org/mitre/jwt/model/JwtClaims.java
@@ -12,34 +12,21 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
-public class JwtClaims {
+public class JwtClaims extends ClaimSet {
+ public static final String TYPE = "typ";
+ public static final String JWT_ID = "jti";
+ public static final String PRINCIPAL = "prn";
+ public static final String AUDIENCE = "aud";
+ public static final String ISSUER = "iss";
+ public static final String ISSUED_AT = "iat";
+ public static final String NOT_BEFORE = "nbf";
+ public static final String EXPIRATION = "exp";
+
/**
* ISO8601 / RFC3339 Date Format
*/
- public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
-
- /*
- * TODO: Should we instead be using a generic claims map with well-named accessor methods?
- */
-
- private Date expiration;
-
- private Date notBefore;
-
- private Date issuedAt;
-
- private String issuer;
-
- private String audience;
-
- private String principal;
-
- private String jwtId;
-
- private String type;
-
- private Map claims = new HashMap();
+ //public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
public JwtClaims() {
@@ -47,36 +34,28 @@ public class JwtClaims {
public JwtClaims(JsonObject json) {
for (Entry element : json.entrySet()) {
- if (element.getKey().equals("exp")) {
- expiration = new Date(element.getValue().getAsLong() * 1000L);
- } else if (element.getKey().equals("nbf")) {
- notBefore = new Date(element.getValue().getAsLong() * 1000L);
- } else if (element.getKey().equals("iat")) {
- issuedAt = new Date(element.getValue().getAsLong() * 1000L);
- } else if (element.getKey().equals("iss")) {
- issuer = element.getValue().getAsString();
- } else if (element.getKey().equals("aud")) {
- audience = element.getValue().getAsString();
- } else if (element.getKey().equals("prn")) {
- principal = element.getValue().getAsString();
- } else if (element.getKey().equals("jti")) {
- jwtId = element.getValue().getAsString();
- } else if (element.getKey().equals("typ")) {
- type = element.getValue().getAsString();
+ if (element.getKey().equals(EXPIRATION)) {
+ setExpiration(new Date(element.getValue().getAsLong() * 1000L));
+ } else if (element.getKey().equals(NOT_BEFORE)) {
+ setNotBefore(new Date(element.getValue().getAsLong() * 1000L));
+ } else if (element.getKey().equals(ISSUED_AT)) {
+ setIssuedAt(new Date(element.getValue().getAsLong() * 1000L));
+ } else if (element.getKey().equals(ISSUER)) {
+ setIssuer(element.getValue().getAsString());
+ } else if (element.getKey().equals(AUDIENCE)) {
+ setAudience(element.getValue().getAsString());
+ } else if (element.getKey().equals(PRINCIPAL)) {
+ setPrincipal(element.getValue().getAsString());
+ } else if (element.getKey().equals(JWT_ID)) {
+ setJwtId(element.getValue().getAsString());
+ } else if (element.getKey().equals(TYPE)) {
+ setType(element.getValue().getAsString());
} else if (element.getValue().isJsonPrimitive()){
// we handle all primitives in here
JsonPrimitive prim = element.getValue().getAsJsonPrimitive();
-
- if (prim.isBoolean()) {
- claims.put(element.getKey(), prim.getAsBoolean());
- } else if (prim.isNumber()) {
- claims.put(element.getKey(), prim.getAsNumber());
- } else if (prim.isString()) {
- claims.put(element.getKey(), prim.getAsString());
- }
+ setClaim(element.getKey(), prim);
} else {
- // everything else gets handled as a raw JsonElement
- claims.put(element.getKey(), element.getValue());
+ setClaim(element.getKey(), element.getValue());
}
}
}
@@ -85,208 +64,113 @@ public class JwtClaims {
* @return the expiration
*/
public Date getExpiration() {
- return expiration;
+ return getClaimAsDate(EXPIRATION);
}
/**
* @param expiration the expiration to set
*/
public void setExpiration(Date expiration) {
- this.expiration = expiration;
+ setClaim(EXPIRATION, expiration);
}
/**
* @return the notBefore
*/
public Date getNotBefore() {
- return notBefore;
+ return getClaimAsDate(NOT_BEFORE);
}
/**
* @param notBefore the notBefore to set
*/
public void setNotBefore(Date notBefore) {
- this.notBefore = notBefore;
+ setClaim(NOT_BEFORE, notBefore);
}
/**
* @return the issuedAt
*/
public Date getIssuedAt() {
- return issuedAt;
+ return getClaimAsDate(ISSUED_AT);
}
/**
* @param issuedAt the issuedAt to set
*/
public void setIssuedAt(Date issuedAt) {
- this.issuedAt = issuedAt;
+ setClaim(ISSUED_AT, issuedAt);
}
/**
* @return the issuer
*/
public String getIssuer() {
- return issuer;
+ return getClaimAsString(ISSUER);
}
/**
* @param issuer the issuer to set
*/
public void setIssuer(String issuer) {
- this.issuer = issuer;
+ setClaim(ISSUER, issuer);
}
/**
* @return the audience
*/
public String getAudience() {
- return audience;
+ return getClaimAsString(AUDIENCE);
}
/**
* @param audience the audience to set
*/
public void setAudience(String audience) {
- this.audience = audience;
+ setClaim(AUDIENCE, audience);
}
/**
* @return the principal
*/
public String getPrincipal() {
- return principal;
+ return getClaimAsString(PRINCIPAL);
}
/**
* @param principal the principal to set
*/
public void setPrincipal(String principal) {
- this.principal = principal;
+ setClaim(AUDIENCE, principal);
}
/**
* @return the jwtId
*/
public String getJwtId() {
- return jwtId;
+ return getClaimAsString(JWT_ID);
}
/**
* @param jwtId the jwtId to set
*/
public void setJwtId(String jwtId) {
- this.jwtId = jwtId;
+ setClaim(JWT_ID, jwtId);
}
/**
* @return the type
*/
public String getType() {
- return type;
+ return getClaimAsString(TYPE);
}
/**
* @param type the type to set
*/
public void setType(String type) {
- this.type = type;
- }
-
- /**
- * Get an extension claim
- */
- public Object getClaim(String key) {
- return claims.get(key);
- }
-
- /**
- * Set an extension claim
- */
- public void setClaim(String key, Object value) {
- claims.put(key, value);
- }
-
- /**
- * Remove an extension claim
- */
- public Object removeClaim(String key) {
- return claims.remove(key);
+ setClaim(TYPE, type);
}
- /**
- * Get a copy of this header as a JsonObject. The JsonObject is not
- * backed by a live copy of this JwtHeader.
- * @return a copy of the data in this header in a JsonObject
- */
- public JsonObject getAsJsonObject() {
- JsonObject o = new JsonObject();
-
- if (this.expiration != null) {
- o.addProperty("exp", this.expiration.getTime() / 1000L);
- }
-
- if (this.notBefore != null) {
- o.addProperty("nbf", this.notBefore.getTime() / 1000L);
- }
-
- if (this.issuedAt != null) {
- o.addProperty("iat", this.issuedAt.getTime() / 1000L);
- }
-
- if (this.issuer != null) {
- o.addProperty("iss", this.issuer);
- }
-
- if (this.audience != null) {
- o.addProperty("aud", this.audience);
- }
-
- if (this.principal != null) {
- o.addProperty("prn", this.principal);
- }
-
- if (this.jwtId != null) {
- o.addProperty("jti", this.jwtId);
- }
-
- if (this.type != null) {
- o.addProperty("typ", this.type);
- }
-
- if (this.claims != null) {
- for (Map.Entry claim : this.claims.entrySet()) {
- if (claim.getValue() instanceof JsonElement) {
- o.add(claim.getKey(), (JsonElement)claim.getValue());
- } else if (claim.getValue() instanceof String) {
- o.addProperty(claim.getKey(), (String)claim.getValue());
- } else if (claim.getValue() instanceof Number) {
- o.addProperty(claim.getKey(), (Number)claim.getValue());
- } else if (claim.getValue() instanceof Boolean) {
- o.addProperty(claim.getKey(), (Boolean)claim.getValue());
- } else if (claim.getValue() instanceof Character) {
- o.addProperty(claim.getKey(), (Character)claim.getValue());
- } else if (claim.getValue() != null) {
- // try to put it in as a string
- o.addProperty(claim.getKey(), claim.getValue().toString());
- } else {
- // otherwise add in as a null
- o.add(claim.getKey(), null);
- }
- }
- }
-
- return o;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "JwtClaims [expiration=" + expiration + ", notBefore=" + notBefore + ", issuedAt=" + issuedAt + ", issuer=" + issuer + ", audience=" + audience + ", principal=" + principal + ", jwtId=" + jwtId + ", type=" + type + ", claims=" + claims + "]";
- }
-
-
}
diff --git a/src/main/java/org/mitre/jwt/model/JwtHeader.java b/src/main/java/org/mitre/jwt/model/JwtHeader.java
index 099f6e786..5c44d9d3f 100644
--- a/src/main/java/org/mitre/jwt/model/JwtHeader.java
+++ b/src/main/java/org/mitre/jwt/model/JwtHeader.java
@@ -7,21 +7,12 @@ import java.util.Map.Entry;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
-public class JwtHeader {
+public class JwtHeader extends ClaimSet {
- /*
- * TODO: Should we instead be using a generic claims map with well-named accessor methods?
- */
-
- private String type;
-
- private String algorithm;
-
- private String encryptionMethod;
-
- private Map claims = new HashMap();
+ public static final String TYPE = "typ";
+ public static final String ALGORITHM = "alg";
+ public static final String ENCRYPTION_METHOD = "enc";
-
/**
* Make an empty header
*/
@@ -36,15 +27,15 @@ public class JwtHeader {
public JwtHeader(JsonObject json) {
for (Entry element : json.entrySet()) {
- if (element.getKey().equals("typ")) {
- this.type = json.get("typ").getAsString();
- } else if (element.getKey().equals("alg")) {
- this.algorithm = json.get("alg").getAsString();
- } else if (element.getKey().equals("enc")) {
- this.encryptionMethod = json.get("enc").getAsString();
+ if (element.getKey().equals(TYPE)) {
+ this.setType(json.get(TYPE).getAsString());
+ } else if (element.getKey().equals(ALGORITHM)) {
+ this.setAlgorithm(json.get(ALGORITHM).getAsString());
+ } else if (element.getKey().equals(ENCRYPTION_METHOD)) {
+ this.setEncryptionMethod(json.get(ENCRYPTION_METHOD).getAsString());
} else {
// TODO: this assumes string encoding for extensions, probably not quite correct
- claims.put(element.getKey(), element.getValue().getAsString());
+ setClaim(element.getKey(), element.getValue().getAsString());
}
}
}
@@ -53,7 +44,7 @@ public class JwtHeader {
* @return the type
*/
public String getType() {
- return type;
+ return getClaimAsString(TYPE);
}
@@ -61,7 +52,7 @@ public class JwtHeader {
* @param type the type to set
*/
public void setType(String type) {
- this.type = type;
+ setClaim(TYPE, type);
}
@@ -69,7 +60,7 @@ public class JwtHeader {
* @return the algorithm
*/
public String getAlgorithm() {
- return algorithm;
+ return getClaimAsString(ALGORITHM);
}
@@ -77,7 +68,7 @@ public class JwtHeader {
* @param algorithm the algorithm to set
*/
public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
+ setClaim(ALGORITHM, algorithm);
}
@@ -85,7 +76,7 @@ public class JwtHeader {
* @return the encryptionMethod
*/
public String getEncryptionMethod() {
- return encryptionMethod;
+ return getClaimAsString(ENCRYPTION_METHOD);
}
@@ -93,80 +84,7 @@ public class JwtHeader {
* @param encryptionMethod the encryptionMethod to set
*/
public void setEncryptionMethod(String encryptionMethod) {
- this.encryptionMethod = encryptionMethod;
- }
-
- /**
- * Get an extension claim
- */
- public Object getClaim(String key) {
- return claims.get(key);
- }
-
- /**
- * Set an extension claim
- */
- public void setClaim(String key, Object value) {
- claims.put(key, value);
+ setClaim(ENCRYPTION_METHOD, encryptionMethod);
}
- /**
- * Remove an extension claim
- */
- public Object removeClaim(String key) {
- return claims.remove(key);
- }
-
- /**
- * Get a copy of this header as a JsonObject. The JsonObject is not
- * backed by a live copy of this JwtHeader.
- * @return a copy of the data in this header in a JsonObject
- */
- public JsonObject getAsJsonObject() {
- JsonObject o = new JsonObject();
-
- if (this.type != null) {
- o.addProperty("typ", this.type);
- }
- if (this.algorithm != null) {
- o.addProperty("alg", this.algorithm);
- }
-
- if (this.encryptionMethod != null) {
- o.addProperty("enc", this.encryptionMethod);
- }
-
- if (this.claims != null) {
- for (Map.Entry claim : this.claims.entrySet()) {
- if (claim.getValue() instanceof String) {
- o.addProperty(claim.getKey(), (String)claim.getValue());
- } else if (claim.getValue() instanceof Number) {
- o.addProperty(claim.getKey(), (Number)claim.getValue());
- } else if (claim.getValue() instanceof Boolean) {
- o.addProperty(claim.getKey(), (Boolean)claim.getValue());
- } else if (claim.getValue() instanceof Character) {
- o.addProperty(claim.getKey(), (Character)claim.getValue());
- } else if (claim.getValue() != null) {
- // try to put it in as a string
- o.addProperty(claim.getKey(), claim.getValue().toString());
- } else {
- // otherwise add in as a null
- o.add(claim.getKey(), null);
- }
- }
- }
-
- return o;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "JwtHeader [type=" + type + ", algorithm=" + algorithm + ", encryptionMethod=" + encryptionMethod + ", claims=" + claims + "]";
- }
-
-
-
}