@Test public void decodeWhenIssuedAtThenSuccess() { String withIssuedAt = "eyJraWQiOiJrZXktaWQtMSIsImFsZyI6IlJTMjU2In0.eyJzY29wZSI6IiIsImV4cCI6OTIyMzM3MjAwNjA5NjM3NSwiaWF0IjoxNTI5OTQyNDQ4fQ.LBzAJO-FR-uJDHST61oX4kimuQjz6QMJPW_mvEXRB6A-fMQWpfTQ089eboipAqsb33XnwWth9ELju9HMWLk0FjlWVVzwObh9FcoKelmPNR8mZIlFG-pAYGgSwi8HufyLabXHntFavBiFtqwp_z9clSOFK1RxWvt3lywEbGgtCKve0BXOjfKWiH1qe4QKGixH-NFxidvz8Qd5WbJwyb9tChC6ZKoKPv7Jp-N5KpxkY-O2iUtINvn4xOSactUsvKHgF8ZzZjvJGzG57r606OZXaNtoElQzjAPU5xDGg5liuEJzfBhvqiWCLRmSuZ33qwp3aoBnFgEw0B85gsNe3ggABg"; Jwt jwt = this.decoder.decode(withIssuedAt).block(); assertThat(jwt.getClaims().get(JwtClaimNames.IAT)).isEqualTo(Instant.ofEpochSecond(1529942448L)); }
@Test public void decodeWhenMessageReadScopeThenSuccess() { Jwt jwt = this.decoder.decode(this.messageReadToken).block(); assertThat(jwt.getClaims().get("scope")).isEqualTo("message:read"); }
@Test public void decodeWhenInvalidSignatureThenFail() { assertThatCode(() -> this.decoder.decode(this.messageReadToken.substring(0, this.messageReadToken.length() - 2)).block()) .isInstanceOf(JwtException.class); }
@Test public void decodeWhenUnsignedTokenThenMessageDoesNotMentionClass() { assertThatCode(() -> this.decoder.decode(this.unsignedToken).block()) .isInstanceOf(JwtException.class) .hasMessage("Unsupported algorithm of none"); }
@Test public void decodeWhenAlgNoneThenFail() { assertThatCode(() -> this.decoder.decode("ew0KICAiYWxnIjogIm5vbmUiLA0KICAidHlwIjogIkpXVCINCn0.ew0KICAic3ViIjogIjEyMzQ1Njc4OTAiLA0KICAibmFtZSI6ICJKb2huIERvZSIsDQogICJpYXQiOiAxNTE2MjM5MDIyDQp9.").block()) .isInstanceOf(JwtException.class) .hasMessage("Unsupported algorithm of none"); }
@Test public void decodeWhenNoPeriodThenFail() { assertThatCode(() -> this.decoder.decode("").block()) .isInstanceOf(JwtException.class); }
@Test public void decodeWhenInvalidAlgMismatchThenFail() { assertThatCode(() -> this.decoder.decode("ew0KICAiYWxnIjogIkVTMjU2IiwNCiAgInR5cCI6ICJKV1QiDQp9.ew0KICAic3ViIjogIjEyMzQ1Njc4OTAiLA0KICAibmFtZSI6ICJKb2huIERvZSIsDQogICJpYXQiOiAxNTE2MjM5MDIyDQp9.").block()) .isInstanceOf(JwtException.class); }
@Test public void decodeWhenExpiredThenFail() { assertThatCode(() -> this.decoder.decode(this.expired).block()) .isInstanceOf(JwtValidationException.class); }
@Override public Mono<Jwt> decode(String token) throws JwtException { JWT jwt = parse(token); if (jwt instanceof SignedJWT) { return this.decode((SignedJWT) jwt); } throw new JwtException("Unsupported algorithm of " + jwt.getHeader().getAlgorithm()); }
@Test public void decodeWhenUsingSignedJwtThenReturnsClaimsGivenByClaimSetConverter() { Converter<Map<String, Object>, Map<String, Object>> claimSetConverter = mock(Converter.class); this.decoder.setClaimSetConverter(claimSetConverter); when(claimSetConverter.convert(any(Map.class))).thenReturn(Collections.singletonMap("custom", "value")); Jwt jwt = this.decoder.decode(this.messageReadToken).block(); assertThat(jwt.getClaims().size()).isEqualTo(1); assertThat(jwt.getClaims().get("custom")).isEqualTo("value"); verify(claimSetConverter).convert(any(Map.class)); }
@Test public void decodeWhenRSAPublicKeyThenSuccess() throws Exception { byte[] bytes = Base64.getDecoder().decode("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqL48v1clgFw+Evm145pmh8nRYiNt72Gupsshn7Qs8dxEydCRp1DPOV/PahPk1y2nvldBNIhfNL13JOAiJ6BTiF+2ICuICAhDArLMnTH61oL1Hepq8W1xpa9gxsnL1P51thvfmiiT4RTW57koy4xIWmIp8ZXXfYgdH2uHJ9R0CQBuYKe7nEOObjxCFWC8S30huOfW2cYtv0iB23h6w5z2fDLjddX6v/FXM7ktcokgpm3/XmvT/+bL6/GGwz9k6kJOyMTubecr+WT//le8ikY66zlplYXRQh6roFfFCL21Pt8xN5zrk+0AMZUnmi8F2S2ztSBmAVJ7H71ELXsURBVZpwIDAQAB"); RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(bytes)); this.decoder = new NimbusReactiveJwtDecoder(publicKey); String noKeyId = "eyJhbGciOiJSUzI1NiJ9.eyJzY29wZSI6IiIsImV4cCI6OTIyMzM3MjAwNjA5NjM3NX0.hNVuHSUkxdLZrDfqdmKcOi0ggmNaDuB4ZPxPtJl1gwBiXzIGN6Hwl24O2BfBZiHFKUTQDs4_RvzD71mEG3DvUrcKmdYWqIB1l8KNmxQLUDG-cAPIpJmRJgCh50tf8OhOE_Cb9E1HcsOUb47kT9iz-VayNBcmo6BmyZLdEGhsdGBrc3Mkz2dd_0PF38I2Hf_cuSjn9gBjFGtiPEXJvob3PEjVTSx_zvodT8D9p3An1R3YBZf5JSd1cQisrXgDX2k1Jmf7UKKWzgfyCgnEtRWWbsUdPqo3rSEY9GDC1iSQXsFTTC1FT_JJDkwzGf011fsU5O_Ko28TARibmKTCxAKNRQ"; assertThatCode(() -> this.decoder.decode(noKeyId).block()) .doesNotThrowAnyException(); }
@Test public void decodeWhenInvalidJwkSetUrlThenFail() { this.decoder = new NimbusReactiveJwtDecoder("http://localhost:1280/certs"); assertThatCode(() -> this.decoder.decode(this.messageReadToken).block()) .isInstanceOf(IllegalStateException.class); }
@Test public void decodeWhenInvalidUrl() { this.decoder = new NimbusReactiveJwtDecoder("https://s"); assertThatCode(() -> this.decoder.decode(this.messageReadToken).block()) .isInstanceOf(IllegalStateException.class) .hasCauseInstanceOf(UnknownHostException.class); }
@Test public void decodeWhenUsingCustomValidatorThenValidatorIsInvoked() { OAuth2TokenValidator jwtValidator = mock(OAuth2TokenValidator.class); this.decoder.setJwtValidator(jwtValidator); OAuth2Error error = new OAuth2Error("mock-error", "mock-description", "mock-uri"); OAuth2TokenValidatorResult result = OAuth2TokenValidatorResult.failure(error); when(jwtValidator.validate(any(Jwt.class))).thenReturn(result); assertThatCode(() -> this.decoder.decode(this.messageReadToken).block()) .isInstanceOf(JwtException.class) .hasMessageContaining("mock-description"); }
@Override public Mono<Jwt> decode(String token) throws JwtException { JWT jwt = parse(token); if (jwt instanceof SignedJWT) { return this.decode((SignedJWT) jwt); } throw new JwtException("Unsupported algorithm of " + jwt.getHeader().getAlgorithm()); }