Merge branch 'master' of github.com:jricher/OpenID-Connect-Java-Spring-Server
commit
01763dbc0c
|
@ -2,4 +2,13 @@
|
||||||
/target
|
/target
|
||||||
*~
|
*~
|
||||||
/bin
|
/bin
|
||||||
|
*.idea
|
||||||
|
*.gitignore
|
||||||
|
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
OpenIDConnect.iml
|
||||||
|
|
||||||
|
server/openid.iml
|
||||||
|
|
||||||
|
.gitignore
|
||||||
|
|
|
@ -1,75 +1,75 @@
|
||||||
package org.mitre.jwt.signer;
|
package org.mitre.jwt.signer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.mitre.jwt.model.Jwt;
|
import org.mitre.jwt.model.Jwt;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
public abstract class AbstractJwtSigner implements JwtSigner {
|
public abstract class AbstractJwtSigner implements JwtSigner {
|
||||||
|
|
||||||
private String algorithm;
|
private String algorithm;
|
||||||
|
|
||||||
public AbstractJwtSigner(String algorithm) {
|
public AbstractJwtSigner(String algorithm) {
|
||||||
this.algorithm = algorithm;
|
this.algorithm = algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the algorithm
|
* @return the algorithm
|
||||||
*/
|
*/
|
||||||
public String getAlgorithm() {
|
public String getAlgorithm() {
|
||||||
return algorithm;
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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;
|
this.algorithm = algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the 'alg' of the given JWT matches the {@link #algorithm} of this signer
|
* Ensures that the 'alg' of the given JWT matches the {@link #algorithm} of this signer
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void sign(Jwt jwt) {
|
public void sign(Jwt jwt) {
|
||||||
if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) {
|
if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) {
|
||||||
// algorithm type doesn't match
|
// algorithm type doesn't match
|
||||||
// TODO: should this be an error or should we just fix it in the incoming jwt?
|
// TODO: should this be an error or should we just fix it in the incoming jwt?
|
||||||
// for now, we fix the Jwt
|
// for now, we fix the Jwt
|
||||||
jwt.getHeader().setAlgorithm(algorithm);
|
jwt.getHeader().setAlgorithm(algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
String sig = generateSignature(jwt.getSignatureBase());
|
String sig = generateSignature(jwt.getSignatureBase());
|
||||||
|
|
||||||
jwt.setSignature(sig);
|
jwt.setSignature(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.mitre.jwt.JwtSigner#verify(java.lang.String)
|
* @see org.mitre.jwt.JwtSigner#verify(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean verify(String jwtString) {
|
public boolean verify(String jwtString) {
|
||||||
// split on the dots
|
// split on the dots
|
||||||
List<String> parts = Lists.newArrayList(Splitter.on(".").split(jwtString));
|
List<String> parts = Lists.newArrayList(Splitter.on(".").split(jwtString));
|
||||||
|
|
||||||
if (parts.size() != 3) {
|
if (parts.size() != 3) {
|
||||||
throw new IllegalArgumentException("Invalid JWT format.");
|
throw new IllegalArgumentException("Invalid JWT format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String h64 = parts.get(0);
|
String h64 = parts.get(0);
|
||||||
String c64 = parts.get(1);
|
String c64 = parts.get(1);
|
||||||
String s64 = parts.get(2);
|
String s64 = parts.get(2);
|
||||||
|
|
||||||
String expectedSignature = generateSignature(h64 + "." + c64 + ".");
|
String expectedSignature = generateSignature(h64 + "." + c64 + ".");
|
||||||
|
|
||||||
return Strings.nullToEmpty(s64).equals(Strings.nullToEmpty(expectedSignature));
|
return Strings.nullToEmpty(s64).equals(Strings.nullToEmpty(expectedSignature));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected abstract String generateSignature(String signatureBase);
|
protected abstract String generateSignature(String signatureBase);
|
||||||
}
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
package org.mitre.jwt.signer.impl;
|
package org.mitre.jwt.signer.impl;
|
||||||
|
|
||||||
import org.mitre.jwt.signer.AbstractJwtSigner;
|
import org.mitre.jwt.signer.AbstractJwtSigner;
|
||||||
|
|
||||||
public class PlaintextSigner extends AbstractJwtSigner {
|
public class PlaintextSigner extends AbstractJwtSigner {
|
||||||
|
|
||||||
public static final String PLAINTEXT = "none";
|
public static final String PLAINTEXT = "none";
|
||||||
|
|
||||||
public PlaintextSigner() {
|
public PlaintextSigner() {
|
||||||
super(PLAINTEXT);
|
super(PLAINTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String generateSignature(String signatureBase) {
|
protected String generateSignature(String signatureBase) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +1,56 @@
|
||||||
package org.mitre.openid.connect.view;
|
package org.mitre.openid.connect.view;
|
||||||
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
import org.springframework.web.servlet.view.AbstractView;
|
import org.springframework.web.servlet.view.AbstractView;
|
||||||
|
|
||||||
import com.google.gson.ExclusionStrategy;
|
import com.google.gson.ExclusionStrategy;
|
||||||
import com.google.gson.FieldAttributes;
|
import com.google.gson.FieldAttributes;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
public class JSONIdTokenView extends AbstractView {
|
public class JSONIdTokenView extends AbstractView {
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||||
*/
|
*/
|
||||||
protected void renderMergedOutputModel(Map<String, Object> model,
|
protected void renderMergedOutputModel(Map<String, Object> model,
|
||||||
HttpServletRequest request, HttpServletResponse response)
|
HttpServletRequest request, HttpServletResponse response)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.setExclusionStrategies(new ExclusionStrategy() {
|
.setExclusionStrategies(new ExclusionStrategy() {
|
||||||
|
|
||||||
public boolean shouldSkipField(FieldAttributes f) {
|
public boolean shouldSkipField(FieldAttributes f) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldSkipClass(Class<?> clazz) {
|
public boolean shouldSkipClass(Class<?> clazz) {
|
||||||
// skip the JPA binding wrapper
|
// skip the JPA binding wrapper
|
||||||
if (clazz.equals(BeanPropertyBindingResult.class)) {
|
if (clazz.equals(BeanPropertyBindingResult.class)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}).create();
|
}).create();
|
||||||
|
|
||||||
response.setContentType("application/json");
|
response.setContentType("application/json");
|
||||||
|
|
||||||
Writer out = response.getWriter();
|
Writer out = response.getWriter();
|
||||||
|
|
||||||
Object obj = model.get("entity");
|
Object obj = model.get("entity");
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
obj = model;
|
obj = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
gson.toJson(obj, out);
|
gson.toJson(obj, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +1,56 @@
|
||||||
package org.mitre.openid.connect.view;
|
package org.mitre.openid.connect.view;
|
||||||
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
import org.springframework.web.servlet.view.AbstractView;
|
import org.springframework.web.servlet.view.AbstractView;
|
||||||
|
|
||||||
import com.google.gson.ExclusionStrategy;
|
import com.google.gson.ExclusionStrategy;
|
||||||
import com.google.gson.FieldAttributes;
|
import com.google.gson.FieldAttributes;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
public class JSONUserInfoView extends AbstractView{
|
public class JSONUserInfoView extends AbstractView{
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||||
*/
|
*/
|
||||||
protected void renderMergedOutputModel(Map<String, Object> model,
|
protected void renderMergedOutputModel(Map<String, Object> model,
|
||||||
HttpServletRequest request, HttpServletResponse response)
|
HttpServletRequest request, HttpServletResponse response)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.setExclusionStrategies(new ExclusionStrategy() {
|
.setExclusionStrategies(new ExclusionStrategy() {
|
||||||
|
|
||||||
public boolean shouldSkipField(FieldAttributes f) {
|
public boolean shouldSkipField(FieldAttributes f) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldSkipClass(Class<?> clazz) {
|
public boolean shouldSkipClass(Class<?> clazz) {
|
||||||
// skip the JPA binding wrapper
|
// skip the JPA binding wrapper
|
||||||
if (clazz.equals(BeanPropertyBindingResult.class)) {
|
if (clazz.equals(BeanPropertyBindingResult.class)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}).create();
|
}).create();
|
||||||
|
|
||||||
response.setContentType("application/json");
|
response.setContentType("application/json");
|
||||||
|
|
||||||
Writer out = response.getWriter();
|
Writer out = response.getWriter();
|
||||||
|
|
||||||
Object obj = model.get("entity");
|
Object obj = model.get("entity");
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
obj = model;
|
obj = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
gson.toJson(obj, out);
|
gson.toJson(obj, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
<li><a href="#">Home</a> <span class="divider">/</span></li>
|
||||||
|
<li class="active">Manage Clients</li>
|
||||||
|
</ul>
|
|
@ -0,0 +1,2 @@
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,49 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>OpenID Connect</title>
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<!-- Le javascript -->
|
||||||
|
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-modal.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-alerts.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-twipsy.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-popover.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-dropdown.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-scrollspy.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-tabs.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-buttons.js"></script>
|
||||||
|
|
||||||
|
<script>$(function () {
|
||||||
|
|
||||||
|
})</script>
|
||||||
|
|
||||||
|
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<!-- Le styles -->
|
||||||
|
<link href="../bootstrap/bootstrap.css" rel="stylesheet">
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
padding-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
background: url("../images/openid_small.png") no-repeat left center;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Le fav and touch icons -->
|
||||||
|
<link rel="shortcut icon" href="images/favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<div class="sidebar">
|
||||||
|
<div class="well">
|
||||||
|
<h5>Administrative</h5>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">Manage Clients</a></li>
|
||||||
|
<li><a href="#">White Lists</a></li>
|
||||||
|
<li><a href="#">Black Lists</a></li>
|
||||||
|
</ul>
|
||||||
|
<h5>Personal</h5>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">Manage Sites</a></li>
|
||||||
|
<li><a href="#">Manage Active Tokens</a></li>
|
||||||
|
<li><a href="#">Profile</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="topbar">
|
||||||
|
<div class="topbar-inner">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="brand" href="#"><span class="logo">OpenID Connect Server</span></a>
|
||||||
|
<ul class="nav">
|
||||||
|
<li class="active"><a href="#">Home</a></li>
|
||||||
|
<li><a href="#about">About</a></li>
|
||||||
|
<li><a href="#about">Statistics</a></li>
|
||||||
|
<li><a href="#contact">Contact</a></li>
|
||||||
|
</ul>
|
||||||
|
<p class="pull-right">Logged in as <a href="#">username</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -6,6 +6,21 @@
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="author" content="">
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<!-- Le javascript -->
|
||||||
|
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-modal.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-alerts.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-twipsy.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-popover.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-dropdown.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-scrollspy.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-tabs.js"></script>
|
||||||
|
<script src="../bootstrap/js/bootstrap-buttons.js"></script>
|
||||||
|
|
||||||
|
<script>$(function () {
|
||||||
|
|
||||||
|
})</script>
|
||||||
|
|
||||||
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
|
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||||
|
@ -33,6 +48,126 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div id="modal-from-dom" class="modal hide fade" style="width: 577px; max-height: none; top: 35%">
|
||||||
|
<div class="modal-header">
|
||||||
|
<a href="#" class="close">×</a>
|
||||||
|
|
||||||
|
<h3>Edit Client</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<fieldset>
|
||||||
|
<legend>OpenID Client</legend>
|
||||||
|
<div class="clearfix">
|
||||||
|
<label for="xlInput">Client Name</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<input type="text" size="30" name="xlInput" id="xlInput" class="xlarge">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<label for="prependedInput">Redirect Url</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<div class="input-prepend">
|
||||||
|
<span class="add-on">http://</span>
|
||||||
|
<input type="text" size="16" name="prependedInput" id="prependedInput" class="medium">
|
||||||
|
</div>
|
||||||
|
<span class="help-block">Url to be redirected</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<label id="optionsCheckboxes">Grant Types:</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<ul class="inputs-list">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" value="option1" name="optionsCheckboxes">
|
||||||
|
<span>Grant Type Blah</span>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" value="option2" name="optionsCheckboxes">
|
||||||
|
<span>Grant Type Blah</span>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" value="option2" name="optionsCheckboxes">
|
||||||
|
<span>Grant Type Blah</span>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>Note:</strong> Grant type help text.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<label for="textarea2">Scope</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<textarea rows="3" name="textarea2" id="textarea2" class="xlarge">email,first name</textarea>
|
||||||
|
<span class="help-block">
|
||||||
|
Please enter scopes separated by commas
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<label for="normalSelect">Authority</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<select id="normalSelect" name="normalSelect">
|
||||||
|
<option>My Authority Option 1</option>
|
||||||
|
<option>My Authority Option 2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<label for="form-description">Description</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<input type="text" size="30" name="form-description" id="form-description" class="xlarge">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<label id="form-allow-tokens">Allow refresh tokens?</label>
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<ul class="inputs-list">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" value="option1" name="form-allow-tokens">
|
||||||
|
<span> </span>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>Note:</strong> Labels surround all the options for much larger click areas and a more usable form.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a href="#" class="btn primary">Save</a>
|
||||||
|
<a href="#" class="btn secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
<div class="topbar-inner">
|
<div class="topbar-inner">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
@ -66,7 +201,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<!-- Main hero unit for a primary marketing message or call to action -->
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<ul class="breadcrumb">
|
<ul class="breadcrumb">
|
||||||
<li><a href="#">Home</a> <span class="divider">/</span></li>
|
<li><a href="#">Home</a> <span class="divider">/</span></li>
|
||||||
|
@ -120,7 +254,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn">edit</button>
|
<button data-controls-modal="modal-from-dom" data-backdrop="true" data-keyboard="true"
|
||||||
|
class="btn">edit
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn danger">delete</button>
|
<button class="btn danger">delete</button>
|
||||||
|
@ -151,7 +287,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn">edit</button>
|
<button data-controls-modal="modal-from-dom" data-backdrop="true" data-keyboard="true"
|
||||||
|
class="btn">edit
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn danger">delete</button>
|
<button class="btn danger">delete</button>
|
||||||
|
@ -182,7 +320,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn">edit</button>
|
<button data-controls-modal="modal-from-dom" data-backdrop="true" data-keyboard="true"
|
||||||
|
class="btn">edit
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn danger">delete</button>
|
<button class="btn danger">delete</button>
|
||||||
|
@ -213,7 +353,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
<td><input type="checkbox" checked="checked" value="" id="" name="" disabled></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn">edit</button>
|
<button data-controls-modal="modal-from-dom" data-backdrop="true" data-keyboard="true"
|
||||||
|
class="btn">edit
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn danger">delete</button>
|
<button class="btn danger">delete</button>
|
||||||
|
|
|
@ -1,177 +1,177 @@
|
||||||
package org.mitre.jwt;
|
package org.mitre.jwt;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mitre.jwt.model.Jwt;
|
import org.mitre.jwt.model.Jwt;
|
||||||
import org.mitre.jwt.signer.JwtSigner;
|
import org.mitre.jwt.signer.JwtSigner;
|
||||||
import org.mitre.jwt.signer.impl.HmacSigner;
|
import org.mitre.jwt.signer.impl.HmacSigner;
|
||||||
import org.mitre.jwt.signer.impl.PlaintextSigner;
|
import org.mitre.jwt.signer.impl.PlaintextSigner;
|
||||||
import org.mitre.jwt.signer.impl.RsaSigner;
|
import org.mitre.jwt.signer.impl.RsaSigner;
|
||||||
import org.mitre.jwt.signer.service.impl.KeyStore;
|
import org.mitre.jwt.signer.service.impl.KeyStore;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(locations = {
|
@ContextConfiguration(locations = {
|
||||||
"file:src/main/webapp/WEB-INF/spring/application-context.xml",
|
"file:src/main/webapp/WEB-INF/spring/application-context.xml",
|
||||||
"classpath:test-context.xml" })
|
"classpath:test-context.xml" })
|
||||||
public class JwtTest {
|
public class JwtTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("testKeystore")
|
@Qualifier("testKeystore")
|
||||||
KeyStore keystore;
|
KeyStore keystore;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testToStringPlaintext() {
|
public void testToStringPlaintext() {
|
||||||
Jwt jwt = new Jwt();
|
Jwt jwt = new Jwt();
|
||||||
jwt.getHeader().setAlgorithm("none");
|
jwt.getHeader().setAlgorithm("none");
|
||||||
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
||||||
jwt.getClaims().setIssuer("joe");
|
jwt.getClaims().setIssuer("joe");
|
||||||
jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);
|
jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);
|
||||||
|
|
||||||
// sign it with a blank signature
|
// sign it with a blank signature
|
||||||
JwtSigner signer = new PlaintextSigner();
|
JwtSigner signer = new PlaintextSigner();
|
||||||
signer.sign(jwt);
|
signer.sign(jwt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expected string based on the following structures, serialized exactly as follows and base64 encoded:
|
* Expected string based on the following structures, serialized exactly as follows and base64 encoded:
|
||||||
*
|
*
|
||||||
* header: {"alg":"none"}
|
* header: {"alg":"none"}
|
||||||
* claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
|
* claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
|
||||||
*/
|
*/
|
||||||
String expected = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";
|
String expected = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";
|
||||||
|
|
||||||
String actual = jwt.toString();
|
String actual = jwt.toString();
|
||||||
|
|
||||||
assertThat(actual, equalTo(expected));
|
assertThat(actual, equalTo(expected));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenerateHmacSignature() {
|
public void testGenerateHmacSignature() {
|
||||||
Jwt jwt = new Jwt();
|
Jwt jwt = new Jwt();
|
||||||
jwt.getHeader().setType("JWT");
|
jwt.getHeader().setType("JWT");
|
||||||
jwt.getHeader().setAlgorithm("HS256");
|
jwt.getHeader().setAlgorithm("HS256");
|
||||||
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
||||||
jwt.getClaims().setIssuer("joe");
|
jwt.getClaims().setIssuer("joe");
|
||||||
jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);
|
jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);
|
||||||
|
|
||||||
// sign it
|
// sign it
|
||||||
byte[] key = null;
|
byte[] key = null;
|
||||||
try {
|
try {
|
||||||
key = "secret".getBytes("UTF-8");
|
key = "secret".getBytes("UTF-8");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
JwtSigner signer = new HmacSigner(key);
|
JwtSigner signer = new HmacSigner(key);
|
||||||
|
|
||||||
signer.sign(jwt);
|
signer.sign(jwt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expected string based on the following structures, serialized exactly as follows and base64 encoded:
|
* Expected string based on the following structures, serialized exactly as follows and base64 encoded:
|
||||||
*
|
*
|
||||||
* header: {"typ":"JWT","alg":"HS256"}
|
* header: {"typ":"JWT","alg":"HS256"}
|
||||||
* claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
|
* claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
|
||||||
*
|
*
|
||||||
* Expected signature: iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E
|
* Expected signature: iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
String signature = "p-63Jzz7mgi3H4hvW6MFB7lmPRZjhsL666MYkmpX33Y";
|
String signature = "p-63Jzz7mgi3H4hvW6MFB7lmPRZjhsL666MYkmpX33Y";
|
||||||
String expected = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ." + signature;
|
String expected = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ." + signature;
|
||||||
|
|
||||||
String actual = jwt.toString();
|
String actual = jwt.toString();
|
||||||
|
|
||||||
assertThat(actual, equalTo(expected));
|
assertThat(actual, equalTo(expected));
|
||||||
assertThat(jwt.getSignature(), equalTo(signature));
|
assertThat(jwt.getSignature(), equalTo(signature));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGenerateRsaSignature() throws Exception {
|
public void testGenerateRsaSignature() throws Exception {
|
||||||
|
|
||||||
// java.security.KeyStore ks = KeyStore.generateRsaKeyPair(keystore
|
// java.security.KeyStore ks = KeyStore.generateRsaKeyPair(keystore
|
||||||
// .getLocation().getFile().getPath(), "OpenID Connect Server",
|
// .getLocation().getFile().getPath(), "OpenID Connect Server",
|
||||||
// "twentyYears", KeyStore.PASSWORD, KeyStore.PASSWORD, 30, 365*20);
|
// "twentyYears", KeyStore.PASSWORD, KeyStore.PASSWORD, 30, 365*20);
|
||||||
//
|
//
|
||||||
// keystore.setKeystore(ks);
|
// keystore.setKeystore(ks);
|
||||||
|
|
||||||
Jwt jwt = new Jwt();
|
Jwt jwt = new Jwt();
|
||||||
jwt.getHeader().setType("JWT");
|
jwt.getHeader().setType("JWT");
|
||||||
jwt.getHeader().setAlgorithm("RS256");
|
jwt.getHeader().setAlgorithm("RS256");
|
||||||
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
|
||||||
jwt.getClaims().setIssuer("joe");
|
jwt.getClaims().setIssuer("joe");
|
||||||
jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);
|
jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);
|
||||||
|
|
||||||
JwtSigner signer = new RsaSigner(RsaSigner.Algorithm.DEFAULT, keystore, "twentyYears");
|
JwtSigner signer = new RsaSigner(RsaSigner.Algorithm.DEFAULT, keystore, "twentyYears");
|
||||||
((RsaSigner) signer).afterPropertiesSet();
|
((RsaSigner) signer).afterPropertiesSet();
|
||||||
|
|
||||||
signer.sign(jwt);
|
signer.sign(jwt);
|
||||||
|
|
||||||
String signature = "TW0nOd_vr1rnV7yIS-lIV2-00V_zJMWxzOc3Z7k3gvMO2aIjIGjZ9nByZMI0iL5komMxYXPl_RCkbd9OKiPkk4iK5CDj7Mawbzu95LgEOOqdXO1f7-IqX9dIvJhVXXInLD3RsGvavyheIqNeFEVidLrJo30tBchB_niljEW7VeX8nSZfiCOdbOTW3hu0ycnon7wFpejb-cRP_S0iqGxCgbYXJzqPT192EHmRy_wmFxxIy9Lc84uqNkAZSIn1jVIeAemm22RoWbq0xLVLTRyiZoxJTUzac_VteiSPRNFlUQuOdxqNf0Hxqh_wVfX1mfXUzv0D8vHJVy6aIqTISmn-qg";
|
String signature = "TW0nOd_vr1rnV7yIS-lIV2-00V_zJMWxzOc3Z7k3gvMO2aIjIGjZ9nByZMI0iL5komMxYXPl_RCkbd9OKiPkk4iK5CDj7Mawbzu95LgEOOqdXO1f7-IqX9dIvJhVXXInLD3RsGvavyheIqNeFEVidLrJo30tBchB_niljEW7VeX8nSZfiCOdbOTW3hu0ycnon7wFpejb-cRP_S0iqGxCgbYXJzqPT192EHmRy_wmFxxIy9Lc84uqNkAZSIn1jVIeAemm22RoWbq0xLVLTRyiZoxJTUzac_VteiSPRNFlUQuOdxqNf0Hxqh_wVfX1mfXUzv0D8vHJVy6aIqTISmn-qg";
|
||||||
String expected = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.TW0nOd_vr1rnV7yIS-lIV2-00V_zJMWxzOc3Z7k3gvMO2aIjIGjZ9nByZMI0iL5komMxYXPl_RCkbd9OKiPkk4iK5CDj7Mawbzu95LgEOOqdXO1f7-IqX9dIvJhVXXInLD3RsGvavyheIqNeFEVidLrJo30tBchB_niljEW7VeX8nSZfiCOdbOTW3hu0ycnon7wFpejb-cRP_S0iqGxCgbYXJzqPT192EHmRy_wmFxxIy9Lc84uqNkAZSIn1jVIeAemm22RoWbq0xLVLTRyiZoxJTUzac_VteiSPRNFlUQuOdxqNf0Hxqh_wVfX1mfXUzv0D8vHJVy6aIqTISmn-qg";
|
String expected = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.TW0nOd_vr1rnV7yIS-lIV2-00V_zJMWxzOc3Z7k3gvMO2aIjIGjZ9nByZMI0iL5komMxYXPl_RCkbd9OKiPkk4iK5CDj7Mawbzu95LgEOOqdXO1f7-IqX9dIvJhVXXInLD3RsGvavyheIqNeFEVidLrJo30tBchB_niljEW7VeX8nSZfiCOdbOTW3hu0ycnon7wFpejb-cRP_S0iqGxCgbYXJzqPT192EHmRy_wmFxxIy9Lc84uqNkAZSIn1jVIeAemm22RoWbq0xLVLTRyiZoxJTUzac_VteiSPRNFlUQuOdxqNf0Hxqh_wVfX1mfXUzv0D8vHJVy6aIqTISmn-qg";
|
||||||
|
|
||||||
String actual = jwt.toString();
|
String actual = jwt.toString();
|
||||||
|
|
||||||
assertThat(actual, equalTo(expected));
|
assertThat(actual, equalTo(expected));
|
||||||
assertThat(jwt.getSignature(), equalTo(signature));
|
assertThat(jwt.getSignature(), equalTo(signature));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateHmacSignature() {
|
public void testValidateHmacSignature() {
|
||||||
// sign it
|
// sign it
|
||||||
byte[] key = null;
|
byte[] key = null;
|
||||||
try {
|
try {
|
||||||
key = "secret".getBytes("UTF-8");
|
key = "secret".getBytes("UTF-8");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
JwtSigner signer = new HmacSigner(key);
|
JwtSigner signer = new HmacSigner(key);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Token string based on the following strucutres, serialized exactly as follows and base64 encoded:
|
* Token string based on the following strucutres, serialized exactly as follows and base64 encoded:
|
||||||
*
|
*
|
||||||
* header: {"typ":"JWT","alg":"HS256"}
|
* header: {"typ":"JWT","alg":"HS256"}
|
||||||
* claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
|
* claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
|
||||||
*
|
*
|
||||||
* Expected signature: iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E
|
* Expected signature: iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
String jwtString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E";
|
String jwtString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E";
|
||||||
|
|
||||||
boolean valid = signer.verify(jwtString);
|
boolean valid = signer.verify(jwtString);
|
||||||
|
|
||||||
assertThat(valid, equalTo(Boolean.TRUE));
|
assertThat(valid, equalTo(Boolean.TRUE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParse() {
|
public void testParse() {
|
||||||
String source = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";
|
String source = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";
|
||||||
|
|
||||||
|
|
||||||
Jwt jwt = Jwt.parse(source);
|
Jwt jwt = Jwt.parse(source);
|
||||||
|
|
||||||
assertThat(jwt.getHeader().getAlgorithm(), equalTo(PlaintextSigner.PLAINTEXT));
|
assertThat(jwt.getHeader().getAlgorithm(), equalTo(PlaintextSigner.PLAINTEXT));
|
||||||
assertThat(jwt.getClaims().getIssuer(), equalTo("joe"));
|
assertThat(jwt.getClaims().getIssuer(), equalTo("joe"));
|
||||||
assertThat(jwt.getClaims().getExpiration(), equalTo(new Date(1300819380L * 1000L)));
|
assertThat(jwt.getClaims().getExpiration(), equalTo(new Date(1300819380L * 1000L)));
|
||||||
assertThat((Boolean)jwt.getClaims().getClaim("http://example.com/is_root"), equalTo(Boolean.TRUE));
|
assertThat((Boolean)jwt.getClaims().getClaim("http://example.com/is_root"), equalTo(Boolean.TRUE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue