Commit 77e5c585 authored by Madhura Bhave's avatar Madhura Bhave

Validate kid in Cloud Foundry token header

Instead of validating the signature against all the public keys,
we can validate it only against the public key with the kid that
matches the one in the token header.

Closes gh-8126
parent 601c6aa3
...@@ -63,6 +63,8 @@ class CloudFoundryAuthorizationException extends RuntimeException { ...@@ -63,6 +63,8 @@ class CloudFoundryAuthorizationException extends RuntimeException {
INVALID_ISSUER(HttpStatus.UNAUTHORIZED), INVALID_ISSUER(HttpStatus.UNAUTHORIZED),
INVALID_KEY_ID(HttpStatus.UNAUTHORIZED),
INVALID_SIGNATURE(HttpStatus.UNAUTHORIZED), INVALID_SIGNATURE(HttpStatus.UNAUTHORIZED),
INVALID_TOKEN(HttpStatus.UNAUTHORIZED), INVALID_TOKEN(HttpStatus.UNAUTHORIZED),
......
...@@ -18,7 +18,7 @@ package org.springframework.boot.actuate.cloudfoundry; ...@@ -18,7 +18,7 @@ package org.springframework.boot.actuate.cloudfoundry;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -104,7 +104,7 @@ class CloudFoundrySecurityService { ...@@ -104,7 +104,7 @@ class CloudFoundrySecurityService {
* Return all token keys known by the UAA. * Return all token keys known by the UAA.
* @return a list of token keys * @return a list of token keys
*/ */
public List<String> fetchTokenKeys() { public Map<String, String> fetchTokenKeys() {
try { try {
return extractTokenKeys(this.restTemplate return extractTokenKeys(this.restTemplate
.getForObject(getUaaUrl() + "/token_keys", Map.class)); .getForObject(getUaaUrl() + "/token_keys", Map.class));
...@@ -115,11 +115,12 @@ class CloudFoundrySecurityService { ...@@ -115,11 +115,12 @@ class CloudFoundrySecurityService {
} }
} }
private List<String> extractTokenKeys(Map<?, ?> response) { private Map<String, String> extractTokenKeys(Map<?, ?> response) {
List<String> tokenKeys = new ArrayList<String>(); Map<String, String> tokenKeys = new HashMap<String, String>();
List<?> keys = (List<?>) response.get("keys"); List<?> keys = (List<?>) response.get("keys");
for (Object key : keys) { for (Object key : keys) {
tokenKeys.add((String) ((Map<?, ?>) key).get("value")); Map<?, ?> tokenKey = (Map<?, ?>) key;
tokenKeys.put((String) (tokenKey).get("kid"), (String) (tokenKey).get("value"));
} }
return tokenKeys; return tokenKeys;
} }
......
...@@ -97,6 +97,11 @@ class Token { ...@@ -97,6 +97,11 @@ class Token {
return getRequired(this.claims, "scope", List.class); return getRequired(this.claims, "scope", List.class);
} }
@SuppressWarnings("unchecked")
public String getKeyId() {
return getRequired(this.header, "kid", String.class);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T> T getRequired(Map<String, Object> map, String key, Class<T> type) { private <T> T getRequired(Map<String, Object> map, String key, Class<T> type) {
Object value = map.get(key); Object value = map.get(key);
......
...@@ -23,7 +23,7 @@ import java.security.PublicKey; ...@@ -23,7 +23,7 @@ import java.security.PublicKey;
import java.security.Signature; import java.security.Signature;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.util.List; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.springframework.boot.actuate.cloudfoundry.CloudFoundryAuthorizationException.Reason; import org.springframework.boot.actuate.cloudfoundry.CloudFoundryAuthorizationException.Reason;
...@@ -38,7 +38,7 @@ class TokenValidator { ...@@ -38,7 +38,7 @@ class TokenValidator {
private final CloudFoundrySecurityService securityService; private final CloudFoundrySecurityService securityService;
private List<String> tokenKeys; private Map<String, String> tokenKeys;
TokenValidator(CloudFoundrySecurityService cloudFoundrySecurityService) { TokenValidator(CloudFoundrySecurityService cloudFoundrySecurityService) {
this.securityService = cloudFoundrySecurityService; this.securityService = cloudFoundrySecurityService;
...@@ -46,12 +46,14 @@ class TokenValidator { ...@@ -46,12 +46,14 @@ class TokenValidator {
public void validate(Token token) { public void validate(Token token) {
validateAlgorithm(token); validateAlgorithm(token);
validateSignature(token); validateKeyIdAndSignature(token);
validateExpiry(token); validateExpiry(token);
validateIssuer(token); validateIssuer(token);
validateAudience(token); validateAudience(token);
} }
private void validateAlgorithm(Token token) { private void validateAlgorithm(Token token) {
String algorithm = token.getSignatureAlgorithm(); String algorithm = token.getSignatureAlgorithm();
if (algorithm == null) { if (algorithm == null) {
...@@ -65,19 +67,25 @@ class TokenValidator { ...@@ -65,19 +67,25 @@ class TokenValidator {
} }
} }
private void validateSignature(Token token) { private void validateKeyIdAndSignature(Token token) {
if (this.tokenKeys == null || !hasValidSignature(token)) { String keyId = token.getKeyId();
if (this.tokenKeys == null || !hasValidKeyId(keyId)) {
this.tokenKeys = this.securityService.fetchTokenKeys(); this.tokenKeys = this.securityService.fetchTokenKeys();
if (!hasValidSignature(token)) { if (!hasValidKeyId(keyId)) {
throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, throw new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID,
"RSA Signature did not match content"); "Key Id present in token header does not match");
} }
} }
if (!hasValidSignature(token, this.tokenKeys.get(keyId))) {
throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE,
"RSA Signature did not match content");
}
} }
private boolean hasValidSignature(Token token) { private boolean hasValidKeyId(String tokenKeyId) {
for (String key : this.tokenKeys) { for (String keyId: this.tokenKeys.keySet()) {
if (hasValidSignature(token, key)) { if (tokenKeyId.equals(keyId)) {
return true; return true;
} }
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package org.springframework.boot.actuate.cloudfoundry; package org.springframework.boot.actuate.cloudfoundry;
import java.util.List; import java.util.Map;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
...@@ -162,13 +162,13 @@ public class CloudFoundrySecurityServiceTests { ...@@ -162,13 +162,13 @@ public class CloudFoundrySecurityServiceTests {
+ "kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo\n" + "kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo\n"
+ "jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI\n" + "jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI\n"
+ "JwIDAQAB\n-----END PUBLIC KEY-----"; + "JwIDAQAB\n-----END PUBLIC KEY-----";
String responseBody = "{\"keys\" : [ {\"value\" : \"" String responseBody = "{\"keys\" : [ {\"kid\":\"test-key\",\"value\" : \""
+ tokenKeyValue.replace("\n", "\\n") + "\"} ]}"; + tokenKeyValue.replace("\n", "\\n") + "\"} ]}";
this.server.expect(requestTo(UAA_URL + "/token_keys")) this.server.expect(requestTo(UAA_URL + "/token_keys"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
List<String> tokenKeys = this.securityService.fetchTokenKeys(); Map<String, String> tokenKeys = this.securityService.fetchTokenKeys();
this.server.verify(); this.server.verify();
assertThat(tokenKeys).containsExactly(tokenKeyValue); assertThat(tokenKeys.get("test-key")).isEqualTo(tokenKeyValue);
} }
@Test @Test
...@@ -178,7 +178,7 @@ public class CloudFoundrySecurityServiceTests { ...@@ -178,7 +178,7 @@ public class CloudFoundrySecurityServiceTests {
String responseBody = "{\"keys\": []}"; String responseBody = "{\"keys\": []}";
this.server.expect(requestTo(UAA_URL + "/token_keys")) this.server.expect(requestTo(UAA_URL + "/token_keys"))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
List<String> tokenKeys = this.securityService.fetchTokenKeys(); Map<String, String> tokenKeys = this.securityService.fetchTokenKeys();
this.server.verify(); this.server.verify();
assertThat(tokenKeys).hasSize(0); assertThat(tokenKeys).hasSize(0);
} }
......
...@@ -82,6 +82,7 @@ public class TokenTests { ...@@ -82,6 +82,7 @@ public class TokenTests {
assertThat(token.getExpiry()).isEqualTo(2147483647); assertThat(token.getExpiry()).isEqualTo(2147483647);
assertThat(token.getIssuer()).isEqualTo("http://localhost:8080/uaa/oauth/token"); assertThat(token.getIssuer()).isEqualTo("http://localhost:8080/uaa/oauth/token");
assertThat(token.getSignatureAlgorithm()).isEqualTo("RS256"); assertThat(token.getSignatureAlgorithm()).isEqualTo("RS256");
assertThat(token.getKeyId()).isEqualTo("key-id");
assertThat(token.getContent()).isEqualTo(content.getBytes()); assertThat(token.getContent()).isEqualTo(content.getBytes());
assertThat(token.getSignature()) assertThat(token.getSignature())
.isEqualTo(Base64Utils.decodeFromString(signature)); .isEqualTo(Base64Utils.decodeFromString(signature));
...@@ -100,7 +101,7 @@ public class TokenTests { ...@@ -100,7 +101,7 @@ public class TokenTests {
@Test @Test
public void getIssuerWhenIssIsNullShouldThrowException() throws Exception { public void getIssuerWhenIssIsNullShouldThrowException() throws Exception {
String header = "{\"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}"; String header = "{\"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647}"; String claims = "{\"exp\": 2147483647}";
Token token = createToken(header, claims); Token token = createToken(header, claims);
this.thrown this.thrown
...@@ -108,6 +109,16 @@ public class TokenTests { ...@@ -108,6 +109,16 @@ public class TokenTests {
token.getIssuer(); token.getIssuer();
} }
@Test
public void getKidWhenKidIsNullShouldThrowException() throws Exception {
String header = "{\"alg\": \"RS256\", \"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647}";
Token token = createToken(header, claims);
this.thrown
.expect(AuthorizationExceptionMatcher.withReason(Reason.INVALID_TOKEN));
token.getKeyId();
}
@Test @Test
public void getExpiryWhenExpIsNullShouldThrowException() throws Exception { public void getExpiryWhenExpIsNullShouldThrowException() throws Exception {
String header = "{\"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}"; String header = "{\"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}";
......
...@@ -26,7 +26,7 @@ import java.security.Signature; ...@@ -26,7 +26,7 @@ import java.security.Signature;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.Map;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.junit.Before; import org.junit.Before;
...@@ -82,10 +82,10 @@ public class TokenValidatorTests { ...@@ -82,10 +82,10 @@ public class TokenValidatorTests {
+ "r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s\n" + "r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s\n"
+ "YwIDAQAB\n-----END PUBLIC KEY-----"; + "YwIDAQAB\n-----END PUBLIC KEY-----";
private static final List<String> INVALID_KEYS = Collections private static final Map<String, String> INVALID_KEYS = Collections
.singletonList(INVALID_KEY); .singletonMap("invalid-key", INVALID_KEY);
private static final List<String> VALID_KEYS = Collections.singletonList(VALID_KEY); private static final Map<String, String> VALID_KEYS = Collections.singletonMap("valid-key", VALID_KEY);
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
...@@ -94,25 +94,25 @@ public class TokenValidatorTests { ...@@ -94,25 +94,25 @@ public class TokenValidatorTests {
} }
@Test @Test
public void validateTokenWhenSignatureValidationFailsTwiceShouldThrowException() public void validateTokenWhenKidValidationFailsTwiceShouldThrowException()
throws Exception { throws Exception {
ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS); ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS);
given(this.securityService.fetchTokenKeys()).willReturn(INVALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(INVALID_KEYS);
String header = "{\"alg\": \"RS256\", \"kid\": \"key-id\",\"typ\": \"JWT\"}"; String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
this.thrown.expect( this.thrown.expect(
AuthorizationExceptionMatcher.withReason(Reason.INVALID_SIGNATURE)); AuthorizationExceptionMatcher.withReason(Reason.INVALID_KEY_ID));
this.tokenValidator.validate( this.tokenValidator.validate(
new Token(getSignedToken(header.getBytes(), claims.getBytes()))); new Token(getSignedToken(header.getBytes(), claims.getBytes())));
} }
@Test @Test
public void validateTokenWhenSignatureValidationSucceedsInTheSecondAttempt() public void validateTokenWhenKidValidationSucceedsInTheSecondAttempt()
throws Exception { throws Exception {
ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS); ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS);
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa");
String header = "{ \"alg\": \"RS256\", \"kid\": \"key-id\",\"typ\": \"JWT\"}"; String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
this.tokenValidator.validate( this.tokenValidator.validate(
new Token(getSignedToken(header.getBytes(), claims.getBytes()))); new Token(getSignedToken(header.getBytes(), claims.getBytes())));
...@@ -123,7 +123,7 @@ public class TokenValidatorTests { ...@@ -123,7 +123,7 @@ public class TokenValidatorTests {
public void validateTokenShouldFetchTokenKeysIfNull() throws Exception { public void validateTokenShouldFetchTokenKeysIfNull() throws Exception {
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa");
String header = "{ \"alg\": \"RS256\", \"kid\": \"key-id\",\"typ\": \"JWT\"}"; String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
this.tokenValidator.validate( this.tokenValidator.validate(
new Token(getSignedToken(header.getBytes(), claims.getBytes()))); new Token(getSignedToken(header.getBytes(), claims.getBytes())));
...@@ -131,17 +131,29 @@ public class TokenValidatorTests { ...@@ -131,17 +131,29 @@ public class TokenValidatorTests {
} }
@Test @Test
public void validateTokenWhenSignatureValidShouldNotFetchTokenKeys() public void validateTokenWhenValidShouldNotFetchTokenKeys()
throws Exception { throws Exception {
ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", VALID_KEYS); ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", VALID_KEYS);
given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa");
String header = "{ \"alg\": \"RS256\", \"kid\": \"key-id\",\"typ\": \"JWT\"}"; String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
this.tokenValidator.validate( this.tokenValidator.validate(
new Token(getSignedToken(header.getBytes(), claims.getBytes()))); new Token(getSignedToken(header.getBytes(), claims.getBytes())));
verify(this.securityService, Mockito.never()).fetchTokenKeys(); verify(this.securityService, Mockito.never()).fetchTokenKeys();
} }
@Test
public void validateTokenWhenSignatureInvalidShouldThrowException() throws Exception {
ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", Collections.singletonMap("valid-key", INVALID_KEY));
given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa");
String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}";
this.thrown.expect(
AuthorizationExceptionMatcher.withReason(Reason.INVALID_SIGNATURE));
this.tokenValidator.validate(
new Token(getSignedToken(header.getBytes(), claims.getBytes())));
}
@Test @Test
public void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException() public void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException()
throws Exception { throws Exception {
...@@ -158,7 +170,7 @@ public class TokenValidatorTests { ...@@ -158,7 +170,7 @@ public class TokenValidatorTests {
public void validateTokenWhenExpiredShouldThrowException() throws Exception { public void validateTokenWhenExpiredShouldThrowException() throws Exception {
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
String header = "{ \"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}"; String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}"; String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}";
this.thrown this.thrown
.expect(AuthorizationExceptionMatcher.withReason(Reason.TOKEN_EXPIRED)); .expect(AuthorizationExceptionMatcher.withReason(Reason.TOKEN_EXPIRED));
...@@ -170,7 +182,7 @@ public class TokenValidatorTests { ...@@ -170,7 +182,7 @@ public class TokenValidatorTests {
public void validateTokenWhenIssuerIsNotValidShouldThrowException() throws Exception { public void validateTokenWhenIssuerIsNotValidShouldThrowException() throws Exception {
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
given(this.securityService.getUaaUrl()).willReturn("http://other-uaa.com"); given(this.securityService.getUaaUrl()).willReturn("http://other-uaa.com");
String header = "{ \"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}"; String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}"; String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}";
this.thrown this.thrown
.expect(AuthorizationExceptionMatcher.withReason(Reason.INVALID_ISSUER)); .expect(AuthorizationExceptionMatcher.withReason(Reason.INVALID_ISSUER));
...@@ -183,7 +195,7 @@ public class TokenValidatorTests { ...@@ -183,7 +195,7 @@ public class TokenValidatorTests {
throws Exception { throws Exception {
given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS);
given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa");
String header = "{ \"alg\": \"RS256\", \"kid\": \"key-id\", \"typ\": \"JWT\"}"; String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}";
String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}";
this.thrown.expect( this.thrown.expect(
AuthorizationExceptionMatcher.withReason(Reason.INVALID_AUDIENCE)); AuthorizationExceptionMatcher.withReason(Reason.INVALID_AUDIENCE));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment