下面列出了怎么用io.jsonwebtoken.JwsHeader的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* create by: iizvv
* description: 获取Token
* create time: 2019-06-29 15:14
*
* @return 请求头
*/
static Map getToken(String p8, String iss, String kid) {
String s = p8.
replace("-----BEGIN PRIVATE KEY-----", "").
replace("-----END PRIVATE KEY-----", "");
byte[] encodeKey = Base64.decode(s);
String token = null;
try {
token = Jwts.builder().
setHeaderParam(JwsHeader.ALGORITHM, "ES256").
setHeaderParam(JwsHeader.KEY_ID,kid).
setHeaderParam(JwsHeader.TYPE, "JWT").
setIssuer(iss).
claim("exp", System.currentTimeMillis()/1000 + 60 * 10).
setAudience("appstoreconnect-v1").
signWith(SignatureAlgorithm.ES256, new ECPrivateKeyImpl(encodeKey)).
compact();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
Map map = new HashMap();
map.put("Content-Type", "application/json");
map.put("Authorization", "Bearer " + token);
return map;
}
private Jws<Claims> parseTokenFromBase64EncodedString(final String base64EncodedToken) throws JwtException {
try {
return Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
final String identity = claims.getSubject();
// Get the key based on the key id in the claims
final Integer keyId = claims.get(KEY_ID_CLAIM, Integer.class);
final Key key = keyService.getKey(keyId);
// Ensure we were able to find a key that was previously issued by this key service for this user
if (key == null || key.getKey() == null) {
throw new UnsupportedJwtException("Unable to determine signing key for " + identity + " [kid: " + keyId + "]");
}
return key.getKey().getBytes(StandardCharsets.UTF_8);
}
}).parseClaimsJws(base64EncodedToken);
} catch (final MalformedJwtException | UnsupportedJwtException | SignatureException | ExpiredJwtException | IllegalArgumentException | AdministrationException e) {
// TODO: Exercise all exceptions to ensure none leak key material to logs
final String errorMessage = "Unable to validate the access token.";
throw new JwtException(errorMessage, e);
}
}
private Key resolveSigningKey(final JwsHeader header) {
final LineApiResponse<JWKSet> response = apiClient.getJWKSet();
if (!response.isSuccess()) {
Log.e(TAG, "failed to get LINE JSON Web Key Set [JWK] document.");
return null;
}
final JWKSet jwkSet = response.getResponseData();
final String keyId = header.getKeyId();
final JWK jwk = jwkSet.getJWK(keyId);
if (jwk == null) {
Log.e(TAG, "failed to find Key by Id: " + keyId);
return null;
}
final String algorithm = header.getAlgorithm();
final SignatureAlgorithm alg = SignatureAlgorithm.forName(algorithm);
if (alg.isEllipticCurve()) {
return generateECPublicKey(jwk);
}
throw new SecurityException("Unsupported signature algorithm '" + algorithm + '\'');
}
private Jws<Claims> parseTokenFromBase64EncodedString(final String base64EncodedToken) throws JwtException {
try {
return Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
final String identity = claims.getSubject();
// Get the key based on the key id in the claims
final String keyId = claims.get(KEY_ID_CLAIM, String.class);
final Key key = keyService.getKey(keyId);
// Ensure we were able to find a key that was previously issued by this key service for this user
if (key == null || key.getKey() == null) {
throw new UnsupportedJwtException("Unable to determine signing key for " + identity + " [kid: " + keyId + "]");
}
return key.getKey().getBytes(StandardCharsets.UTF_8);
}
}).parseClaimsJws(base64EncodedToken);
} catch (final MalformedJwtException | UnsupportedJwtException | SignatureException | ExpiredJwtException | IllegalArgumentException e) {
// TODO: Exercise all exceptions to ensure none leak key material to logs
final String errorMessage = "Unable to validate the access token.";
throw new JwtException(errorMessage, e);
}
}
@Override
public Claims parse(final String credentials) {
// Parse the JWT claims
return Jwts.parserBuilder().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public Key resolveSigningKey(final JwsHeader header, final Claims claims) {
if (header.getKeyId() == null) {
throw new JwtException("Missing Key ID (kid) header field");
}
try {
if (keyIds.contains(header.getKeyId()) && keyStore.containsAlias(header.getKeyId())) {
return keyStore.getCertificate(header.getKeyId()).getPublicKey();
}
} catch (final KeyStoreException ex) {
throw new SecurityException("Error retrieving key from keystore", ex);
}
throw new SecurityException("Could not locate key in keystore: " + header.getKeyId());
}
}).build().parseClaimsJws(credentials).getBody();
}
@Override
public Claims parse(final String token) {
return Jwts.parserBuilder().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public Key resolveSigningKey(final JwsHeader header, final Claims claims) {
final String keyid = header.getKeyId();
if (keyid == null) {
throw new JwtException("Missing Key ID (kid) header field");
}
if (keys.containsKey(keyid)) {
return keys.get(keyid);
}
throw new SecurityException("Could not locate key: " + keyid);
}
}).build().parseClaimsJws(token).getBody();
}
@Test
void testAuthenticateKeystore() throws Exception {
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase);
final Key privateKey = ks.getKey("trellis", passphrase);
final String jwt = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis")
.setSubject("https://people.apache.org/~acoburn/#me")
.signWith(privateKey, SignatureAlgorithm.RS256).compact();
final Authenticator authenticator = new FederatedJwtAuthenticator(ks,
asList("trellis", "foo"));
final Principal p = authenticator.authenticate(jwt);
assertNotNull(p, "Missing principal!");
assertEquals("https://people.apache.org/~acoburn/#me", p.getName(), "Incorrect webid!");
}
@Test
void testAuthenticateKeystoreRSA() throws Exception {
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase);
final Key privateKey = ks.getKey("trellis", passphrase);
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis-public")
.setSubject("https://people.apache.org/~acoburn/#i")
.signWith(privateKey, SignatureAlgorithm.RS256).compact();
final Authenticator authenticator = new FederatedJwtAuthenticator(ks,
singletonList("trellis-public"));
final Principal p = authenticator.authenticate(token);
assertNotNull(p, "Missing principal!");
assertEquals("https://people.apache.org/~acoburn/#i", p.getName(), "Incorrect webid!");
}
@Test
void testAuthenticateSubIss() throws Exception {
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase);
final Key privateKey = ks.getKey("trellis-ec", passphrase);
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis-ec")
.setSubject("acoburn").setIssuer("http://localhost")
.signWith(privateKey, SignatureAlgorithm.ES256).compact();
final Authenticator authenticator = new FederatedJwtAuthenticator(ks,
singletonList("trellis-ec"));
final Principal p = authenticator.authenticate(token);
assertNotNull(p, "Missing principal!");
assertEquals("http://localhost/acoburn", p.getName(), "Incorrect webid!");
}
@Override
public CertificateProvider create(io.gravitee.am.certificate.api.CertificateProvider provider) {
// create certificate provider
CertificateProvider certificateProvider = new CertificateProvider(provider);
// create parser and builder (default to jjwt)
io.jsonwebtoken.JwtParser jjwtParser;
io.jsonwebtoken. JwtBuilder jjwtBuilder;
try {
io.gravitee.am.certificate.api.Key providerKey = provider.key().blockingGet();
Key signingKey = providerKey.getValue() instanceof KeyPair ? ((KeyPair) providerKey.getValue()).getPrivate() : (Key) providerKey.getValue();
Key verifyingKey = providerKey.getValue() instanceof KeyPair ? ((KeyPair) providerKey.getValue()).getPublic() : (Key) providerKey.getValue();
jjwtParser = Jwts.parserBuilder().deserializeJsonWith(new JacksonDeserializer<>(objectMapper)).setSigningKey(verifyingKey).build();
jjwtBuilder = Jwts.builder().serializeToJsonWith(new JacksonSerializer<>(objectMapper)).signWith(signingKey).setHeaderParam(JwsHeader.KEY_ID, providerKey.getKeyId());
} catch (UnsupportedOperationException ex) {
jjwtParser = Jwts.parserBuilder().deserializeJsonWith(new JacksonDeserializer<>(objectMapper)).build();
jjwtBuilder = Jwts.builder().serializeToJsonWith(new JacksonSerializer<>(objectMapper));
}
certificateProvider.setJwtParser(new JJWTParser(jjwtParser));
certificateProvider.setJwtBuilder(new JJWTBuilder(jjwtBuilder));
return certificateProvider;
}
@SuppressWarnings("serial")
protected String getRegistrationRequest(final KeyPair userKey, final String nonce, final String agreement, final String[] contacts) {
return Jwts.builder()
.setHeaderParam(NONCE_KEY, nonce)
.setHeaderParam(JwsHeader.JSON_WEB_KEY, JWKUtils.getWebKey(userKey.getPublic()))
.setClaims(new TreeMap<String, Object>(){{
put(RESOURCE_KEY, RESOURCE_NEW_REG);
if (contacts != null && contacts.length > 0){
put(CONTACT_KEY, contacts);
}
if (agreement != null){
put(AGREEMENT_KEY, agreement);
}
}})
.signWith(getJWSSignatureAlgorithm(), userKey.getPrivate())
.compact();
}
@Override
public Key resolveSigningKey(JwsHeader header, Claims claims) {
if (!MACHINE_TOKEN_KIND.equals(header.get("kind"))) {
throw new NotMachineTokenJwtException();
}
String wsId = claims.get(WORKSPACE_ID_CLAIM, String.class);
if (wsId == null) {
throw new JwtException(
"Unable to fetch signature key pair: no workspace id present in token");
}
try {
return keyManager.getOrCreateKeyPair(wsId).getPublic();
} catch (SignatureKeyManagerException e) {
throw new JwtException("Unable to fetch signature key pair:" + e.getMessage(), e);
}
}
private Jws<Claims> parseTokenFromBase64EncodedString(final String base64EncodedToken) throws JwtException {
try {
return Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
final String identity = claims.getSubject();
// Get the key based on the key id in the claims
final Integer keyId = claims.get(KEY_ID_CLAIM, Integer.class);
final Key key = keyService.getKey(keyId);
// Ensure we were able to find a key that was previously issued by this key service for this user
if (key == null || key.getKey() == null) {
throw new UnsupportedJwtException("Unable to determine signing key for " + identity + " [kid: " + keyId + "]");
}
return key.getKey().getBytes(StandardCharsets.UTF_8);
}
}).parseClaimsJws(base64EncodedToken);
} catch (final MalformedJwtException | UnsupportedJwtException | SignatureException | ExpiredJwtException | IllegalArgumentException | AdministrationException e) {
// TODO: Exercise all exceptions to ensure none leak key material to logs
final String errorMessage = "Unable to validate the access token.";
throw new JwtException(errorMessage, e);
}
}
@Override
public Key apply(JwsHeader<?> header)
{
String keyId = getKeyId(header);
SignatureAlgorithm algorithm = SignatureAlgorithm.forName(header.getAlgorithm());
return keys.computeIfAbsent(keyId, this::loadKey).getKey(algorithm);
}
private static String getKeyId(JwsHeader<?> header)
{
String keyId = header.getKeyId();
if (keyId == null) {
// allow for migration from system not using kid
return DEFAULT_KEY;
}
keyId = INVALID_KID_CHARS.replaceFrom(keyId, '_');
return keyId;
}
/**
* Make sure Jwt created is formatted according to the Google Cloud IoT Core<a
* href="https://cloud.google.com/iot/docs/how-tos/credentials/jwts#jwt_composition">spec</a>.
*/
@Test
public void testCreateJwtRsa() throws JoseException {
JwtGenerator jwtGenerator =
new JwtGenerator(RSA_KEY_PAIR, JWT_AUDIENCE, TOKEN_LIFETIME, TEST_CLOCK);
String rawJwt = jwtGenerator.createJwt();
// Validate JWT
Jws<Claims> parsedJwt = Jwts.parser()
.setSigningKey(RSA_KEY_PAIR.getPublic())
.parseClaimsJws(rawJwt);
JwsHeader header = parsedJwt.getHeader();
Claims claims = parsedJwt.getBody();
assertThat(header.getAlgorithm()).isEqualTo("RS256");
assertThat(header.getType()).isEqualTo("JWT");
assertThat(claims.getAudience()).isEqualTo(JWT_AUDIENCE);
// JWT requires time in seconds from epoch, not millis, so allow issue time within one
// second.
assertThat(claims.getIssuedAt().getTime()).isAtLeast(TEST_CLOCK.millis() - 1000);
assertThat(claims.getIssuedAt().getTime()).isAtMost(TEST_CLOCK.millis() + 1000);
// Check expiration time within one second of issue time + TOKEN_LIFETIME
assertThat(claims.getExpiration().getTime())
.isLessThan(Clock.offset(TEST_CLOCK, TOKEN_LIFETIME.plusSeconds(1)).millis());
assertThat(claims.getExpiration().getTime())
.isAtLeast(Clock.offset(TEST_CLOCK, TOKEN_LIFETIME.minusSeconds(1)).millis());
}
/**
* Make sure Jwt created is formatted according to the Google Cloud IoT Core<a
* href="https://cloud.google.com/iot/docs/how-tos/credentials/jwts#jwt_composition">spec</a>.
*/
@Test
public void testCreateJwtEc() throws JoseException {
JwtGenerator jwtGenerator =
new JwtGenerator(EC_KEY_PAIR, JWT_AUDIENCE, TOKEN_LIFETIME, TEST_CLOCK);
String rawJwt = jwtGenerator.createJwt();
// Validate JWT
Jws<Claims> parsedJwt;
try {
parsedJwt = Jwts.parser()
.setSigningKey(EC_KEY_PAIR.getPublic())
.parseClaimsJws(rawJwt);
} catch (UnsupportedJwtException | MalformedJwtException | SignatureException e) {
fail("Error parsing JWT: " + e);
return; // Satisfy compiler
}
JwsHeader header = parsedJwt.getHeader();
Claims claims = parsedJwt.getBody();
assertThat(header.getAlgorithm()).isEqualTo("ES256");
assertThat(header.getType()).isEqualTo("JWT");
assertThat(claims.getAudience()).isEqualTo(JWT_AUDIENCE);
// JWT requires time in seconds from epoch, not millis, so allow issue time within one
// second.
assertThat(claims.getIssuedAt().getTime()).isAtLeast(TEST_CLOCK.millis() - 1000);
assertThat(claims.getIssuedAt().getTime()).isAtMost(TEST_CLOCK.millis() + 1000);
// Check expiration time within one second of issue time + TOKEN_LIFETIME
assertThat(claims.getExpiration().getTime())
.isLessThan(Clock.offset(TEST_CLOCK, TOKEN_LIFETIME.plusSeconds(1)).millis());
assertThat(claims.getExpiration().getTime())
.isAtLeast(Clock.offset(TEST_CLOCK, TOKEN_LIFETIME.minusSeconds(1)).millis());
}
@Override
public Key resolveSigningKey(JwsHeader header, Claims claims) {
Key result = delegate.resolveSigningKey(header, claims);
if (result == null) {
result = this.fallbackKey;
}
return result;
}
@Test
void testAuthenticateNoSub() throws Exception {
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase);
final Key privateKey = ks.getKey("trellis-ec", passphrase);
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis-ec")
.setIssuer("http://localhost").signWith(privateKey, SignatureAlgorithm.ES256).compact();
final Authenticator authenticator = new FederatedJwtAuthenticator(ks,
singletonList("trellis-ec"));
assertNull(authenticator.authenticate(token), "Unexpected principal!");
}
@Test
void testAuthenticateSubNoWebIss() throws Exception {
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase);
final Key privateKey = ks.getKey("trellis-ec", passphrase);
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis-ec")
.setSubject("acoburn").setIssuer("some org")
.signWith(privateKey, SignatureAlgorithm.ES256).compact();
final Authenticator authenticator = new FederatedJwtAuthenticator(ks,
singletonList("trellis-ec"));
assertNull(authenticator.authenticate(token), "Unexpected principal!");
}
@Test
void testFilterGenericJwks() throws Exception {
final BigInteger exponent = new BigInteger(1, getUrlDecoder().decode("VRPRBm9dCoAJfBbEz5oAHEz7Tnm0i0O6m5yj7N" +
"wqAZOj9i4ZwgZ8VZQo88oxZQWNaYd1yKeoQhUsJija_vxQEPXO1Q2q6OqMcwTBH0wyGhIFp--z2dAyRlDVLUTQbJUXyqammdh7b16-i" +
"gH-BB67jfolM-cw-O7YaN7GrxCCYX5bI38IipeYfcroeIUXdLYmmUdNy7c8P2_K4O-iHQ6A4AUtQRUOzt2FGOdmlGZihupI9YprshIy" +
"9CZq_iA3BcOl4Gcc-ljwwUzT0M_4jt53DCV7oxqWVt9WRdYDNoD62g2FzQ-1nYUqsz4YChk1MuOPV1xFpRklwSpt5dfhuldnbQ"));
final BigInteger modulus = new BigInteger(1, getUrlDecoder().decode("oMyjaeUbmnqojRpMBDbWbfBFitd_dQcFJ96CDWw" +
"zsVcyAK3_kp4dEvhc2KLBjrmE69gJ-4HRuPF-kulDEmpC-MVx9eOihdUG9XV0ZA_eYWj9RoI_Gt3TUqTxlQH_nJRADTfy82fOCCboKp" +
"aQ2idZH55Vb0FDbau2b2462tYRmcnxTFjClP4fDTTubI-3oFJ4tKMjynvUT34mCrZPiM8Q4noxVoyRYpzUTL1USxdUf56IKSB8NduH4" +
"38zhMXE5VLC6PzhR3i_4KKpe4nq2otsrJ3KlEc7Me6UeiMXxPYz8rrPovW5L3LFWDmntGs5q923fBZFLFg8yBgMdTineaahEQ"));
try {
System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_JWK_URL, "https://www.trellisldp.org/tests/jwks.json");
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis-test")
.setSubject(WEBID2).signWith(key).compact();
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token);
final OAuthFilter filter = new OAuthFilter();
filter.filter(mockContext);
verify(mockContext).setSecurityContext(securityArgument.capture());
assertEquals(WEBID2, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!");
} finally {
System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_JWK_URL);
}
}
@Test
void testFilterGenericFederated() throws Exception {
final String passphrase = "password";
try {
final String keystorePath = OAuthUtilsTest.class.getResource("/keystore.jks").getPath();
System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_PATH, keystorePath);
System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_CREDENTIALS, passphrase);
System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_IDS, "trellis,trellis-ec");
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase.toCharArray());
final Key privateKey = ks.getKey("trellis", passphrase.toCharArray());
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis")
.setSubject(WEBID2).signWith(privateKey, SignatureAlgorithm.RS256).compact();
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token);
final OAuthFilter filter = new OAuthFilter();
filter.filter(mockContext);
verify(mockContext).setSecurityContext(securityArgument.capture());
assertEquals(WEBID2, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!");
} finally {
System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_PATH);
System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_CREDENTIALS);
System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_IDS);
}
}
@Test
void testAuthenticateJwks() throws Exception {
final String webid = "https://people.apache.org/~acoburn/#i";
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, keyid)
.setSubject(webid).signWith(key).compact();
final Authenticator authenticator = new JwksAuthenticator(url);
final Principal p = authenticator.authenticate(token);
assertNotNull(p, "Missing principal!");
assertEquals("https://people.apache.org/~acoburn/#i", p.getName(), "Incorrect webid!");
}
@Test
void testAuthenticateJwksAsWebid() throws Exception {
final String webid = "https://people.apache.org/~acoburn/#i";
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, keyid)
.claim("webid", webid).signWith(key).compact();
final Authenticator authenticator = new JwksAuthenticator(url);
final Principal p = authenticator.authenticate(token);
assertNotNull(p, "Missing principal!");
assertEquals("https://people.apache.org/~acoburn/#i", p.getName(), "Incorrect webid!");
}
@Test
void testAuthenticateJwksExpired() throws Exception {
final String webid = "https://people.apache.org/~acoburn/#i";
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, keyid).claim("webid", webid)
.setExpiration(from(now().minusSeconds(10))).signWith(key).compact();
final Authenticator authenticator = new JwksAuthenticator(url);
assertThrows(ExpiredJwtException.class, () -> authenticator.authenticate(token), "Unexpected principal!");
}
@Test
void testAuthenticateJwksWrongKeyid() throws Exception {
final String webid = "https://people.apache.org/~acoburn/#i";
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "non-existent")
.setSubject(webid).signWith(key).compact();
final Authenticator authenticator = new JwksAuthenticator(url);
assertThrows(SecurityException.class, () -> authenticator.authenticate(token), "Unexpected principal!");
}
@Test
void testAuthenticateJwksInvalidKeyLocation() throws Exception {
final String webid = "https://people.apache.org/~acoburn/#i";
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, keyid).setSubject(webid)
.signWith(key).compact();
final Authenticator authenticator = new JwksAuthenticator("https://www.trellisldp.org/tests/non-existent");
assertThrows(SecurityException.class, () -> authenticator.authenticate(token), "Unexpected principal!");
}
/**
* Gets the value of the <em>exp</em> claim of a JWT.
*
* @param token The token.
* @return The expiration.
* @throws NullPointerException if the token is {@code null}.
* @throws IllegalArgumentException if the given token contains no <em>exp</em> claim.
*/
public static final Date getExpiration(final String token) {
if (token == null) {
throw new NullPointerException("token must not be null");
}
final AtomicReference<Date> result = new AtomicReference<>();
try {
Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public Key resolveSigningKey(final JwsHeader header, final Claims claims) {
final Date exp = claims.getExpiration();
if (exp != null) {
result.set(exp);
}
return DUMMY_KEY;
}
}).parse(token);
} catch (final JwtException e) {
// expected since we do not know the signing key
}
if (result.get() == null) {
throw new IllegalArgumentException("token contains no exp claim");
} else {
return result.get();
}
}
@Test
public void testResolveSigningKey() {
final String oldConf = System.setProperty(JwtsSigningKeyResolver.ZTS_PROP_ATHENZ_CONF,
"src/test/resources/athenz.conf");
JwtsSigningKeyResolver resolver = new JwtsSigningKeyResolver(null, null);
JwsHeader header = Mockito.mock(JwsHeader.class);
Mockito.when(header.getKeyId())
.thenReturn("eckey1")
.thenReturn("unknown");
// first we get eckey1 which exists
java.security.Key key = resolver.resolveSigningKey(header, "body");
assertNotNull(key);
// next we get unknown
key = resolver.resolveSigningKey(header, "body");
assertNull(key);
if (oldConf == null) {
System.clearProperty(JwtsSigningKeyResolver.ZTS_PROP_ATHENZ_CONF);
} else {
System.setProperty(JwtsSigningKeyResolver.ZTS_PROP_ATHENZ_CONF, oldConf);
}
}
@Test
@SuppressWarnings("rawtypes")
public void testParse() throws Exception {
// mock internal parser
DefaultOAuthJwtAccessTokenParser parser = new DefaultOAuthJwtAccessTokenParser(baseKeyStore, this.classLoader.getResource("jwt_jwks.json").toString());
JwtParser jwtParserMock = Mockito.mock(JwtParser.class);
Field f = parser.getClass().getDeclaredField("parser");
f.setAccessible(true);
f.set(parser, jwtParserMock);
// parse error
Mockito.when(jwtParserMock.parseClaimsJws(null)).thenThrow(new NullPointerException());
assertThrows(OAuthJwtAccessTokenException.class, () -> parser.parse(null));
// parse success
String jwtString = "dummy-jwt-string";
Jws<Claims> jws = new Jws<Claims>() {
public JwsHeader getHeader() { return null; }
public Claims getBody() { return null; }
@Override
public String getSignature() {
return "dummy-jwt-signature";
}
};
Mockito.when(jwtParserMock.parseClaimsJws(jwtString)).thenReturn(jws);
OAuthJwtAccessToken token = parser.parse(jwtString);
assertNotNull(token);
assertTrue(token instanceof DefaultOAuthJwtAccessToken);
assertEquals(token.getSignature(), "dummy-jwt-signature");
}