tweaked pom, refactored jwt claims

pull/59/head
Justin Richer 13 years ago
parent c87346a4ab
commit cd0a117031

@ -5,8 +5,11 @@
<groupId>org.mitre</groupId> <groupId>org.mitre</groupId>
<artifactId>openid</artifactId> <artifactId>openid</artifactId>
<name>OpenIdConnect</name> <name>OpenIdConnect</name>
<packaging>war</packaging> <packaging>pom</packaging>
<version>0.1</version> <version>0.1</version>
<modules>
<module>spring-security-oauth/spring-security-oauth2</module>
</modules>
<properties> <properties>
<java-version>1.6</java-version> <java-version>1.6</java-version>
<org.springframework-version>3.0.6.RELEASE</org.springframework-version> <org.springframework-version>3.0.6.RELEASE</org.springframework-version>
@ -304,7 +307,7 @@
</execution> </execution>
</executions> </executions>
<configuration> <configuration>
<warName>pushEE</warName> <warName>openid-connect-server</warName>
<useCache>true</useCache> <useCache>true</useCache>
</configuration> </configuration>
</plugin> </plugin>

@ -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<String, Object> claims = new LinkedHashMap<String, Object>();
/**
* 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<String, Object> 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;
}
}

@ -12,34 +12,21 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; 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 * ISO8601 / RFC3339 Date Format
*/ */
public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"); //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<String, Object> claims = new HashMap<String, Object>();
public JwtClaims() { public JwtClaims() {
@ -47,36 +34,28 @@ public class JwtClaims {
public JwtClaims(JsonObject json) { public JwtClaims(JsonObject json) {
for (Entry<String, JsonElement> element : json.entrySet()) { for (Entry<String, JsonElement> element : json.entrySet()) {
if (element.getKey().equals("exp")) { if (element.getKey().equals(EXPIRATION)) {
expiration = new Date(element.getValue().getAsLong() * 1000L); setExpiration(new Date(element.getValue().getAsLong() * 1000L));
} else if (element.getKey().equals("nbf")) { } else if (element.getKey().equals(NOT_BEFORE)) {
notBefore = new Date(element.getValue().getAsLong() * 1000L); setNotBefore(new Date(element.getValue().getAsLong() * 1000L));
} else if (element.getKey().equals("iat")) { } else if (element.getKey().equals(ISSUED_AT)) {
issuedAt = new Date(element.getValue().getAsLong() * 1000L); setIssuedAt(new Date(element.getValue().getAsLong() * 1000L));
} else if (element.getKey().equals("iss")) { } else if (element.getKey().equals(ISSUER)) {
issuer = element.getValue().getAsString(); setIssuer(element.getValue().getAsString());
} else if (element.getKey().equals("aud")) { } else if (element.getKey().equals(AUDIENCE)) {
audience = element.getValue().getAsString(); setAudience(element.getValue().getAsString());
} else if (element.getKey().equals("prn")) { } else if (element.getKey().equals(PRINCIPAL)) {
principal = element.getValue().getAsString(); setPrincipal(element.getValue().getAsString());
} else if (element.getKey().equals("jti")) { } else if (element.getKey().equals(JWT_ID)) {
jwtId = element.getValue().getAsString(); setJwtId(element.getValue().getAsString());
} else if (element.getKey().equals("typ")) { } else if (element.getKey().equals(TYPE)) {
type = element.getValue().getAsString(); setType(element.getValue().getAsString());
} else if (element.getValue().isJsonPrimitive()){ } else if (element.getValue().isJsonPrimitive()){
// we handle all primitives in here // we handle all primitives in here
JsonPrimitive prim = element.getValue().getAsJsonPrimitive(); JsonPrimitive prim = element.getValue().getAsJsonPrimitive();
setClaim(element.getKey(), prim);
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());
}
} else { } else {
// everything else gets handled as a raw JsonElement setClaim(element.getKey(), element.getValue());
claims.put(element.getKey(), element.getValue());
} }
} }
} }
@ -85,208 +64,113 @@ public class JwtClaims {
* @return the expiration * @return the expiration
*/ */
public Date getExpiration() { public Date getExpiration() {
return expiration; return getClaimAsDate(EXPIRATION);
} }
/** /**
* @param expiration the expiration to set * @param expiration the expiration to set
*/ */
public void setExpiration(Date expiration) { public void setExpiration(Date expiration) {
this.expiration = expiration; setClaim(EXPIRATION, expiration);
} }
/** /**
* @return the notBefore * @return the notBefore
*/ */
public Date getNotBefore() { public Date getNotBefore() {
return notBefore; return getClaimAsDate(NOT_BEFORE);
} }
/** /**
* @param notBefore the notBefore to set * @param notBefore the notBefore to set
*/ */
public void setNotBefore(Date notBefore) { public void setNotBefore(Date notBefore) {
this.notBefore = notBefore; setClaim(NOT_BEFORE, notBefore);
} }
/** /**
* @return the issuedAt * @return the issuedAt
*/ */
public Date getIssuedAt() { public Date getIssuedAt() {
return issuedAt; return getClaimAsDate(ISSUED_AT);
} }
/** /**
* @param issuedAt the issuedAt to set * @param issuedAt the issuedAt to set
*/ */
public void setIssuedAt(Date issuedAt) { public void setIssuedAt(Date issuedAt) {
this.issuedAt = issuedAt; setClaim(ISSUED_AT, issuedAt);
} }
/** /**
* @return the issuer * @return the issuer
*/ */
public String getIssuer() { public String getIssuer() {
return issuer; return getClaimAsString(ISSUER);
} }
/** /**
* @param issuer the issuer to set * @param issuer the issuer to set
*/ */
public void setIssuer(String issuer) { public void setIssuer(String issuer) {
this.issuer = issuer; setClaim(ISSUER, issuer);
} }
/** /**
* @return the audience * @return the audience
*/ */
public String getAudience() { public String getAudience() {
return audience; return getClaimAsString(AUDIENCE);
} }
/** /**
* @param audience the audience to set * @param audience the audience to set
*/ */
public void setAudience(String audience) { public void setAudience(String audience) {
this.audience = audience; setClaim(AUDIENCE, audience);
} }
/** /**
* @return the principal * @return the principal
*/ */
public String getPrincipal() { public String getPrincipal() {
return principal; return getClaimAsString(PRINCIPAL);
} }
/** /**
* @param principal the principal to set * @param principal the principal to set
*/ */
public void setPrincipal(String principal) { public void setPrincipal(String principal) {
this.principal = principal; setClaim(AUDIENCE, principal);
} }
/** /**
* @return the jwtId * @return the jwtId
*/ */
public String getJwtId() { public String getJwtId() {
return jwtId; return getClaimAsString(JWT_ID);
} }
/** /**
* @param jwtId the jwtId to set * @param jwtId the jwtId to set
*/ */
public void setJwtId(String jwtId) { public void setJwtId(String jwtId) {
this.jwtId = jwtId; setClaim(JWT_ID, jwtId);
} }
/** /**
* @return the type * @return the type
*/ */
public String getType() { public String getType() {
return type; return getClaimAsString(TYPE);
} }
/** /**
* @param type the type to set * @param type the type to set
*/ */
public void setType(String type) { public void setType(String type) {
this.type = type; setClaim(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);
} }
/**
* 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<String, Object> 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 + "]";
}
} }

@ -7,21 +7,12 @@ import java.util.Map.Entry;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
public class JwtHeader { public class JwtHeader extends ClaimSet {
/* public static final String TYPE = "typ";
* TODO: Should we instead be using a generic claims map with well-named accessor methods? public static final String ALGORITHM = "alg";
*/ public static final String ENCRYPTION_METHOD = "enc";
private String type;
private String algorithm;
private String encryptionMethod;
private Map<String, Object> claims = new HashMap<String, Object>();
/** /**
* Make an empty header * Make an empty header
*/ */
@ -36,15 +27,15 @@ public class JwtHeader {
public JwtHeader(JsonObject json) { public JwtHeader(JsonObject json) {
for (Entry<String, JsonElement> element : json.entrySet()) { for (Entry<String, JsonElement> element : json.entrySet()) {
if (element.getKey().equals("typ")) { if (element.getKey().equals(TYPE)) {
this.type = json.get("typ").getAsString(); this.setType(json.get(TYPE).getAsString());
} else if (element.getKey().equals("alg")) { } else if (element.getKey().equals(ALGORITHM)) {
this.algorithm = json.get("alg").getAsString(); this.setAlgorithm(json.get(ALGORITHM).getAsString());
} else if (element.getKey().equals("enc")) { } else if (element.getKey().equals(ENCRYPTION_METHOD)) {
this.encryptionMethod = json.get("enc").getAsString(); this.setEncryptionMethod(json.get(ENCRYPTION_METHOD).getAsString());
} else { } else {
// TODO: this assumes string encoding for extensions, probably not quite correct // 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 * @return the type
*/ */
public String getType() { public String getType() {
return type; return getClaimAsString(TYPE);
} }
@ -61,7 +52,7 @@ public class JwtHeader {
* @param type the type to set * @param type the type to set
*/ */
public void setType(String type) { public void setType(String type) {
this.type = type; setClaim(TYPE, type);
} }
@ -69,7 +60,7 @@ public class JwtHeader {
* @return the algorithm * @return the algorithm
*/ */
public String getAlgorithm() { public String getAlgorithm() {
return algorithm; return getClaimAsString(ALGORITHM);
} }
@ -77,7 +68,7 @@ public class JwtHeader {
* @param algorithm the algorithm to set * @param algorithm the algorithm to set
*/ */
public void setAlgorithm(String algorithm) { public void setAlgorithm(String algorithm) {
this.algorithm = algorithm; setClaim(ALGORITHM, algorithm);
} }
@ -85,7 +76,7 @@ public class JwtHeader {
* @return the encryptionMethod * @return the encryptionMethod
*/ */
public String getEncryptionMethod() { public String getEncryptionMethod() {
return encryptionMethod; return getClaimAsString(ENCRYPTION_METHOD);
} }
@ -93,80 +84,7 @@ public class JwtHeader {
* @param encryptionMethod the encryptionMethod to set * @param encryptionMethod the encryptionMethod to set
*/ */
public void setEncryptionMethod(String encryptionMethod) { public void setEncryptionMethod(String encryptionMethod) {
this.encryptionMethod = encryptionMethod; setClaim(ENCRYPTION_METHOD, 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);
} }
/**
* 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<String, Object> 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 + "]";
}
} }

Loading…
Cancel
Save