started a JWT library
parent
a8d39b905f
commit
7a6af8c07d
|
@ -1 +1 @@
|
|||
Subproject commit f1f301046b6c6f397bc4d40a25dd407ca6f2b757
|
||||
Subproject commit b81dd3091e53be285bbfd9f0886b5a88b2cab19c
|
11
pom.xml
11
pom.xml
|
@ -194,7 +194,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>1.7.1</version>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
|
@ -214,7 +214,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>r09</version>
|
||||
<version>10.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
|
@ -229,7 +229,12 @@
|
|||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.3</version>
|
||||
<version>1.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk16</artifactId>
|
||||
<version>1.46</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
package org.mitre.jwt;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class Jwt {
|
||||
|
||||
private JwtHeader header = new JwtHeader();
|
||||
|
||||
private JwtClaims claims = new JwtClaims();
|
||||
|
||||
private String signature;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the header
|
||||
*/
|
||||
public JwtHeader getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param header the header to set
|
||||
*/
|
||||
public void setHeader(JwtHeader header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the claims
|
||||
*/
|
||||
public JwtClaims getClaims() {
|
||||
return claims;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param claims the claims to set
|
||||
*/
|
||||
public void setClaims(JwtClaims claims) {
|
||||
this.claims = claims;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the signature
|
||||
*/
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param signature the signature to set
|
||||
*/
|
||||
public void setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the canonical encoded string of this JWT
|
||||
*/
|
||||
public String toString() {
|
||||
JsonObject h = header.getAsJsonObject();
|
||||
JsonObject o = claims.getAsJsonObject();
|
||||
|
||||
String h64 = new String(Base64.encodeBase64URLSafe(h.toString().getBytes()));
|
||||
String o64 = new String(Base64.encodeBase64(o.toString().getBytes()));
|
||||
|
||||
return h64 + "." + o64 + "." + Strings.nullToEmpty(this.signature);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a wire-encoded JWT
|
||||
*/
|
||||
public static Jwt parse(String s) {
|
||||
|
||||
// split on the dots
|
||||
List<String> parts = Lists.newArrayList(Splitter.on(".").split(s));
|
||||
|
||||
if (parts.size() != 3) {
|
||||
throw new IllegalArgumentException("Invalid JWT format.");
|
||||
}
|
||||
|
||||
String h64 = parts.get(0);
|
||||
String o64 = parts.get(1);
|
||||
String s64 = parts.get(2);
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
|
||||
|
||||
|
||||
// shuttle for return value
|
||||
Jwt jwt = new Jwt();
|
||||
|
||||
return jwt;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
package org.mitre.jwt;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class JwtClaims {
|
||||
|
||||
/**
|
||||
* ISO8601 / RFC3339 Date Format
|
||||
*/
|
||||
public static DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-DD'T'HH:mm:ssz");
|
||||
|
||||
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() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expiration
|
||||
*/
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expiration the expiration to set
|
||||
*/
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the notBefore
|
||||
*/
|
||||
public Date getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param notBefore the notBefore to set
|
||||
*/
|
||||
public void setNotBefore(Date notBefore) {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the issuedAt
|
||||
*/
|
||||
public Date getIssuedAt() {
|
||||
return issuedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param issuedAt the issuedAt to set
|
||||
*/
|
||||
public void setIssuedAt(Date issuedAt) {
|
||||
this.issuedAt = issuedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the issuer
|
||||
*/
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param issuer the issuer to set
|
||||
*/
|
||||
public void setIssuer(String issuer) {
|
||||
this.issuer = issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the audience
|
||||
*/
|
||||
public String getAudience() {
|
||||
return audience;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param audience the audience to set
|
||||
*/
|
||||
public void setAudience(String audience) {
|
||||
this.audience = audience;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the principal
|
||||
*/
|
||||
public String getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param principal the principal to set
|
||||
*/
|
||||
public void setPrincipal(String principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jwtId
|
||||
*/
|
||||
public String getJwtId() {
|
||||
return jwtId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jwtId the jwtId to set
|
||||
*/
|
||||
public void setJwtId(String jwtId) {
|
||||
this.jwtId = jwtId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public String getType() {
|
||||
return 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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", dateFormat.format(this.expiration));
|
||||
}
|
||||
|
||||
if (this.notBefore != null) {
|
||||
o.addProperty("nbf", dateFormat.format(this.notBefore));
|
||||
}
|
||||
|
||||
if (this.issuedAt != null) {
|
||||
o.addProperty("iat", dateFormat.format(this.issuedAt));
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package org.mitre.jwt;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class JwtHeader {
|
||||
|
||||
private String type;
|
||||
|
||||
private String algorithm;
|
||||
|
||||
private String encryptionMethod;
|
||||
|
||||
private Map<String, Object> claims = new HashMap<String, Object>();
|
||||
|
||||
|
||||
public JwtHeader() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the algorithm
|
||||
*/
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param algorithm the algorithm to set
|
||||
*/
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the encryptionMethod
|
||||
*/
|
||||
public String getEncryptionMethod() {
|
||||
return encryptionMethod;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package org.mitre.jwt;
|
||||
|
||||
public interface JwtSigner {
|
||||
|
||||
public void sign(Jwt jwt);
|
||||
|
||||
}
|
|
@ -2,11 +2,13 @@ package org.mitre.openid.connect.model;
|
|||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import org.mitre.jwt.Jwt;
|
||||
|
||||
/*
|
||||
* TODO: This class needs to be encoded as a JWT
|
||||
*/
|
||||
@Entity
|
||||
public class IdToken {
|
||||
public class IdToken extends Jwt {
|
||||
|
||||
private String iss;
|
||||
private String user_id;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</beans:bean>
|
||||
|
||||
<!-- JSON views for each type of model object -->
|
||||
<beans:bean id="jsonUserInfoView" class="org.mitre.openid.connect.model.serializer.JSONUserInfoView"/>
|
||||
<beans:bean id="jsonIdTokenView" class="org.mitre.openid.connect.model.serializer.JSONIdTokenView"/>
|
||||
<!-- <beans:bean id="jsonUserInfoView" class="org.mitre.openid.connect.model.serializer.JSONUserInfoView"/> -->
|
||||
<!-- <beans:bean id="jsonIdTokenView" class="org.mitre.openid.connect.model.serializer.JSONIdTokenView"/> -->
|
||||
|
||||
</beans:beans>
|
||||
|
|
Loading…
Reference in New Issue