type) {
56 | return weld.select(type, new ClaimQualifier(name, null)).get();
57 | }
58 |
59 | @Test
60 | void issuerNullPointerException() {
61 | JsonString issuer = selectJsonValue("iss", JsonString.class);
62 | assertNull(issuer);
63 | }
64 |
65 | @Test
66 | void issuerInjected() {
67 | jwtProducer = weld.select(PrincipalProducer.class).get();
68 | jwtProducer.setJsonWebToken(jwt);
69 | Mockito.when(jwt.claim(Claims.iss.name())).thenReturn(Optional.of("issuer1"));
70 | JsonString issuer = selectJsonValue("iss", JsonString.class);
71 |
72 | assertNotNull(issuer);
73 | assertEquals("issuer1", issuer.getString());
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/java/io/smallrye/jwt/auth/cdi/PrincipalProducerIT.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.cdi;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertEquals;
4 | import static org.junit.jupiter.api.Assertions.assertNotNull;
5 | import static org.junit.jupiter.api.Assertions.assertNull;
6 |
7 | import java.util.Collections;
8 | import java.util.HashMap;
9 |
10 | import org.eclipse.microprofile.jwt.JsonWebToken;
11 | import org.jboss.weld.context.bound.BoundRequestContext;
12 | import org.jboss.weld.junit5.WeldInitiator;
13 | import org.jboss.weld.junit5.WeldJunit5Extension;
14 | import org.jboss.weld.junit5.WeldSetup;
15 | import org.junit.jupiter.api.AfterEach;
16 | import org.junit.jupiter.api.BeforeEach;
17 | import org.junit.jupiter.api.Test;
18 | import org.junit.jupiter.api.extension.ExtendWith;
19 | import org.mockito.Mock;
20 | import org.mockito.Mockito;
21 | import org.mockito.MockitoAnnotations;
22 |
23 | @ExtendWith(WeldJunit5Extension.class)
24 | class PrincipalProducerIT {
25 |
26 | @WeldSetup
27 | WeldInitiator weld = WeldInitiator.of(PrincipalProducer.class);
28 |
29 | @Mock
30 | JsonWebToken jwt;
31 |
32 | BoundRequestContext context;
33 |
34 | @BeforeEach
35 | void setUp() {
36 | MockitoAnnotations.initMocks(this);
37 | context = weld.select(BoundRequestContext.class).get();
38 | context.associate(new HashMap<>());
39 | // Start Request Scope
40 | context.activate();
41 | }
42 |
43 | @AfterEach
44 | void tearDown() {
45 | // End Request Scope
46 | context.deactivate();
47 | }
48 |
49 | @Test
50 | void nullPrincipal() {
51 | JsonWebToken jwt = weld.select(JsonWebToken.class).get();
52 | assertNotNull(jwt);
53 | assertNull(jwt.getName());
54 | assertNull(jwt.getClaimNames());
55 | }
56 |
57 | @Test
58 | void principalInjected() {
59 | PrincipalProducer jwtProducer = weld.select(PrincipalProducer.class).get();
60 | Mockito.when(jwt.getName()).thenReturn("User1");
61 | Mockito.when(jwt.getClaimNames()).thenReturn(Collections.singleton("upn"));
62 | jwtProducer.setJsonWebToken(jwt);
63 |
64 | JsonWebToken jwt = weld.select(JsonWebToken.class).get();
65 | assertNotNull(jwt);
66 | assertEquals("User1", jwt.getName());
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/java/io/smallrye/jwt/auth/principal/AwsAlbKeyConfigurationValidatorTest.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.principal;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertFalse;
4 | import static org.junit.jupiter.api.Assertions.assertTrue;
5 |
6 | import org.junit.jupiter.api.Test;
7 |
8 | public class AwsAlbKeyConfigurationValidatorTest {
9 |
10 | @Test
11 | void containsSubPath() {
12 | assertTrue(AwsAlbKeyConfigurationValidator
13 | .containsSubPath("https://public-keys.auth.elb.eu-central-1.amazonaws.com/keyid"));
14 | assertTrue(AwsAlbKeyConfigurationValidator
15 | .containsSubPath("https://public-keys.auth.elb.eu-central-1.amazonaws.com/index/keyid"));
16 | assertTrue(AwsAlbKeyConfigurationValidator
17 | .containsSubPath("https://public-keys.auth.elb.eu-central-1.amazonaws.com/index.html"));
18 | assertFalse(
19 | AwsAlbKeyConfigurationValidator.containsSubPath("https://public-keys.auth.elb.eu-central-1.amazonaws.com/"));
20 | assertFalse(AwsAlbKeyConfigurationValidator.containsSubPath("https://public-keys.auth.elb.eu-central-1.amazonaws.com"));
21 | }
22 |
23 | @Test
24 | void removeEndingSlash() {
25 | assertTrue(AwsAlbKeyConfigurationValidator.removeEndingSlash("key-location/keyid")
26 | .equals("key-location/keyid"));
27 | assertTrue(AwsAlbKeyConfigurationValidator.removeEndingSlash("key-location/index/keyid/")
28 | .equals("key-location/index/keyid"));
29 | assertTrue(AwsAlbKeyConfigurationValidator.removeEndingSlash("key-location/index.html/")
30 | .equals("key-location/index.html"));
31 | assertTrue(AwsAlbKeyConfigurationValidator.removeEndingSlash("key-location/")
32 | .equals("key-location"));
33 | assertTrue(AwsAlbKeyConfigurationValidator.removeEndingSlash("key-location")
34 | .equals("key-location"));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/java/io/smallrye/jwt/auth/principal/AwsAlbKeyResolverTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.auth.principal;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertTrue;
20 | import static org.mockito.Mockito.when;
21 |
22 | import java.security.Key;
23 | import java.security.interfaces.ECPublicKey;
24 | import java.util.List;
25 | import java.util.Set;
26 |
27 | import org.jose4j.http.SimpleGet;
28 | import org.jose4j.http.SimpleResponse;
29 | import org.jose4j.jwk.JsonWebKey;
30 | import org.jose4j.jws.JsonWebSignature;
31 | import org.jose4j.jwx.Headers;
32 | import org.junit.jupiter.api.Test;
33 | import org.junit.jupiter.api.extension.ExtendWith;
34 | import org.mockito.Mock;
35 | import org.mockito.Mockito;
36 | import org.mockito.junit.jupiter.MockitoExtension;
37 |
38 | import io.smallrye.jwt.algorithm.SignatureAlgorithm;
39 |
40 | @ExtendWith(MockitoExtension.class)
41 | class AwsAlbKeyResolverTest {
42 |
43 | private static final String AWS_ALB_KEY = "-----BEGIN PUBLIC KEY-----"
44 | + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjPHY1j9umvc8nZEswOzs+lPpLKLn"
45 | + "qCBqvyZGJfBlXapmtGiqYEwpIqh/lZdkr4wDii7CP1DzIUSHONbc+jufiQ=="
46 | + "-----END PUBLIC KEY-----";
47 |
48 | @Mock
49 | JsonWebSignature signature;
50 | @Mock
51 | Headers headers;
52 | @Mock
53 | SimpleGet simpleGet;
54 | @Mock
55 | SimpleResponse simpleResponse;
56 |
57 | AwsAlbKeyResolverTest() throws Exception {
58 |
59 | }
60 |
61 | @Test
62 | void loadAwsAlbVerificationKey() throws Exception {
63 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(
64 | "https://localhost:8080",
65 | "https://cognito-idp.eu-central-1.amazonaws.com");
66 | contextInfo.setSignatureAlgorithm(Set.of(SignatureAlgorithm.ES256));
67 |
68 | AwsAlbKeyResolver keyLocationResolver = new AwsAlbKeyResolver(contextInfo);
69 | keyLocationResolver = Mockito.spy(keyLocationResolver);
70 |
71 | when(keyLocationResolver.getHttpGet()).thenReturn(simpleGet);
72 |
73 | when(simpleGet.get("https://localhost:8080/c2f80c8b-c05c-4068-af14-17299f7896b1"))
74 | .thenReturn(simpleResponse);
75 |
76 | when(simpleResponse.getBody()).thenReturn(AWS_ALB_KEY);
77 |
78 | when(signature.getHeaders()).thenReturn(headers);
79 | when(headers.getStringHeaderValue(JsonWebKey.KEY_ID_PARAMETER)).thenReturn("c2f80c8b-c05c-4068-af14-17299f7896b1");
80 |
81 | Key key = keyLocationResolver.resolveKey(signature, List.of());
82 | assertTrue(key instanceof ECPublicKey);
83 | // Confirm the cached key is returned
84 | Key key2 = keyLocationResolver.resolveKey(signature, List.of());
85 | assertTrue(key2 == key);
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/decryptPrivateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "kid":"key1",
4 | "n":"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ",
5 | "e":"AQAB",
6 | "d":"AvIDTlsK_priQLTwEQf5IVf2Xl638Q7dHdXyDC-oAAPmv1GcqRVH7Wm5oAPW_CZQfWhV55WRVaJzP8AhksyD5NcslH79hQZT4NT6xgApGYecrvmseuZ4dfR-e1cxXTRNBxaoXvwSiv4LuOPHmC8XGX712AhOoCGKiZp1WFqqkKwTpkgJEApJFVb-XRIKQa0YaRKpJsJ534pLMwTh7LoPLM4BCaBVbRfHzH2H5L3TSJP718kyCuxg3z2p9Y7zIOLTmgFdeR0_kd_xKUFZ2ByN3SKlC0IWlLUSiMPsGYExRpZTMZHKyD939gv-2_Z-bOYfKlYNIvAmQH_8CcX2I039LQ",
7 | "p":"104AjPaxZoi_BiMBODlChnZOvRJT071PdkeZ283uyrdW8qqKD9q8FTMgUXzKoboHtUiHbJbLOobPmPDh93839rq7dTdCNzNVOuLmE-V3_bmaShdzvxEIazwPf6AvjbEZAc-zu2RS4SNkp1LbzgSl9nINSlF7t6Lkl6T28PYULys",
8 | "q":"om5ooyzxa4ZJ-dU0ODsEb-Bmz6xwb27xF9aEhBYJprHeoNs2QM1D64_A39weD9MYwBux4-ivshCJ0dVKEbDujJRLnzf-ssrasA6CFyaaCT4DKtq1oWb9rcG-2LQd5Bm9PttrUrSUNqitr085IYikaLEz7UU6gtXPoC8UOcJ4cSc",
9 | "dp":"DeWE95Q8oweUfMrpmz1m49LjBiUWsAX6CQJaFevWy9LFk-gZ_Sf7F8sy_M93LLUbJkJGK2YYO_DTmWWC0Dyv2gb3bntglLuFdsWKYCJhekjugnW9DMoGpxU7Utt99kFGAe3sBd5V0x47sukQMt3t8FgwL2nO-G1VH8yP-8GGT_0",
10 | "dq":"TGBeE1wuqMCcSD1YMJiPnYuGzF_o_nzMIMldxj4Wi6tXY4uwFwhtx3Xw21JFUGuSV8KuAtyGwNPF-kSwb2Eiyjdw140c1jVMXzxzLy-XfoEKPDxa62niHrHba0pGQ9tWgRfrfxgqGQl3odc-peX6aL_qCsdim-KtnkSE3iPzPkE",
11 | "qi":"Jzp5KnT24y0wOoPUn_11S3ZcYl0i03dkaH4c5zR02G1MJG9K017juurx2aXVTctOzrj7O226EUiL1Qbq3QtnWFDDGY6vNZuqzJM7AMXsvp1djq_6fEVhxCIOgfJbmhb3mkG82rxn4et9o_TNr6mvEmHzG15sHbvZbAnn4GeqToY"
12 | }
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/privateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"oct",
3 | "k":"Fdh9u8rINxfivbrianbbVT1u232VQBZYKx1HGAGPt2I",
4 | "kid": "secretkey1"
5 | }
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/privateKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
3 | PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
4 | OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
5 | qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
6 | nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
7 | uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
8 | oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
9 | 6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
10 | URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
11 | 96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
12 | Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
13 | zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
14 | KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
15 | iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
16 | m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
17 | 34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
18 | 5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
19 | tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
20 | WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
21 | b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
22 | nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
23 | MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
24 | Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
25 | Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
26 | FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
27 | f3cg+fr8aou7pr9SHhJlZCU=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/publicCrt.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----\nMIIDHDCCAgSgAwIBAgIIcdNq6CqSmxgwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE\nAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkw\nODE2MjEyMTAwWhcNMTkwOTAyMDkzNjAwWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl\nbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAOmck250iO/lgPgq8WQ7CvHUSNpyXMZPwIJ+viTBKFWtBS99\np6hUskt/L4+dq4kpGh2TdO1SroeL318sKSHnoLFKcd9e7Dmgl5a4tIccupXUjJgu\njcKj8u02FeUhrERb6scUWfdtIoEev2Fz8jrIThDFYWhqiwyXhEgiPQui41Sl23b3\ntXXoBuFHoVrbf/TneMGVDqff0jdiIKCLWF/z1f+iTbC9aDQAb/lsEnuC4/HpJLOh\nZOeYbcMcOlM+vib3bPkRXgSO0TeU+QqPbF5J+WtEtzBLQOV4MTFnULe4jaTxSZAU\nXwwbuJqPcN1P1KVZFT2WbTf2LbRdNoZ084Q4YtsCAwEAAaM4MDYwDAYDVR0TAQH/\nBAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ\nKoZIhvcNAQEFBQADggEBACCADIWtyqY+sTXI6PKBUag2QtzyK4JMsEIixw3HPOCT\nGfJcCeTENsk4dieGGUCwkZITo8vBs7JaxpZ+xZXvNbG82S7x7NoOgDbae/OHAKYs\nSj3bKMoXUt/HhLcAUPCWf5UKg4ROaLMvi+A1rMU0tBCCLSKHjuKh5D+iKm5tA5fM\nusztqlSiIA8xAbS7UK95ZIMQBSl4XPZbcmOZUKWqWQJr5aouLqGJIoKQUMHoeqGI\nxLTEnzcr1WTdApfXJsenHSfeugJ+/BYJUXAcldxUn8PozFYoGtgrGMlI89WaXBpZ\nrsSehnsnIDqbqZaPjrSOTUVZiY+vaFmgmHtH4A339nU=\n-----END CERTIFICATE-----\n
2 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/publicKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "n":"livFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm-ntyIv1p4kE1sPEQO73-HY8-Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF_F9-KEBWkwVta-PZ37bwqSE4sCb1soZFrVz_UT_LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv_3Lw50bAkbT4HeLFxTx4flEoZLKO_g0bAoV2uqBhkA9xnQ",
4 | "e":"AQAB",
5 | "kid": "key1"
6 | }
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/publicKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
3 | Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
4 | TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
5 | UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
6 | AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
7 | sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
8 | nQIDAQAB
9 | -----END RSA PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/implementation/jwt-auth/src/test/resources/token-claims.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969,
11 |
12 | "byte": 1,
13 | "short": 9,
14 | "integer": 99,
15 | "long": 999,
16 | "float": 99.9,
17 | "double": 99.99,
18 | "boolean": true,
19 | "char": "y",
20 | "string": "string",
21 |
22 | "stringArray": [
23 | "value0",
24 | "value1",
25 | "value2"
26 | ],
27 | "integerArray": [
28 | 0,
29 | 1,
30 | 2,
31 | 3
32 | ],
33 | "doubleArray": [
34 | 0.1,
35 | 1.1,
36 | 2.2,
37 | 3.3,
38 | 4.4
39 | ],
40 | "address": {
41 | "street": "street",
42 | "code": "code"
43 | },
44 | "customObject": {
45 | "my-service": {
46 | "groups": [
47 | "group1",
48 | "group2"
49 | ],
50 | "roles": [
51 | "role-in-my-service"
52 | ]
53 | },
54 | "service-B": {
55 | "roles": [
56 | "role-in-B"
57 | ]
58 | },
59 | "service-C": {
60 | "groups": [
61 | "groupC",
62 | "web-tier"
63 | ]
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/implementation/jwt-build/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 4.0.0
21 |
22 |
23 | io.smallrye
24 | smallrye-jwt-implementation-parent
25 | 4.6.3-SNAPSHOT
26 |
27 |
28 | smallrye-jwt-build
29 |
30 | SmallRye: MicroProfile JWT Build Implementation
31 |
32 |
33 |
34 | jakarta.json
35 | jakarta.json-api
36 | provided
37 |
38 |
39 | jakarta.annotation
40 | jakarta.annotation-api
41 | provided
42 |
43 |
44 | org.eclipse.microprofile.config
45 | microprofile-config-api
46 |
47 |
48 | org.eclipse.microprofile.jwt
49 | microprofile-jwt-auth-api
50 |
51 |
52 | org.bitbucket.b_c
53 | jose4j
54 |
55 |
56 | io.smallrye
57 | smallrye-jwt-common
58 |
59 |
60 | org.jboss.logging
61 | jboss-logging
62 |
63 |
64 | org.jboss.logging
65 | jboss-logging-annotations
66 |
67 |
68 | org.jboss.logging
69 | jboss-logging-processor
70 |
71 |
72 |
73 |
74 | org.junit.jupiter
75 | junit-jupiter
76 |
77 |
78 | org.eclipse.parsson
79 | parsson
80 |
81 |
82 | io.smallrye.config
83 | smallrye-config
84 |
85 |
86 | org.bouncycastle
87 | bcprov-jdk15on
88 |
89 |
90 |
91 |
92 |
93 |
94 | org.apache.maven.plugins
95 | maven-surefire-plugin
96 |
97 | true
98 |
99 |
100 |
101 | org.apache.maven.plugins
102 | maven-failsafe-plugin
103 |
104 |
105 | default-integration-test
106 |
107 | integration-test
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtEncryptionException.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build;
2 |
3 | /**
4 | * JWT Encryption Exception
5 | */
6 | @SuppressWarnings("serial")
7 | public class JwtEncryptionException extends JwtException {
8 | public JwtEncryptionException() {
9 | }
10 |
11 | public JwtEncryptionException(String errorMessage) {
12 | super(errorMessage);
13 | }
14 |
15 | public JwtEncryptionException(Throwable t) {
16 | super(t);
17 | }
18 |
19 | public JwtEncryptionException(String errorMessage, Throwable t) {
20 | super(errorMessage, t);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtException.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build;
2 |
3 | /**
4 | * Base JWT Exception
5 | */
6 | @SuppressWarnings("serial")
7 | public class JwtException extends RuntimeException {
8 | public JwtException() {
9 | }
10 |
11 | public JwtException(String errorMessage) {
12 | super(errorMessage);
13 | }
14 |
15 | public JwtException(Throwable t) {
16 | super(t);
17 | }
18 |
19 | public JwtException(String errorMessage, Throwable t) {
20 | super(errorMessage, t);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtSignatureBuilder.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build;
2 |
3 | import java.security.PublicKey;
4 | import java.security.cert.X509Certificate;
5 | import java.util.List;
6 |
7 | import io.smallrye.jwt.algorithm.SignatureAlgorithm;
8 |
9 | /**
10 | * JWT JsonWebSignature Builder.
11 | *
12 | *
13 | * JwtSignatureBuilder implementations must set the 'alg' (algorithm) header to 'RS256'
14 | * and 'typ' (token type) header to 'JWT' unless they have already been set.
15 | *
16 | * Note that JwtSignatureBuilder implementations are not expected to be thread-safe.
17 | *
18 | * @see RFC7515
19 | */
20 | public interface JwtSignatureBuilder extends JwtSignature {
21 |
22 | /**
23 | * Set a signature algorithm.
24 | * Note that only 'RS256' (default), 'ES256' and 'HS256' algorithms must be supported.
25 | *
26 | * @since 2.1.3
27 | *
28 | * @param algorithm the signature algorithm
29 | * @return JwtSignatureBuilder
30 | */
31 | JwtSignatureBuilder algorithm(SignatureAlgorithm algorithm);
32 |
33 | /**
34 | * Set a signature algorithm.
35 | * Note that only 'RS256' (default), 'ES256' and 'HS256' algorithms must be supported.
36 | *
37 | * @deprecated Use {@link #algorithm}
38 | *
39 | * @param algorithm the signature algorithm
40 | * @return JwtSignatureBuilder
41 | */
42 | @Deprecated
43 | default JwtSignatureBuilder signatureAlgorithm(SignatureAlgorithm algorithm) {
44 | return algorithm(algorithm);
45 | }
46 |
47 | /**
48 | * Set a 'kid' signature key id.
49 | *
50 | * @since 2.1.3
51 | *
52 | * @param keyId the key id
53 | * @return JwtSignatureBuilder
54 | */
55 | JwtSignatureBuilder keyId(String keyId);
56 |
57 | /**
58 | * Set a 'kid' signature key id.
59 | *
60 | * @deprecated Use {@link #keyId}
61 | *
62 | * @param keyId the key id
63 | * @return JwtSignatureBuilder
64 | */
65 | @Deprecated
66 | default JwtSignatureBuilder signatureKeyId(String keyId) {
67 | return keyId(keyId);
68 | }
69 |
70 | /**
71 | * Set X.509 Certificate SHA-1 'x5t' thumbprint.
72 | *
73 | * @param cert the certificate
74 | * @return JwtSignatureBuilder
75 | */
76 | JwtSignatureBuilder thumbprint(X509Certificate cert);
77 |
78 | /**
79 | * Set X.509 Certificate SHA-256 'x5t#S256' thumbprint.
80 | *
81 | * @param cert the certificate
82 | * @return JwtSignatureBuilder
83 | */
84 | JwtSignatureBuilder thumbprintS256(X509Certificate cert);
85 |
86 | /**
87 | * Set X.509 Certificate 'x5c' chain.
88 | *
89 | * @param cert the certificate
90 | * @return JwtSignatureBuilder
91 | */
92 | default JwtSignatureBuilder chain(X509Certificate cert) {
93 | return chain(List.of(cert));
94 | }
95 |
96 | /**
97 | * Set X.509 Certificate 'x5c' chain.
98 | *
99 | * @param chain the certificate chain
100 | * @return JwtSignatureBuilder
101 | */
102 | JwtSignatureBuilder chain(List chain);
103 |
104 | /**
105 | * Set JSON Web Key 'jwk' key.
106 | *
107 | * @param key the public key
108 | * @return JwtSignatureBuilder
109 | */
110 | JwtSignatureBuilder jwk(PublicKey key);
111 |
112 | /**
113 | * Set a token type (`typ`) header.
114 | *
115 | * @param type the token type
116 | * @return JwtSignatureBuilder
117 | */
118 | JwtSignatureBuilder type(String type);
119 |
120 | /**
121 | * Custom JWT signature header.
122 | *
123 | * If the 'alg' (algorithm) header is set with this method then it
124 | * has to match one of the {@link SignatureAlgorithm} values.
125 | *
126 | * @param name the header name
127 | * @param value the header value
128 | * @return JwtSignatureBuilder
129 | */
130 | JwtSignatureBuilder header(String name, Object value);
131 | }
132 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/JwtSignatureException.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build;
2 |
3 | /**
4 | * JWT Signature Exception
5 | */
6 | @SuppressWarnings("serial")
7 | public class JwtSignatureException extends JwtException {
8 | public JwtSignatureException() {
9 | }
10 |
11 | public JwtSignatureException(String errorMessage) {
12 | super(errorMessage);
13 | }
14 |
15 | public JwtSignatureException(Throwable t) {
16 | super(t);
17 | }
18 |
19 | public JwtSignatureException(String errorMessage, Throwable t) {
20 | super(errorMessage, t);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/impl/ImplLogging.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build.impl;
2 |
3 | import org.jboss.logging.BasicLogger;
4 | import org.jboss.logging.Logger;
5 | import org.jboss.logging.annotations.LogMessage;
6 | import org.jboss.logging.annotations.Message;
7 | import org.jboss.logging.annotations.MessageLogger;
8 |
9 | @MessageLogger(projectCode = "SRJWT", length = 5)
10 | interface ImplLogging extends BasicLogger {
11 | ImplLogging log = Logger.getMessageLogger(ImplLogging.class, ImplLogging.class.getPackage().getName());
12 |
13 | @LogMessage(level = Logger.Level.WARN)
14 | @Message(id = 1000, value = "%s property is deprecated and will be removed in the next major release")
15 | void deprecatedProperty(String property);
16 | }
17 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/impl/JwtProviderImpl.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build.impl;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.Map;
5 |
6 | import jakarta.json.JsonObject;
7 | import jakarta.json.JsonValue;
8 |
9 | import org.eclipse.microprofile.jwt.Claims;
10 | import org.eclipse.microprofile.jwt.JsonWebToken;
11 |
12 | import io.smallrye.jwt.build.JwtClaimsBuilder;
13 | import io.smallrye.jwt.build.spi.JwtProvider;
14 |
15 | /**
16 | * Default service provider for JWT Claims Builder objects.
17 | *
18 | */
19 | public class JwtProviderImpl extends JwtProvider {
20 |
21 | /**
22 | * {@inheritDoc}
23 | */
24 | @Override
25 | public JwtClaimsBuilder claims() {
26 | return new JwtClaimsBuilderImpl();
27 | }
28 |
29 | /**
30 | * {@inheritDoc}
31 | */
32 | @Override
33 | public JwtClaimsBuilder claims(Map claims) {
34 | return new JwtClaimsBuilderImpl(claims);
35 | }
36 |
37 | /**
38 | * {@inheritDoc}
39 | */
40 | public JwtClaimsBuilder claims(JsonObject jsonObject) {
41 | Map claims = new LinkedHashMap<>();
42 | for (Map.Entry entry : jsonObject.entrySet()) {
43 | claims.put(entry.getKey(), entry.getValue());
44 | }
45 | return claims(claims);
46 | }
47 |
48 | /**
49 | * {@inheritDoc}
50 | */
51 | @Override
52 | public JwtClaimsBuilder claims(String jsonLocation) {
53 | return new JwtClaimsBuilderImpl(jsonLocation);
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | @Override
60 | public JwtClaimsBuilder claimsJson(String json) {
61 | return new JwtClaimsBuilderImpl(JwtBuildUtils.parseJwtContent(json));
62 | }
63 |
64 | /**
65 | * {@inheritDoc}
66 | */
67 | @Override
68 | public JwtClaimsBuilder claims(JsonWebToken jwt) {
69 | Map claims = new LinkedHashMap<>();
70 | for (String name : jwt.getClaimNames()) {
71 | if (Claims.raw_token.name().equals(name)) {
72 | continue;
73 | }
74 | claims.put(name, jwt.getClaim(name));
75 | }
76 | return claims(claims);
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/main/java/io/smallrye/jwt/build/spi/SpiMessages.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.build.spi;
2 |
3 | import org.jboss.logging.Messages;
4 | import org.jboss.logging.annotations.Cause;
5 | import org.jboss.logging.annotations.Message;
6 | import org.jboss.logging.annotations.MessageBundle;
7 |
8 | import io.smallrye.jwt.build.JwtException;
9 |
10 | @MessageBundle(projectCode = "SRJWT", length = 5)
11 | interface SpiMessages {
12 | SpiMessages msg = Messages.getBundle(SpiMessages.class);
13 |
14 | @Message(id = 4000, value = "JwtProvider %s has not been found: %s")
15 | JwtException providerNotFound(String provider, String exceptionMessage, @Cause Throwable throwable);
16 |
17 | @Message(id = 4001, value = "JwtProvider %s class could not be accessed: %s")
18 | JwtException providerClassCannotBeAccessed(String provider, String exceptionMessage, @Cause Throwable throwable);
19 |
20 | @Message(id = 4002, value = "JwtProvider %s could not be instantiated: %s")
21 | JwtException providerCannotBeInstantiated(String provider, String exceptionMessage, @Cause Throwable throwable);
22 | }
23 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/java/io/smallrye/jwt/build/JwtProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.build;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertSame;
20 | import static org.junit.jupiter.api.Assertions.assertTrue;
21 |
22 | import org.junit.jupiter.api.Test;
23 |
24 | import io.smallrye.jwt.build.impl.JwtProviderImpl;
25 | import io.smallrye.jwt.build.spi.JwtProvider;
26 |
27 | class JwtProviderTest {
28 | @Test
29 | void provider() {
30 | JwtProvider provider = JwtProvider.provider();
31 | assertTrue(provider instanceof JwtProviderImpl);
32 | assertSame(provider, JwtProvider.provider());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/java/io/smallrye/jwt/build/JwtSignPS256Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.build;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertEquals;
20 |
21 | import java.io.File;
22 | import java.security.Security;
23 |
24 | import org.jose4j.jws.JsonWebSignature;
25 | import org.jose4j.jwt.JwtClaims;
26 | import org.jose4j.lang.BouncyCastleProviderHelp;
27 | import org.junit.jupiter.api.AfterAll;
28 | import org.junit.jupiter.api.BeforeAll;
29 | import org.junit.jupiter.api.Test;
30 |
31 | import io.smallrye.jwt.algorithm.SignatureAlgorithm;
32 | import io.smallrye.jwt.util.KeyUtils;
33 |
34 | class JwtSignPS256Test {
35 | @BeforeAll
36 | public static void installBouncyCastleProviderIfNeeded() {
37 | if (!isPS256Supported()) {
38 | BouncyCastleProviderHelp.enableBouncyCastleProvider();
39 | }
40 | }
41 |
42 | @AfterAll
43 | public static void uninstallBouncyCastleProviderIfNeeded() {
44 | if (!isPS256Supported()) {
45 | Security.removeProvider("org.bouncycastle.jce.provider.BouncyCastleProvider");
46 | }
47 | }
48 |
49 | private static boolean isPS256Supported() {
50 | for (String sigAlg : Security.getAlgorithms("Signature")) {
51 | if ("RSASSA-PSS".equalsIgnoreCase(sigAlg)) {
52 | return true;
53 | }
54 | }
55 | return false;
56 | }
57 |
58 | @Test
59 | void signClaimsPS256() throws Exception {
60 | String path = "src/test/resources/privateKey.pem";
61 | File file = new File(path);
62 | String jwt = Jwt.claims()
63 | .claim("customClaim", "custom-value")
64 | .jws().algorithm(SignatureAlgorithm.PS256)
65 | .sign("file:" + file.getAbsolutePath());
66 |
67 | JsonWebSignature jws = JwtSignTest.getVerifiedJws(jwt, KeyUtils.readPublicKey("/publicKey.pem"));
68 | JwtClaims claims = JwtClaims.parse(jws.getPayload());
69 |
70 | assertEquals(4, claims.getClaimsMap().size());
71 | JwtSignTest.checkDefaultClaimsAndHeaders(JwtSignTest.getJwsHeaders(jwt, 2), claims, "PS256", 300);
72 |
73 | assertEquals("custom-value", claims.getClaimValue("customClaim"));
74 | }
75 |
76 | @Test
77 | void signClaimsPS256Configured() throws Exception {
78 | JwtBuildConfigSource configSource = JwtSignTest.getConfigSource();
79 | configSource.setSignatureAlgorithm("PS256");
80 | String jwt = null;
81 | try {
82 | jwt = Jwt.claims()
83 | .claim("customClaim", "custom-value")
84 | .sign("/privateKey.pem");
85 | } finally {
86 | configSource.setSignatureAlgorithm(null);
87 | }
88 |
89 | JsonWebSignature jws = JwtSignTest.getVerifiedJws(jwt, KeyUtils.readPublicKey("/publicKey.pem"));
90 | JwtClaims claims = JwtClaims.parse(jws.getPayload());
91 |
92 | assertEquals(4, claims.getClaimsMap().size());
93 | JwtSignTest.checkDefaultClaimsAndHeaders(JwtSignTest.getJwsHeaders(jwt, 2), claims, "PS256", 300);
94 |
95 | assertEquals("custom-value", claims.getClaimValue("customClaim"));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource:
--------------------------------------------------------------------------------
1 | io.smallrye.jwt.build.JwtBuildConfigSource
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/certificate.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC9DCCAdygAwIBAgIJAO0Y7B7dV9KpMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV
3 | BAMMBHRlc3QwHhcNMjAwODI1MTIzOTA1WhcNMjEwODI1MTIzOTA1WjAPMQ0wCwYD
4 | VQQDDAR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsl8Cqii/
5 | 4UFg5Lq3R8kZ//Wmapq4KQn4k+foEOymfUbw44E6pCU+iCK0RbyKXgTMErMN3ZFD
6 | xpoDdSeEDoS2kdlRF4XNtFG8RW6+h1wLJGRj7gi9bc0Vg5CzTGWhDvI6oT23KtUa
7 | OBjIWknZtLAR5nEJ7vMADq3QKMHcxofx1GmmAQ2NDmVQJvTfM8wV02oZ2vX6yQjB
8 | 6t3vbMyIr+h2GU8teu9v/oUf9A9R2Pm6qULSZ80qyo5BXlwwG2D4HsGCxCdg5PqK
9 | Oi9SOkvlE65eBUR8NXxwHdou+SQ/ry//MPwLSpHo9AggVEmSYlfigyVo5w1FUVo6
10 | uYUG/abuKhCSoQIDAQABo1MwUTAdBgNVHQ4EFgQUcDgMETNCuUuEGWzKoXjrvS8+
11 | kQAwHwYDVR0jBBgwFoAUcDgMETNCuUuEGWzKoXjrvS8+kQAwDwYDVR0TAQH/BAUw
12 | AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAH0o4kU37vc7OR/+fPQJdrBQqQaukq5ri
13 | yuMSTrU1vSizEXpd0RFE8moSks6+Vh4mEzU7zLAU54N6glcGItEmBko5xgTuQRgd
14 | b0LtR7Bu28QKfRRJxZ9GnGxinDPtFPD+7oTXZfI2Ed/RAuVlbppEBr2Pr2eO9B1x
15 | fgYJNwA1K/XA38G7njxQ/wcpgOp/iFdV7dyR6CyAtwkD92sMnEZKPVz3trBT9DFM
16 | 5mynDFn9PHYVB7R5mUjIc7C9yskHGIsqqSBAfsxUqKfCS2NlWjn4+JZ8BYPLgy6X
17 | hlGxh5zhvJPoT6J9+gA5l1Z2xMXI08ym8quIIUJNoYovSf8x4bXVjQ==
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/customClaim.json:
--------------------------------------------------------------------------------
1 | {
2 | "customClaim": "custom-value"
3 | }
4 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/ecPrivateKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgvhj6xtHJanL3yBYt
3 | vmaLQ+ZlbO/zu66oWFYjQOxfpGahRANCAATDgeiG/A6PbUUFATU+sk4CU9FAzJaK
4 | aZcf2sgdrtgxNaLGRI1IWWu/fpApXBpu/Xl9Kv0BS5awPfTIZMzcujLS
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/ecPublicKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw4HohvwOj21FBQE1PrJOAlPRQMyW
3 | immXH9rIHa7YMTWixkSNSFlrv36QKVwabv15fSr9AUuWsD30yGTM3Loy0g==
4 | -----END PUBLIC KEY-----
5 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/edEcPrivateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"OKP",
3 | "crv":"Ed25519",
4 | "d":"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
5 | "x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
6 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/edEcPublicKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"OKP",
3 | "crv":"Ed25519",
4 | "x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
5 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/keystore.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smallrye/smallrye-jwt/b43b673fb4cdfb06a7a9224b0b09529a4e8d9027/implementation/jwt-build/src/test/resources/keystore.p12
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateEncryptionKeys.jwks:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty":"oct",
5 | "k":"Fdh9u8rINxfivbrianbbVT1u232VQBZYKx1HGAGPt2I",
6 | "kid": "secretkey1"
7 | },
8 | {
9 | "kty":"oct",
10 | "k":"mHgOIP5oLngqXKq0123456",
11 | "kid": "secretkey3",
12 | "alg": "A128KW"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"oct",
3 | "k":"Fdh9u8rINxfivbrianbbVT1u232VQBZYKx1HGAGPt2I",
4 | "kid": "secretkey1"
5 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
3 | PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
4 | OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
5 | qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
6 | nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
7 | uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
8 | oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
9 | 6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
10 | URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
11 | 96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
12 | Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
13 | zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
14 | KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
15 | iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
16 | m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
17 | 34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
18 | 5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
19 | tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
20 | WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
21 | b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
22 | nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
23 | MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
24 | Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
25 | Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
26 | FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
27 | f3cg+fr8aou7pr9SHhJlZCU=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateKey2.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyXwKqKL/hQWDk
3 | urdHyRn/9aZqmrgpCfiT5+gQ7KZ9RvDjgTqkJT6IIrRFvIpeBMwSsw3dkUPGmgN1
4 | J4QOhLaR2VEXhc20UbxFbr6HXAskZGPuCL1tzRWDkLNMZaEO8jqhPbcq1Ro4GMha
5 | Sdm0sBHmcQnu8wAOrdAowdzGh/HUaaYBDY0OZVAm9N8zzBXTahna9frJCMHq3e9s
6 | zIiv6HYZTy1672/+hR/0D1HY+bqpQtJnzSrKjkFeXDAbYPgewYLEJ2Dk+oo6L1I6
7 | S+UTrl4FRHw1fHAd2i75JD+vL/8w/AtKkej0CCBUSZJiV+KDJWjnDUVRWjq5hQb9
8 | pu4qEJKhAgMBAAECggEAJvBs4X7B3MfsAiLszgQN4/3ZlZ4vI+5kUM2osMEo22J4
9 | RgI5Lgpfa1LALhUp07qSXmauWTdUJ3AJ3zKANrcsMAzUEiGItZu+UR4LA/vJBunP
10 | kvBfgi/qSW12ZvAsx9mDiR2y9evNrH9khalnmHVzgu4ccAimc43oSm1/5+tXlLoZ
11 | 1QK/FohxBxAshtuDHGs8yKUL0jpv7dOrjhCj2ibmPYe6AUk9F61sVWO0/i0Q8UAO
12 | cYT3L5nCS5WnLhdCdYpIJJ7xl2PrVE/BAD+JEG5uCOYfVeYh+iCZVfpX17ryfNNU
13 | aBtyxKEGVtHbje3mO86mYN3noaS0w/zpUjBPgV+KEQKBgQDsp6VTmDIqHFTp2cC2
14 | yrDMxRznif92EGv7ccJDZtbTC37mAuf2J7x5b6AiE1EfxEXyGYzSk99sCns+GbL1
15 | EHABUt5pimDCl33b6XvuccQNpnJ0MfM5eRX9Ogyt/OKdDRnQsvrTPNCWOyJjvG01
16 | HQM4mfxaBBnxnvl5meH2pyG/ZQKBgQDA87DnyqEFhTDLX5c1TtwHSRj2xeTPGKG0
17 | GyxOJXcxR8nhtY9ee0kyLZ14RytnOxKarCFgYXeG4IoGEc/I42WbA4sq88tZcbe4
18 | IJkdX0WLMqOTdMrdx9hMU1ytKVUglUJZBVm7FaTQjA+ArMwqkXAA5HBMtArUsfJK
19 | Ut3l0hMIjQKBgQDS1vmAZJQs2Fj+jzYWpLaneOWrk1K5yR+rQUql6jVyiUdhfS1U
20 | LUrJlh3Avh0EhEUc0I6Z/YyMITpztUmu9BoV09K7jMFwHK/RAU+cvFbDIovN4cKk
21 | bbCdjt5FFIyBB278dLjrAb+EWOLmoLVbIKICB47AU+8ZSV1SbTrYGUcD0QKBgQCA
22 | liZv4na6sg9ZiUPAr+QsKserNSiN5zFkULOPBKLRQbFFbPS1l12pRgLqNCu1qQV1
23 | 9H5tt6arSRpSfy5FB14gFxV4s23yFrnDyF2h2GsFH+MpEq1bbaI1A10AvUnQ5AeK
24 | QemRpxPmM2DldMK/H5tPzO0WAOoy4r/ATkc4sG4kxQKBgBL9neT0TmJtxlYGzjNc
25 | jdJXs3Q91+nZt3DRMGT9s0917SuP77+FdJYocDiH1rVa9sGG8rkh1jTdqliAxDXw
26 | Im5IGS/0OBnkaN1nnGDk5yTiYxOutC5NSj7ecI5Erud8swW6iGqgz2ioFpGxxIYq
27 | RlgTv/6mVt41KALfKrYIkVLw
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateKeyA128KW.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"oct",
3 | "k":"mHgOIP5oLngqXKq0123456",
4 | "kid": "secretkey3",
5 | "alg": "A128KW"
6 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateKeyHS512.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"oct",
3 | "k":"mHgOIP5oLngqXKq0jo4AkG_I0aY0nRIgAfuB8p-MW9zvxTpW9GPapkIdNcHxe5Y1lCnfVWSePazRaePg2uf9Sg",
4 | "kid": "secretkey2",
5 | "alg": "HS512"
6 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/privateSigningKeys.jwks:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty":"oct",
5 | "k":"Fdh9u8rINxfivbrianbbVT1u232VQBZYKx1HGAGPt2I",
6 | "kid": "secretkey1"
7 | },
8 | {
9 | "kty":"oct",
10 | "k":"mHgOIP5oLngqXKq0jo4AkG_I0aY0nRIgAfuB8p-MW9zvxTpW9GPapkIdNcHxe5Y1lCnfVWSePazRaePg2uf9Sg",
11 | "kid": "secretkey2",
12 | "alg": "HS512"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/publicKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "n":"livFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm-ntyIv1p4kE1sPEQO73-HY8-Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF_F9-KEBWkwVta-PZ37bwqSE4sCb1soZFrVz_UT_LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv_3Lw50bAkbT4HeLFxTx4flEoZLKO_g0bAoV2uqBhkA9xnQ",
4 | "e":"AQAB",
5 | "kid": "key1"
6 | }
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/publicKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
3 | Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
4 | TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
5 | UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
6 | AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
7 | sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
8 | nQIDAQAB
9 | -----END RSA PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/implementation/jwt-build/src/test/resources/token.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969
11 | }
12 |
--------------------------------------------------------------------------------
/implementation/jwt-cdi-extension/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 4.0.0
21 |
22 |
23 | io.smallrye
24 | smallrye-jwt-implementation-parent
25 | 4.6.3-SNAPSHOT
26 |
27 |
28 | smallrye-jwt-cdi-extension
29 |
30 | SmallRye: MicroProfile JWT CDI Extension Implementation
31 |
32 |
33 |
34 | jakarta.enterprise
35 | jakarta.enterprise.cdi-api
36 | provided
37 |
38 |
39 | jakarta.annotation
40 | jakarta.annotation-api
41 | provided
42 |
43 |
44 | jakarta.servlet
45 | jakarta.servlet-api
46 | provided
47 |
48 |
49 | jakarta.json
50 | jakarta.json-api
51 | provided
52 |
53 |
54 | jakarta.security.enterprise
55 | jakarta.security.enterprise-api
56 | provided
57 |
58 |
59 | io.smallrye
60 | smallrye-jwt
61 |
62 |
63 | io.smallrye
64 | smallrye-jwt-jaxrs
65 |
66 |
67 | io.smallrye
68 | smallrye-jwt-http-mechanism
69 |
70 |
71 | org.jboss.logging
72 | jboss-logging
73 |
74 |
75 | org.jboss.logging
76 | jboss-logging-annotations
77 |
78 |
79 | org.jboss.logging
80 | jboss-logging-processor
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/implementation/jwt-http-mechanism/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 4.0.0
21 |
22 |
23 | io.smallrye
24 | smallrye-jwt-implementation-parent
25 | 4.6.3-SNAPSHOT
26 |
27 |
28 | smallrye-jwt-http-mechanism
29 |
30 | SmallRye: MicroProfile JWT HTTP Mechanism Implementation
31 |
32 |
33 |
34 | jakarta.enterprise
35 | jakarta.enterprise.cdi-api
36 | provided
37 |
38 |
39 | jakarta.annotation
40 | jakarta.annotation-api
41 | provided
42 |
43 |
44 | jakarta.servlet
45 | jakarta.servlet-api
46 | provided
47 |
48 |
49 | jakarta.json
50 | jakarta.json-api
51 | provided
52 |
53 |
54 | jakarta.security.enterprise
55 | jakarta.security.enterprise-api
56 | provided
57 |
58 |
59 | io.smallrye
60 | smallrye-jwt
61 |
62 |
63 | org.jboss.logging
64 | jboss-logging
65 |
66 |
67 | org.jboss.logging
68 | jboss-logging-annotations
69 |
70 |
71 | org.jboss.logging
72 | jboss-logging-processor
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/implementation/jwt-http-mechanism/src/main/java/io/smallrye/jwt/auth/mechanism/MechanismLogging.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.mechanism;
2 |
3 | import org.jboss.logging.BasicLogger;
4 | import org.jboss.logging.Logger;
5 | import org.jboss.logging.annotations.Cause;
6 | import org.jboss.logging.annotations.LogMessage;
7 | import org.jboss.logging.annotations.Message;
8 | import org.jboss.logging.annotations.MessageLogger;
9 |
10 | @MessageLogger(projectCode = "SRJWT", length = 5)
11 | interface MechanismLogging extends BasicLogger {
12 | MechanismLogging log = Logger.getMessageLogger(MechanismLogging.class, MechanismLogging.class.getPackage().getName());
13 |
14 | @LogMessage(level = Logger.Level.DEBUG)
15 | @Message(id = 11000, value = "Success")
16 | void success();
17 |
18 | @LogMessage(level = Logger.Level.DEBUG)
19 | @Message(id = 11001, value = "Unable to validate bearer token")
20 | void unableToValidateBearerToken(@Cause Throwable throwable);
21 |
22 | @LogMessage(level = Logger.Level.DEBUG)
23 | @Message(id = 11002, value = "No usable bearer token was found in the request, continuing unauthenticated")
24 | void noUsableBearerTokenFound();
25 |
26 | @LogMessage(level = Logger.Level.DEBUG)
27 | @Message(id = 11003, value = "Failed to resolve the key. Either corrupt or unavailable.")
28 | void noUsableKey();
29 |
30 | @LogMessage(level = Logger.Level.DEBUG)
31 | @Message(id = 11004, value = "JWK set does not contain provided token 'kid'")
32 | void kidNotInJWkSet();
33 | }
34 |
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 4.0.0
21 |
22 |
23 | io.smallrye
24 | smallrye-jwt-implementation-parent
25 | 4.6.3-SNAPSHOT
26 |
27 |
28 | smallrye-jwt-jaxrs
29 |
30 | SmallRye: MicroProfile JWT JAX-RS Implementation
31 |
32 |
33 |
34 | jakarta.enterprise
35 | jakarta.enterprise.cdi-api
36 | provided
37 |
38 |
39 | jakarta.annotation
40 | jakarta.annotation-api
41 | provided
42 |
43 |
44 | jakarta.servlet
45 | jakarta.servlet-api
46 | provided
47 |
48 |
49 | jakarta.ws.rs
50 | jakarta.ws.rs-api
51 | provided
52 |
53 |
54 | jakarta.json
55 | jakarta.json-api
56 | provided
57 |
58 |
59 | jakarta.security.enterprise
60 | jakarta.security.enterprise-api
61 | provided
62 |
63 |
64 |
65 | io.smallrye
66 | smallrye-jwt
67 |
68 |
69 |
70 | org.jboss.logging
71 | jboss-logging
72 |
73 |
74 | org.jboss.logging
75 | jboss-logging-annotations
76 |
77 |
78 | org.jboss.logging
79 | jboss-logging-processor
80 |
81 |
82 |
83 |
84 |
85 |
86 | org.apache.maven.plugins
87 | maven-surefire-plugin
88 |
89 | true
90 |
91 |
92 |
93 | org.apache.maven.plugins
94 | maven-failsafe-plugin
95 |
96 |
97 | default-integration-test
98 |
99 | integration-test
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/src/main/java/io/smallrye/jwt/auth/jaxrs/DenyAllFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.auth.jaxrs;
18 |
19 | import jakarta.annotation.Priority;
20 | import jakarta.ws.rs.ForbiddenException;
21 | import jakarta.ws.rs.Priorities;
22 | import jakarta.ws.rs.container.ContainerRequestContext;
23 | import jakarta.ws.rs.container.ContainerRequestFilter;
24 |
25 | /**
26 | * @author Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com
27 | *
28 | * Date: 6/12/18
29 | */
30 | @Priority(Priorities.AUTHORIZATION)
31 | public class DenyAllFilter implements ContainerRequestFilter {
32 |
33 | @Override
34 | public void filter(ContainerRequestContext requestContext) {
35 | throw new ForbiddenException();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/src/main/java/io/smallrye/jwt/auth/jaxrs/JAXRSLogging.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.jaxrs;
2 |
3 | import org.jboss.logging.BasicLogger;
4 | import org.jboss.logging.Logger;
5 | import org.jboss.logging.annotations.Cause;
6 | import org.jboss.logging.annotations.LogMessage;
7 | import org.jboss.logging.annotations.Message;
8 | import org.jboss.logging.annotations.MessageLogger;
9 |
10 | @MessageLogger(projectCode = "SRJWT", length = 5)
11 | interface JAXRSLogging extends BasicLogger {
12 | JAXRSLogging log = Logger.getMessageLogger(JAXRSLogging.class, JAXRSLogging.class.getPackage().getName());
13 |
14 | @LogMessage(level = Logger.Level.DEBUG)
15 | @Message(id = 10000, value = "Success")
16 | void success();
17 |
18 | @LogMessage(level = Logger.Level.DEBUG)
19 | @Message(id = 10001, value = "Unable to validate bearer token")
20 | void unableToValidateBearerToken(@Cause Throwable throwable);
21 |
22 | @LogMessage(level = Logger.Level.DEBUG)
23 | @Message(id = 10002, value = "Failed to resolve the key. Either corrupt or unavailable.")
24 | void noUsableKey();
25 |
26 | @LogMessage(level = Logger.Level.DEBUG)
27 | @Message(id = 10003, value = "EE Security is not in use, %s has been registered")
28 | void eeSecurityNotInUseButRegistered(String authenticationFilterName);
29 |
30 | @LogMessage(level = Logger.Level.DEBUG)
31 | @Message(id = 10004, value = "MP-JWT LoginConfig present, %s is enabled")
32 | void mpJWTLoginConfigPresent(String className);
33 |
34 | @LogMessage(level = Logger.Level.INFO)
35 | @Message(id = 10005, value = "LoginConfig not found on Application class, %s will not be enabled")
36 | void mpJWTLoginConfigNotFound(String className);
37 |
38 | @LogMessage(level = Logger.Level.DEBUG)
39 | @Message(id = 10006, value = "An invalid JWT was sent to an unauthenticated endpoint")
40 | void invalidJWTSentToUnauthenticatedEndpoint();
41 | }
42 |
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/src/main/java/io/smallrye/jwt/auth/jaxrs/JAXRSMessages.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.jaxrs;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.util.Collection;
5 |
6 | import org.jboss.logging.Messages;
7 | import org.jboss.logging.annotations.Message;
8 | import org.jboss.logging.annotations.MessageBundle;
9 | import org.jboss.logging.annotations.Transform;
10 |
11 | @MessageBundle(projectCode = "SRJWT", length = 5)
12 | interface JAXRSMessages {
13 | JAXRSMessages msg = Messages.getBundle(JAXRSMessages.class);
14 |
15 | @Message(id = 9000, value = "Duplicate MicroProfile JWT annotations found on %s. Expected at most 1 annotation, found: %d")
16 | IllegalStateException duplicateJWTAnnotationsFound(String annotationPlacementDescriptor,
17 | @Transform(Transform.TransformType.SIZE) Collection annotations);
18 | }
19 |
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/src/main/java/io/smallrye/jwt/auth/jaxrs/JWTSecurityContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.auth.jaxrs;
18 |
19 | import java.security.Principal;
20 |
21 | import jakarta.ws.rs.core.SecurityContext;
22 |
23 | import org.eclipse.microprofile.jwt.JsonWebToken;
24 |
25 | /**
26 | * A delegating JAX-RS SecurityContext prototype that provides access to the JWTCallerPrincipal
27 | * TODO
28 | */
29 | public class JWTSecurityContext implements SecurityContext {
30 | private SecurityContext delegate;
31 | private JsonWebToken principal;
32 |
33 | JWTSecurityContext(SecurityContext delegate, JsonWebToken principal) {
34 | this.delegate = delegate;
35 | this.principal = principal;
36 | }
37 |
38 | @Override
39 | public Principal getUserPrincipal() {
40 | return principal;
41 | }
42 |
43 | @Override
44 | public boolean isUserInRole(String role) {
45 | return principal.getGroups().contains(role);
46 | }
47 |
48 | @Override
49 | public boolean isSecure() {
50 | return delegate.isSecure();
51 | }
52 |
53 | @Override
54 | public String getAuthenticationScheme() {
55 | return delegate.getAuthenticationScheme();
56 | }
57 | }
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/src/main/java/io/smallrye/jwt/auth/jaxrs/RolesAllowedFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.auth.jaxrs;
18 |
19 | import static java.util.Arrays.asList;
20 |
21 | import java.util.HashSet;
22 | import java.util.Set;
23 |
24 | import jakarta.annotation.Priority;
25 | import jakarta.ws.rs.ForbiddenException;
26 | import jakarta.ws.rs.NotAuthorizedException;
27 | import jakarta.ws.rs.Priorities;
28 | import jakarta.ws.rs.container.ContainerRequestContext;
29 | import jakarta.ws.rs.container.ContainerRequestFilter;
30 | import jakarta.ws.rs.core.SecurityContext;
31 |
32 | /**
33 | * @author Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com
34 | *
35 | * Date: 6/12/18
36 | */
37 | @Priority(Priorities.AUTHORIZATION)
38 | public class RolesAllowedFilter implements ContainerRequestFilter {
39 |
40 | private final Set allowedRoles;
41 | private final boolean allRolesAllowed;
42 |
43 | public RolesAllowedFilter(String[] allowedRoles) {
44 | this.allowedRoles = new HashSet<>(asList(allowedRoles));
45 | this.allRolesAllowed = this.allowedRoles.stream().anyMatch("*"::equals);
46 | }
47 |
48 | @Override
49 | public void filter(ContainerRequestContext requestContext) {
50 | SecurityContext securityContext = requestContext.getSecurityContext();
51 | boolean isForbidden;
52 | if (allRolesAllowed) {
53 | isForbidden = securityContext.getUserPrincipal() == null;
54 | } else {
55 | isForbidden = allowedRoles.stream().noneMatch(securityContext::isUserInRole);
56 | }
57 | if (isForbidden) {
58 | if (requestContext.getSecurityContext().getUserPrincipal() == null) {
59 | throw new NotAuthorizedException("Bearer");
60 | } else {
61 | throw new ForbiddenException();
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/implementation/jwt-jaxrs/src/main/java/io/smallrye/jwt/auth/jaxrs/SmallRyeJWTAuthJaxRsFeature.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package io.smallrye.jwt.auth.jaxrs;
17 |
18 | import jakarta.ws.rs.core.Application;
19 | import jakarta.ws.rs.core.Context;
20 | import jakarta.ws.rs.core.Feature;
21 | import jakarta.ws.rs.core.FeatureContext;
22 |
23 | import org.eclipse.microprofile.auth.LoginConfig;
24 |
25 | /**
26 | * JAX-RS Feature to support JWT authentication and authorization filters, This feature must
27 | * be enabled by client applications by using the
28 | * {@link Application#getClasses()} method or via another feature.
29 | *
30 | * @author Michael Edgar {@literal }
31 | */
32 | public class SmallRyeJWTAuthJaxRsFeature implements Feature {
33 |
34 | @Context
35 | private Application restApplication;
36 |
37 | @Override
38 | public boolean configure(FeatureContext context) {
39 | boolean enabled = mpJwtEnabled();
40 |
41 | if (enabled) {
42 | context.register(JWTAuthorizationFilterRegistrar.class);
43 |
44 | context.register(JWTAuthenticationFilter.class);
45 |
46 | JAXRSLogging.log.mpJWTLoginConfigPresent(getClass().getSimpleName());
47 | } else {
48 | JAXRSLogging.log.mpJWTLoginConfigNotFound(getClass().getSimpleName());
49 | }
50 |
51 | return enabled;
52 | }
53 |
54 | boolean mpJwtEnabled() {
55 | boolean enabled = false;
56 |
57 | if (restApplication != null) {
58 | Class> applicationClass = restApplication.getClass();
59 |
60 | if (applicationClass.isAnnotationPresent(LoginConfig.class)) {
61 | LoginConfig config = applicationClass.getAnnotation(LoginConfig.class);
62 | enabled = "MP-JWT".equals(config.authMethod());
63 | }
64 | }
65 |
66 | return enabled;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/implementation/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | 4.0.0
20 |
21 |
22 | io.smallrye
23 | smallrye-jwt-parent
24 | 4.6.3-SNAPSHOT
25 |
26 |
27 | pom
28 | smallrye-jwt-implementation-parent
29 | SmallRye: MicroProfile JWT - Implementation Parent
30 |
31 |
32 | common
33 | jwt-auth
34 | jwt-jaxrs
35 | jwt-http-mechanism
36 | jwt-cdi-extension
37 | jwt-build
38 |
39 |
40 |
--------------------------------------------------------------------------------
/message-ranges.txt:
--------------------------------------------------------------------------------
1 | # This document is intended to establish the ranges for message IDs in the various sub-projects.
2 |
3 | # Range = owner
4 |
5 | 00000-00999 = smallrye-jwt [io.smallrye.jwt] (messages)
6 |
7 | 01000-01999 = smallrye-jwt [io.smallrye.jwt] (logging)
8 |
9 | 02000-02999 = smallrye-jwt [io.smallrye.jwt.config] (messages)
10 |
11 | 03000-03999 = smallrye-jwt [io.smallrye.jwt.config] (logging)
12 |
13 | 04000-04999 = smallrye-jwt [io.smallrye.jwt.build.spi] (messages)
14 |
15 | 05000-05999 = smallrye-jwt [io.smallrye.jwt.build.impl] (messages)
16 |
17 | 06000-06999 = smallrye-jwt [io.smallrye.jwt.auth] (logging)
18 |
19 | 07000-07999 = smallrye-jwt [io.smallrye.jwt.auth.principal] (messages)
20 |
21 | 08000-08999 = smallrye-jwt [io.smallrye.jwt.auth.principal] (logging)
22 |
23 | 09000-09999 = smallrye-jwt [io.smallrye.jwt.auth.jaxrs] (messages)
24 |
25 | 10000-10999 = smallrye-jwt [io.smallrye.jwt.auth.jaxrs] (logging)
26 |
27 | 11000-11999 = smallrye-jwt [io.smallrye.jwt.auth.mechanism] (logging)
28 |
29 | 12000-12999 = smallrye-jwt [io.smallrye.jwt.auth.cdi] (logging)
30 |
31 | 13000-13999 = smallrye-jwt [io.smallrye.jwt.auth.cdi] (messages)
32 |
33 | 14000-14999 =
34 |
35 | 15000-15999 =
36 |
37 | 16000-16999 =
38 |
39 | 17000-17999 =
40 |
41 | 18000-18999 =
42 |
43 | 19000-19999 =
--------------------------------------------------------------------------------
/release/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | io.smallrye
7 | smallrye-jwt-parent
8 | 4.6.3-SNAPSHOT
9 |
10 |
11 | smallrye-jwt-release
12 |
13 | Empty Release Project to Avoid Maven Bug
14 | Empty Release Project to Avoid Maven Bug
15 |
16 | pom
17 |
18 |
19 |
--------------------------------------------------------------------------------
/testsuite/basic/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 4.0.0
21 |
22 |
23 | io.smallrye
24 | smallrye-jwt-testsuite-parent
25 | 4.6.3-SNAPSHOT
26 |
27 |
28 | smallrye-jwt-testsuite-basic
29 |
30 | SmallRye: MicroProfile JWT Basic Testsuite
31 |
32 |
33 |
34 | org.junit.jupiter
35 | junit-jupiter
36 |
37 |
38 | io.smallrye
39 | smallrye-jwt
40 | test
41 |
42 |
43 | io.smallrye
44 | smallrye-jwt-build
45 | test
46 |
47 |
48 | jakarta.enterprise
49 | jakarta.enterprise.cdi-api
50 | test
51 |
52 |
53 |
54 |
55 | org.eclipse.microprofile.jwt
56 | microprofile-jwt-auth-tck
57 | test
58 |
59 |
60 | javax.inject
61 | javax.inject
62 |
63 |
64 |
65 |
66 | org.eclipse.microprofile.jwt
67 | microprofile-jwt-auth-tck
68 | test-jar
69 | test
70 |
71 |
72 | io.smallrye.config
73 | smallrye-config
74 |
75 |
76 | org.eclipse.parsson
77 | parsson
78 |
79 |
80 |
81 |
82 |
83 |
84 | org.apache.maven.plugins
85 | maven-surefire-plugin
86 |
87 | true
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/TestTokenRequireSub.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt;
2 |
3 | import static org.eclipse.microprofile.jwt.tck.TCKConstants.TEST_ISSUER;
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 | import static org.junit.jupiter.api.Assertions.assertNull;
6 | import static org.junit.jupiter.api.Assertions.assertThrows;
7 |
8 | import java.security.interfaces.RSAPublicKey;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | import org.eclipse.microprofile.jwt.JsonWebToken;
13 | import org.eclipse.microprofile.jwt.tck.util.SignatureAlgorithm;
14 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
15 | import org.junit.jupiter.api.Test;
16 |
17 | import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
18 | import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
19 | import io.smallrye.jwt.auth.principal.ParseException;
20 |
21 | class TestTokenRequireSub {
22 | @Test
23 | void defaultSubAvailable() throws Exception {
24 | Map timeClaims = new HashMap<>();
25 | String token = TokenUtils.signClaims("/Token1.json", SignatureAlgorithm.RS256, null, timeClaims);
26 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
27 | if (publicKey == null) {
28 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
29 | }
30 |
31 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
32 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
33 | JsonWebToken jwt = factory.parse(token, contextInfo);
34 | String sub = jwt.getSubject();
35 | assertEquals(sub, "24400320");
36 | }
37 |
38 | @Test
39 | void defaultSubNotAvailable() throws Exception {
40 | Map timeClaims = new HashMap<>();
41 | String token = TokenUtils.signClaims("/TokenSubPath.json", SignatureAlgorithm.RS256, null, timeClaims);
42 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
43 | if (publicKey == null) {
44 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
45 | }
46 |
47 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
48 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
49 | assertThrows(ParseException.class, () -> factory.parse(token, contextInfo));
50 | }
51 |
52 | @Test
53 | void noSubValidation() throws Exception {
54 | Map timeClaims = new HashMap<>();
55 | String token = TokenUtils.signClaims("/TokenSubPath.json", SignatureAlgorithm.RS256, null, timeClaims);
56 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
57 | if (publicKey == null) {
58 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
59 | }
60 |
61 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
62 | contextInfo.setRequireNamedPrincipal(false);
63 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
64 | JsonWebToken jwt = factory.parse(token, contextInfo);
65 | String sub = jwt.getSubject();
66 | assertNull(sub);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/TestTokenRequiredClaims.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt;
2 |
3 | import static java.util.stream.Collectors.toSet;
4 | import static org.eclipse.microprofile.jwt.tck.TCKConstants.TEST_ISSUER;
5 | import static org.junit.jupiter.api.Assertions.assertThrows;
6 | import static org.junit.jupiter.api.Assertions.assertTrue;
7 |
8 | import java.security.interfaces.RSAPublicKey;
9 | import java.util.Collections;
10 | import java.util.stream.Stream;
11 |
12 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
13 | import org.jose4j.jwt.consumer.InvalidJwtException;
14 | import org.junit.jupiter.api.Test;
15 |
16 | import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
17 | import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
18 | import io.smallrye.jwt.auth.principal.ParseException;
19 |
20 | class TestTokenRequiredClaims {
21 | @Test
22 | void base() throws Exception {
23 | String token = TokenUtils.signClaims("/Token1.json");
24 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
25 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
26 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
27 | factory.parse(token, contextInfo);
28 | }
29 |
30 | @Test
31 | void missingRequiredClaim() throws Exception {
32 | String token = TokenUtils.signClaims("/Token1.json");
33 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
34 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
35 | contextInfo.setRequiredClaims(Collections.singleton("something"));
36 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
37 |
38 | final ParseException exception = assertThrows(ParseException.class, () -> factory.parse(token, contextInfo));
39 | assertTrue(exception.getCause() instanceof InvalidJwtException);
40 | }
41 |
42 | @Test
43 | void missingRequiredClaims() throws Exception {
44 | String token = TokenUtils.signClaims("/Token1.json");
45 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
46 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
47 | contextInfo.setRequiredClaims(Stream.of("something", "else").collect(toSet()));
48 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
49 |
50 | final ParseException exception = assertThrows(ParseException.class, () -> factory.parse(token, contextInfo));
51 | assertTrue(exception.getCause() instanceof InvalidJwtException);
52 | }
53 |
54 | @Test
55 | void requiredClaims() throws Exception {
56 | String token = TokenUtils.signClaims("/Token1.json");
57 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
58 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
59 | contextInfo.setRequiredClaims(Stream.of("roles", "customObject", "customDoubleArray").collect(toSet()));
60 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
61 | factory.parse(token, contextInfo);
62 | }
63 |
64 | @Test
65 | void requiredAndMissingClaims() throws Exception {
66 | String token = TokenUtils.signClaims("/Token1.json");
67 | RSAPublicKey publicKey = TokenUtils.readPublicKey("/publicKey.pem");
68 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
69 | contextInfo.setRequiredClaims(
70 | Stream.of("roles", "customObject", "customDoubleArray", "something").collect(toSet()));
71 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
72 |
73 | final ParseException exception = assertThrows(ParseException.class, () -> factory.parse(token, contextInfo));
74 | assertTrue(exception.getCause() instanceof InvalidJwtException);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/TestTokenWithGroupsPath2.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt;
18 |
19 | import static org.eclipse.microprofile.jwt.tck.TCKConstants.TEST_ISSUER;
20 | import static org.junit.jupiter.api.Assertions.assertEquals;
21 | import static org.junit.jupiter.api.Assertions.assertTrue;
22 |
23 | import java.security.PublicKey;
24 | import java.util.HashMap;
25 | import java.util.Map;
26 | import java.util.Set;
27 |
28 | import org.eclipse.microprofile.jwt.JsonWebToken;
29 | import org.eclipse.microprofile.jwt.tck.util.SignatureAlgorithm;
30 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
31 | import org.junit.jupiter.api.BeforeAll;
32 | import org.junit.jupiter.api.Test;
33 |
34 | import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
35 | import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
36 |
37 | /**
38 | * A more extensive test of the how the token JSON content types are mapped
39 | * to values via the JsonWebToken implementation.
40 | */
41 | class TestTokenWithGroupsPath2 {
42 | /** The test generated JWT token string */
43 | private static String token;
44 | /** The /publicKey.pem instance */
45 | private static PublicKey publicKey;
46 |
47 | @BeforeAll
48 | static void generateToken() throws Exception {
49 | Map timeClaims = new HashMap<>();
50 | token = TokenUtils.signClaims("/TokenGroupsPath2.json", SignatureAlgorithm.RS256, null, timeClaims);
51 | publicKey = TokenUtils.readPublicKey("/publicKey.pem");
52 | if (publicKey == null) {
53 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
54 | }
55 | }
56 |
57 | @Test
58 | void groupsObject() throws Exception {
59 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
60 | contextInfo.setGroupsPath("groups/array");
61 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
62 | JsonWebToken jwt = factory.parse(token, contextInfo);
63 | Set groups = jwt.getGroups();
64 | assertEquals(groups.size(), 1);
65 | assertTrue(groups.contains("microprofile_jwt_user"));
66 | }
67 |
68 | @Test
69 | void groupsString() throws Exception {
70 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
71 | contextInfo.setGroupsPath("groups/groups");
72 | contextInfo.setGroupsSeparator(",");
73 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
74 | JsonWebToken jwt = factory.parse(token, contextInfo);
75 | Set groups = jwt.getGroups();
76 | assertEquals(groups.size(), 2);
77 | assertTrue(groups.contains("microprofile_jwt_user1"));
78 | assertTrue(groups.contains("microprofile_jwt_user2"));
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/TestTokenWithGroupsString.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt;
18 |
19 | import static org.eclipse.microprofile.jwt.tck.TCKConstants.TEST_ISSUER;
20 | import static org.junit.jupiter.api.Assertions.assertEquals;
21 | import static org.junit.jupiter.api.Assertions.assertTrue;
22 |
23 | import java.security.PublicKey;
24 | import java.util.HashMap;
25 | import java.util.Map;
26 | import java.util.Set;
27 |
28 | import org.eclipse.microprofile.jwt.JsonWebToken;
29 | import org.eclipse.microprofile.jwt.tck.util.SignatureAlgorithm;
30 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
31 | import org.junit.jupiter.api.BeforeAll;
32 | import org.junit.jupiter.api.Test;
33 |
34 | import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
35 | import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
36 |
37 | /**
38 | * A more extensive test of the how the token JSON content types are mapped
39 | * to values via the JsonWebToken implementation.
40 | */
41 | class TestTokenWithGroupsString {
42 | /** The test generated JWT token string */
43 | private static String token;
44 | /** The /publicKey.pem instance */
45 | private static PublicKey publicKey;
46 |
47 | @BeforeAll
48 | static void generateToken() throws Exception {
49 | Map timeClaims = new HashMap<>();
50 | token = TokenUtils.signClaims("/TokenGroupsString.json", SignatureAlgorithm.RS256, null, timeClaims);
51 | publicKey = TokenUtils.readPublicKey("/publicKey.pem");
52 | if (publicKey == null) {
53 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
54 | }
55 | }
56 |
57 | @Test
58 | void groupsString() throws Exception {
59 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
60 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
61 | JsonWebToken jwt = factory.parse(token, contextInfo);
62 | Set groups = jwt.getGroups();
63 | assertEquals(groups.size(), 2);
64 | assertTrue(groups.contains("role1"));
65 | assertTrue(groups.contains("role2"));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/TestTokenWithSubPath.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt;
2 |
3 | import static org.eclipse.microprofile.jwt.tck.TCKConstants.TEST_ISSUER;
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 | import static org.junit.jupiter.api.Assertions.assertNull;
6 |
7 | import java.security.PublicKey;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | import org.eclipse.microprofile.jwt.JsonWebToken;
12 | import org.eclipse.microprofile.jwt.tck.util.SignatureAlgorithm;
13 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
14 | import org.junit.jupiter.api.BeforeAll;
15 | import org.junit.jupiter.api.Test;
16 |
17 | import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
18 | import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
19 |
20 | class TestTokenWithSubPath {
21 | private static String token;
22 | private static PublicKey publicKey;
23 |
24 | @BeforeAll
25 | static void generateToken() throws Exception {
26 | Map timeClaims = new HashMap<>();
27 | token = TokenUtils.signClaims("/TokenSubPath.json", SignatureAlgorithm.RS256, null, timeClaims);
28 | publicKey = TokenUtils.readPublicKey("/publicKey.pem");
29 | if (publicKey == null) {
30 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
31 | }
32 | }
33 |
34 | @Test
35 | void subClaimIsAvailableOnPath() throws Exception {
36 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
37 | contextInfo.setSubjectPath("realm/access/sub/principal");
38 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
39 | JsonWebToken jwt = factory.parse(token, contextInfo);
40 | String sub = jwt.getSubject();
41 | assertEquals(sub, "microprofile_jwt_principal");
42 | }
43 |
44 | @Test
45 | void subClaimIsAvailableOnPathWithNamespace() throws Exception {
46 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
47 | contextInfo.setSubjectPath("realm/\"https://idp/access\"/sub/principal");
48 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
49 | JsonWebToken jwt = factory.parse(token, contextInfo);
50 | String sub = jwt.getSubject();
51 | assertEquals(sub, "namespace_microprofile_jwt_principal");
52 | }
53 |
54 | @Test
55 | void subClaimIsNotAvailableOnTooDeepPath() throws Exception {
56 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
57 | contextInfo.setRequireNamedPrincipal(false);
58 | contextInfo.setSubjectPath("realm/access/sub/principal/5");
59 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
60 | JsonWebToken jwt = factory.parse(token, contextInfo);
61 | assertNull(jwt.getSubject());
62 | }
63 |
64 | @Test
65 | void subClaimIsNotAvailableIfClaimIsNotString() throws Exception {
66 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
67 | contextInfo.setRequireNamedPrincipal(false);
68 | contextInfo.setSubjectPath("realm/access/sub");
69 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
70 | JsonWebToken jwt = factory.parse(token, contextInfo);
71 | assertNull(jwt.getSubject());
72 | }
73 |
74 | @Test
75 | void subClaimIsNotAvailableOnWrongPath() throws Exception {
76 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
77 | contextInfo.setRequireNamedPrincipal(false);
78 | contextInfo.setSubjectPath("realm/access/user/principal");
79 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
80 | JsonWebToken jwt = factory.parse(token, contextInfo);
81 | assertNull(jwt.getSubject());
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/TestTokenWithoutGroupsClaim.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt;
18 |
19 | import static org.eclipse.microprofile.jwt.tck.TCKConstants.TEST_ISSUER;
20 | import static org.junit.jupiter.api.Assertions.assertEquals;
21 | import static org.junit.jupiter.api.Assertions.assertTrue;
22 |
23 | import java.security.PublicKey;
24 | import java.util.HashMap;
25 | import java.util.Map;
26 | import java.util.Set;
27 |
28 | import org.eclipse.microprofile.jwt.JsonWebToken;
29 | import org.eclipse.microprofile.jwt.tck.util.SignatureAlgorithm;
30 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
31 | import org.junit.jupiter.api.BeforeAll;
32 | import org.junit.jupiter.api.Test;
33 |
34 | import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
35 | import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
36 |
37 | /**
38 | * A more extensive test of the how the token JSON content types are mapped
39 | * to values via the JsonWebToken implementation.
40 | */
41 | class TestTokenWithoutGroupsClaim {
42 | /** The test generated JWT token string */
43 | private static String token;
44 | /** The /publicKey.pem instance */
45 | private static PublicKey publicKey;
46 |
47 | @BeforeAll
48 | static void generateToken() throws Exception {
49 | Map timeClaims = new HashMap<>();
50 | token = TokenUtils.signClaims("/TokenNoGroups.json", SignatureAlgorithm.RS256, null, timeClaims);
51 | publicKey = TokenUtils.readPublicKey("/publicKey.pem");
52 | if (publicKey == null) {
53 | throw new IllegalStateException("Failed to load /publicKey.pem resource");
54 | }
55 | }
56 |
57 | @Test
58 | void defaultGroupsClaimIsAvailable() throws Exception {
59 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
60 | contextInfo.setDefaultGroupsClaim("microprofile_jwt_user");
61 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
62 | JsonWebToken jwt = factory.parse(token, contextInfo);
63 | Set groups = jwt.getGroups();
64 | assertEquals(1, groups.size());
65 | assertTrue(groups.contains("microprofile_jwt_user"));
66 | }
67 |
68 | @Test
69 | void groupsClaimIsNotAvailable() throws Exception {
70 | JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(publicKey, TEST_ISSUER);
71 | JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
72 | JsonWebToken jwt = factory.parse(token, contextInfo);
73 | assertTrue(jwt.getGroups().isEmpty());
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/AwsAlbTokenTest.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.principal;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertEquals;
4 |
5 | import java.util.Set;
6 |
7 | import org.eclipse.microprofile.jwt.JsonWebToken;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import io.smallrye.jwt.algorithm.SignatureAlgorithm;
11 |
12 | public class AwsAlbTokenTest {
13 |
14 | private static final String AWS_ALB_KEY = "-----BEGIN PUBLIC KEY-----"
15 | + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjPHY1j9umvc8nZEswOzs+lPpLKLn"
16 | + "qCBqvyZGJfBlXapmtGiqYEwpIqh/lZdkr4wDii7CP1DzIUSHONbc+jufiQ=="
17 | + "-----END PUBLIC KEY-----";
18 |
19 | private static final String JWT = "eyJ0eXAiOiJKV1QiLCJraWQiOiJjMmY4MGM4Yi1jMDVjLTQwNjgtYWYxNC0xNzI5OWY3ODk2YjEiLCJhbGciOiJFUzI1NiIsImlzcyI6Imh0dHBzOi8vY29nbml0by1pZHAuZXUtY2VudHJhbC0xLmFtYXpvbmF3cy5jb20vZXUtY2VudHJhbC0xX015UnJPQ0hRdyIsImNsaWVudCI6IjRmbXZodDIydGpyZ2Q3ZDNrM3RnaHR0Y3Q3Iiwic2lnbmVyIjoiYXJuOmF3czplbGFzdGljbG9hZGJhbGFuY2luZzpldS1jZW50cmFsLTE6MTk3MjgwOTU4MjI1OmxvYWRiYWxhbmNlci9hcHAvZWNzLXdpdGgtY29nbml0by1sYi82Mjg0YmU2NWI4MjdjNTk4IiwiZXhwIjoxNjg3NzQ4MDQ1fQ=="
20 | + ".eyJzdWIiOiIyM2Q0OThiMi0zMDMxLTcwZDItOGExNS00OWRkODg2YTA4N2IiLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJlbWFpbCI6ImR1a2VAc3VuLmNvbSIsInVzZXJuYW1lIjoiZHVrZSIsImV4cCI6MTY4Nzc0ODA0NSwiaXNzIjoiaHR0cHM6Ly9jb2duaXRvLWlkcC5ldS1jZW50cmFsLTEuYW1hem9uYXdzLmNvbS9ldS1jZW50cmFsLTFfTXlSck9DSFF3In0="
21 | + ".Jd7RXHsOj8vw2b4irZCxxWO-0UQBZ2X1bRNsKZ9D02JWJaNOvOnrV8T-qrcmWNpl7MjNhsGSm1C4e2rAjaF0jg==";
22 |
23 | @Test
24 | void parseToken() throws Exception {
25 | JWTAuthContextInfo config = new JWTAuthContextInfo();
26 | config.setPublicKeyContent(AWS_ALB_KEY);
27 | config.setIssuedBy("https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_MyRrOCHQw");
28 | // ES256 is used to sign
29 | config.setSignatureAlgorithm(Set.of(SignatureAlgorithm.ES256));
30 | // Token has no `iat`
31 | config.setMaxTimeToLiveSecs(-1L);
32 | // It has already expired so for the test to pass the clock skew has to be set
33 | config.setClockSkew(Integer.MAX_VALUE);
34 | JWTParser parser = new DefaultJWTParser(config);
35 | JsonWebToken jwt = parser.parse(JWT);
36 | assertEquals("duke", jwt.getClaim("username"));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/DefaultJWTCallerPrincipalTest.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.auth.principal;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 | import static org.junit.jupiter.api.Assertions.assertNotNull;
6 |
7 | import java.security.interfaces.RSAPublicKey;
8 | import java.util.Set;
9 |
10 | import org.eclipse.microprofile.jwt.Claims;
11 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
12 | import org.jose4j.jwt.JwtClaims;
13 | import org.jose4j.jwt.consumer.JwtContext;
14 | import org.junit.jupiter.api.BeforeEach;
15 | import org.junit.jupiter.api.Test;
16 |
17 | class DefaultJWTCallerPrincipalTest {
18 |
19 | private static final String TCK_TOKEN1_AUD = "s6BhdRkqt3";
20 |
21 | RSAPublicKey publicKey;
22 | DefaultJWTTokenParser parser;
23 | JWTAuthContextInfo config;
24 | JwtContext context;
25 |
26 | @BeforeEach
27 | void setUp() throws Exception {
28 | publicKey = TokenUtils.readPublicKey("/publicKey.pem");
29 | parser = new DefaultJWTTokenParser();
30 | config = new JWTAuthContextInfo(publicKey, "https://server.example.com");
31 | context = parser.parse(TokenUtils.signClaims("/Token1.json"), config);
32 | }
33 |
34 | @Test
35 | void getAudience() {
36 | DefaultJWTCallerPrincipal principal = new DefaultJWTCallerPrincipal(context.getJwtClaims());
37 | Set audience = principal.getAudience();
38 | assertNotNull(audience);
39 | assertEquals(1, audience.size());
40 | assertArrayEquals(new String[] { TCK_TOKEN1_AUD }, audience.toArray(new String[0]));
41 | }
42 |
43 | @Test
44 | void getAudienceClaimValue() {
45 | DefaultJWTCallerPrincipal principal = new DefaultJWTCallerPrincipal(context.getJwtClaims());
46 | @SuppressWarnings("unchecked")
47 | Set audience = (Set) principal.getClaimValue(Claims.aud.name());
48 | assertNotNull(audience);
49 | assertEquals(1, audience.size());
50 | assertArrayEquals(new String[] { TCK_TOKEN1_AUD }, audience.toArray(new String[0]));
51 | }
52 |
53 | @Test
54 | void getAudienceClaim() {
55 | DefaultJWTCallerPrincipal principal = new DefaultJWTCallerPrincipal(context.getJwtClaims());
56 | Set audience = principal.getClaim(Claims.aud.name());
57 | assertNotNull(audience);
58 | assertEquals(1, audience.size());
59 | assertArrayEquals(new String[] { TCK_TOKEN1_AUD }, audience.toArray(new String[0]));
60 | }
61 |
62 | @Test
63 | void claimsWithDecimalValues() {
64 | Double exp = 1311281970.5;
65 | Double iat = 1311280970.5;
66 |
67 | final JwtClaims claims = context.getJwtClaims();
68 | claims.setClaim(Claims.exp.name(), exp);
69 | claims.setClaim(Claims.iat.name(), iat);
70 | DefaultJWTCallerPrincipal principal = new DefaultJWTCallerPrincipal(claims);
71 |
72 | Long expClaim = principal.getExpirationTime();
73 | Long iatClaim = principal.getIssuedAtTime();
74 |
75 | assertNotNull(expClaim);
76 | assertNotNull(iatClaim);
77 |
78 | assertEquals(exp.longValue(), expClaim);
79 | assertEquals(iat.longValue(), iatClaim);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/KeyLocationResolverKeyContentTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.auth.principal;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertNotNull;
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 | import static org.junit.jupiter.api.Assertions.assertTrue;
22 |
23 | import java.io.BufferedReader;
24 | import java.io.InputStream;
25 | import java.io.InputStreamReader;
26 | import java.io.StringWriter;
27 | import java.nio.charset.StandardCharsets;
28 | import java.security.PrivateKey;
29 | import java.util.Base64;
30 |
31 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
32 | import org.jose4j.lang.UnresolvableKeyException;
33 | import org.junit.jupiter.api.Test;
34 |
35 | import io.smallrye.jwt.config.JWTAuthContextInfoProvider;
36 | import io.smallrye.jwt.util.KeyUtils;
37 |
38 | class KeyLocationResolverKeyContentTest {
39 | @Test
40 | void verifyWithPemKey() throws Exception {
41 | verifyToken(null, readKeyContent("/publicKey.pem"));
42 | }
43 |
44 | @Test
45 | void verifyWithInvalidPemKey() throws Exception {
46 | PrivateKey privateKey = TokenUtils.readPrivateKey("/privateKey.pem");
47 | String token = TokenUtils.signClaims(privateKey, null, "/Token1.json", null, null);
48 | JWTAuthContextInfoProvider provider = JWTAuthContextInfoProvider.createWithKey("invalidkey",
49 | "https://server.example.com");
50 | JWTAuthContextInfo contextInfo = provider.getContextInfo();
51 | ParseException thrown = assertThrows(ParseException.class, () -> new DefaultJWTTokenParser().parse(token, contextInfo),
52 | "UnresolvableKeyException is expected");
53 | assertTrue(thrown.getCause() instanceof UnresolvableKeyException);
54 | }
55 |
56 | @Test
57 | void verifyWithPemKeyTrimmed() throws Exception {
58 | verifyToken(null, KeyUtils.removePemKeyBeginEnd(readKeyContent("/publicKey.pem")));
59 | }
60 |
61 | @Test
62 | void verifyWithJwkKey() throws Exception {
63 | verifyToken(null,
64 | Base64.getUrlEncoder().encodeToString(readKeyContent("/publicKey.jwk").getBytes(StandardCharsets.UTF_8)));
65 | }
66 |
67 | @Test
68 | void verifyWithJwkKeySet() throws Exception {
69 | verifyToken("key1",
70 | Base64.getUrlEncoder().encodeToString(readKeyContent("/publicKeySet.jwk").getBytes(StandardCharsets.UTF_8)));
71 | }
72 |
73 | private void verifyToken(String kid, String publicKey) throws Exception {
74 | PrivateKey privateKey = TokenUtils.readPrivateKey("/privateKey.pem");
75 | String token = TokenUtils.signClaims(privateKey, kid, "/Token1.json", null, null);
76 | JWTAuthContextInfoProvider provider = JWTAuthContextInfoProvider.createWithKey(publicKey,
77 | "https://server.example.com");
78 | JWTAuthContextInfo contextInfo = provider.getContextInfo();
79 | assertNotNull(new DefaultJWTTokenParser().parse(token, contextInfo));
80 | }
81 |
82 | private String readKeyContent(String keyLocation) throws Exception {
83 | InputStream is = KeyUtils.class.getResourceAsStream(keyLocation);
84 | StringWriter contents = new StringWriter();
85 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
86 | String line = null;
87 | while ((line = reader.readLine()) != null) {
88 | contents.write(line);
89 | }
90 | }
91 | return contents.toString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/java/io/smallrye/jwt/auth/principal/KeyStoreLocationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Red Hat, Inc, and individual contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 | package io.smallrye.jwt.auth.principal;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertEquals;
20 | import static org.junit.jupiter.api.Assertions.assertNotNull;
21 |
22 | import java.security.KeyStore;
23 | import java.security.PrivateKey;
24 | import java.security.PublicKey;
25 | import java.util.Optional;
26 |
27 | import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
28 | import org.jose4j.jwt.JwtClaims;
29 | import org.junit.jupiter.api.Test;
30 |
31 | import io.smallrye.jwt.config.JWTAuthContextInfoProvider;
32 | import io.smallrye.jwt.util.KeyUtils;
33 |
34 | class KeyStoreLocationTest {
35 | @Test
36 | void verifyToken() throws Exception {
37 | KeyStore keyStore = KeyUtils.loadKeyStore("server-keystore.jks", "password", Optional.empty(), Optional.empty());
38 | PrivateKey signingKey = (PrivateKey) keyStore.getKey("server", "password".toCharArray());
39 | String jwt = TokenUtils.signClaims(signingKey, null, "/Token1.json");
40 |
41 | JWTAuthContextInfoProvider provider = JWTAuthContextInfoProvider.createWithKeyStoreLocation("server-keystore.jks",
42 | Optional.of("password"), Optional.of("server"), Optional.empty(),
43 | "https://server.example.com");
44 | JwtClaims claims = new DefaultJWTTokenParser().parse(jwt, provider.getContextInfo()).getJwtClaims();
45 | assertNotNull(claims);
46 | assertEquals("https://server.example.com", claims.getIssuer());
47 | }
48 |
49 | @Test
50 | void decryptToken() throws Exception {
51 | KeyStore keyStore = KeyUtils.loadKeyStore("server-keystore.jks", "password", Optional.empty(), Optional.empty());
52 | PublicKey encryptionKey = keyStore.getCertificate("server").getPublicKey();
53 | String jwt = TokenUtils.encryptClaims(encryptionKey, null, "/Token1.json");
54 |
55 | JWTAuthContextInfoProvider provider = JWTAuthContextInfoProvider.createWithKeyStoreLocation("server-keystore.jks",
56 | Optional.of("password"), Optional.empty(), Optional.of("server"),
57 | "https://server.example.com");
58 | JwtClaims claims = new DefaultJWTTokenParser().parse(jwt, provider.getContextInfo()).getJwtClaims();
59 | assertNotNull(claims);
60 | assertEquals("https://server.example.com", claims.getIssuer());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/Token1.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969,
11 | "roles": [
12 | "Echoer"
13 | ],
14 | "groups": [
15 | "Echoer",
16 | "Tester",
17 | "group1",
18 | "group2"
19 | ],
20 | "customString": "customStringValue",
21 | "customInteger": 123456789,
22 | "customDouble": 3.141592653589793,
23 | "customStringArray": [
24 | "value0",
25 | "value1",
26 | "value2"
27 | ],
28 | "customIntegerArray": [
29 | 0,
30 | 1,
31 | 2,
32 | 3
33 | ],
34 | "customDoubleArray": [
35 | 0.1,
36 | 1.1,
37 | 2.2,
38 | 3.3,
39 | 4.4
40 | ],
41 | "customObject": {
42 | "my-service": {
43 | "groups": [
44 | "group1",
45 | "group2"
46 | ],
47 | "roles": [
48 | "role-in-my-service"
49 | ]
50 | },
51 | "service-B": {
52 | "roles": [
53 | "role-in-B"
54 | ]
55 | },
56 | "service-C": {
57 | "groups": [
58 | "groupC",
59 | "web-tier"
60 | ]
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/TokenGroupsPath.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969,
11 | "realm": {
12 | "access": {
13 | "groups": {
14 | "array": [
15 | "microprofile_jwt_user"
16 | ]
17 | },
18 | "https://idp/groups": {
19 | "array": [
20 | "namespace_microprofile_jwt_user"
21 | ]
22 | }
23 | }
24 | },
25 | "scope": "read write",
26 | "auth": "read,write"
27 | }
28 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/TokenGroupsPath2.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969,
11 | "groups": {
12 | "array": [
13 | "microprofile_jwt_user"
14 | ],
15 | "groups":"microprofile_jwt_user1,microprofile_jwt_user2"
16 | },
17 | "scope": "read write",
18 | "auth": "read,write"
19 | }
20 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/TokenGroupsString.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969,
11 | "groups": "role1 role2",
12 | "scope": "read write",
13 | "auth": "read,write"
14 | }
15 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/TokenNoGroups.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "upn": "jdoe@example.com",
6 | "preferred_username": "jdoe",
7 | "aud": "s6BhdRkqt3",
8 | "exp": 1311281970,
9 | "iat": 1311280970,
10 | "auth_time": 1311280969
11 | }
12 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/TokenSubPath.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "https://server.example.com",
3 | "jti": "a-123",
4 | "aud": "s6BhdRkqt3",
5 | "exp": 1311281970,
6 | "iat": 1311280970,
7 | "auth_time": 1311280969,
8 | "realm": {
9 | "access": {
10 | "sub": {
11 | "principal": "microprofile_jwt_principal"
12 | }
13 | },
14 | "https://idp/access": {
15 | "sub": {
16 | "principal": "namespace_microprofile_jwt_principal"
17 | }
18 | }
19 | },
20 | "groups": [
21 | "Echoer",
22 | "Tester",
23 | "group1",
24 | "group2"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/certificate.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC9DCCAdygAwIBAgIJAO0Y7B7dV9KpMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV
3 | BAMMBHRlc3QwHhcNMjAwODI1MTIzOTA1WhcNMjEwODI1MTIzOTA1WjAPMQ0wCwYD
4 | VQQDDAR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsl8Cqii/
5 | 4UFg5Lq3R8kZ//Wmapq4KQn4k+foEOymfUbw44E6pCU+iCK0RbyKXgTMErMN3ZFD
6 | xpoDdSeEDoS2kdlRF4XNtFG8RW6+h1wLJGRj7gi9bc0Vg5CzTGWhDvI6oT23KtUa
7 | OBjIWknZtLAR5nEJ7vMADq3QKMHcxofx1GmmAQ2NDmVQJvTfM8wV02oZ2vX6yQjB
8 | 6t3vbMyIr+h2GU8teu9v/oUf9A9R2Pm6qULSZ80qyo5BXlwwG2D4HsGCxCdg5PqK
9 | Oi9SOkvlE65eBUR8NXxwHdou+SQ/ry//MPwLSpHo9AggVEmSYlfigyVo5w1FUVo6
10 | uYUG/abuKhCSoQIDAQABo1MwUTAdBgNVHQ4EFgQUcDgMETNCuUuEGWzKoXjrvS8+
11 | kQAwHwYDVR0jBBgwFoAUcDgMETNCuUuEGWzKoXjrvS8+kQAwDwYDVR0TAQH/BAUw
12 | AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAH0o4kU37vc7OR/+fPQJdrBQqQaukq5ri
13 | yuMSTrU1vSizEXpd0RFE8moSks6+Vh4mEzU7zLAU54N6glcGItEmBko5xgTuQRgd
14 | b0LtR7Bu28QKfRRJxZ9GnGxinDPtFPD+7oTXZfI2Ed/RAuVlbppEBr2Pr2eO9B1x
15 | fgYJNwA1K/XA38G7njxQ/wcpgOp/iFdV7dyR6CyAtwkD92sMnEZKPVz3trBT9DFM
16 | 5mynDFn9PHYVB7R5mUjIc7C9yskHGIsqqSBAfsxUqKfCS2NlWjn4+JZ8BYPLgy6X
17 | hlGxh5zhvJPoT6J9+gA5l1Z2xMXI08ym8quIIUJNoYovSf8x4bXVjQ==
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/decryptPrivateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "n":"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ",
4 | "e":"AQAB",
5 | "d":"AvIDTlsK_priQLTwEQf5IVf2Xl638Q7dHdXyDC-oAAPmv1GcqRVH7Wm5oAPW_CZQfWhV55WRVaJzP8AhksyD5NcslH79hQZT4NT6xgApGYecrvmseuZ4dfR-e1cxXTRNBxaoXvwSiv4LuOPHmC8XGX712AhOoCGKiZp1WFqqkKwTpkgJEApJFVb-XRIKQa0YaRKpJsJ534pLMwTh7LoPLM4BCaBVbRfHzH2H5L3TSJP718kyCuxg3z2p9Y7zIOLTmgFdeR0_kd_xKUFZ2ByN3SKlC0IWlLUSiMPsGYExRpZTMZHKyD939gv-2_Z-bOYfKlYNIvAmQH_8CcX2I039LQ",
6 | "p":"104AjPaxZoi_BiMBODlChnZOvRJT071PdkeZ283uyrdW8qqKD9q8FTMgUXzKoboHtUiHbJbLOobPmPDh93839rq7dTdCNzNVOuLmE-V3_bmaShdzvxEIazwPf6AvjbEZAc-zu2RS4SNkp1LbzgSl9nINSlF7t6Lkl6T28PYULys",
7 | "q":"om5ooyzxa4ZJ-dU0ODsEb-Bmz6xwb27xF9aEhBYJprHeoNs2QM1D64_A39weD9MYwBux4-ivshCJ0dVKEbDujJRLnzf-ssrasA6CFyaaCT4DKtq1oWb9rcG-2LQd5Bm9PttrUrSUNqitr085IYikaLEz7UU6gtXPoC8UOcJ4cSc",
8 | "dp":"DeWE95Q8oweUfMrpmz1m49LjBiUWsAX6CQJaFevWy9LFk-gZ_Sf7F8sy_M93LLUbJkJGK2YYO_DTmWWC0Dyv2gb3bntglLuFdsWKYCJhekjugnW9DMoGpxU7Utt99kFGAe3sBd5V0x47sukQMt3t8FgwL2nO-G1VH8yP-8GGT_0",
9 | "dq":"TGBeE1wuqMCcSD1YMJiPnYuGzF_o_nzMIMldxj4Wi6tXY4uwFwhtx3Xw21JFUGuSV8KuAtyGwNPF-kSwb2Eiyjdw140c1jVMXzxzLy-XfoEKPDxa62niHrHba0pGQ9tWgRfrfxgqGQl3odc-peX6aL_qCsdim-KtnkSE3iPzPkE",
10 | "qi":"Jzp5KnT24y0wOoPUn_11S3ZcYl0i03dkaH4c5zR02G1MJG9K017juurx2aXVTctOzrj7O226EUiL1Qbq3QtnWFDDGY6vNZuqzJM7AMXsvp1djq_6fEVhxCIOgfJbmhb3mkG82rxn4et9o_TNr6mvEmHzG15sHbvZbAnn4GeqToY"
11 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/ecPrivateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"EC",
3 | "crv":"P-256",
4 | "x":"weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ",
5 | "y":"e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck",
6 | "d":"VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw",
7 | "kid": "eckey"
8 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/ecPrivateKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgvhj6xtHJanL3yBYt
3 | vmaLQ+ZlbO/zu66oWFYjQOxfpGahRANCAATDgeiG/A6PbUUFATU+sk4CU9FAzJaK
4 | aZcf2sgdrtgxNaLGRI1IWWu/fpApXBpu/Xl9Kv0BS5awPfTIZMzcujLS
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/ecPublicKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw4HohvwOj21FBQE1PrJOAlPRQMyW
3 | immXH9rIHa7YMTWixkSNSFlrv36QKVwabv15fSr9AUuWsD30yGTM3Loy0g==
4 | -----END PUBLIC KEY-----
5 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/edEcPrivateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"OKP",
3 | "crv":"Ed25519",
4 | "d":"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
5 | "x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
6 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/edEcPublicKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"OKP",
3 | "crv":"Ed25519",
4 | "x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
5 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/encryptPublicKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "n":"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ",
4 | "e":"AQAB"
5 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/privateKey2.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyXwKqKL/hQWDk
3 | urdHyRn/9aZqmrgpCfiT5+gQ7KZ9RvDjgTqkJT6IIrRFvIpeBMwSsw3dkUPGmgN1
4 | J4QOhLaR2VEXhc20UbxFbr6HXAskZGPuCL1tzRWDkLNMZaEO8jqhPbcq1Ro4GMha
5 | Sdm0sBHmcQnu8wAOrdAowdzGh/HUaaYBDY0OZVAm9N8zzBXTahna9frJCMHq3e9s
6 | zIiv6HYZTy1672/+hR/0D1HY+bqpQtJnzSrKjkFeXDAbYPgewYLEJ2Dk+oo6L1I6
7 | S+UTrl4FRHw1fHAd2i75JD+vL/8w/AtKkej0CCBUSZJiV+KDJWjnDUVRWjq5hQb9
8 | pu4qEJKhAgMBAAECggEAJvBs4X7B3MfsAiLszgQN4/3ZlZ4vI+5kUM2osMEo22J4
9 | RgI5Lgpfa1LALhUp07qSXmauWTdUJ3AJ3zKANrcsMAzUEiGItZu+UR4LA/vJBunP
10 | kvBfgi/qSW12ZvAsx9mDiR2y9evNrH9khalnmHVzgu4ccAimc43oSm1/5+tXlLoZ
11 | 1QK/FohxBxAshtuDHGs8yKUL0jpv7dOrjhCj2ibmPYe6AUk9F61sVWO0/i0Q8UAO
12 | cYT3L5nCS5WnLhdCdYpIJJ7xl2PrVE/BAD+JEG5uCOYfVeYh+iCZVfpX17ryfNNU
13 | aBtyxKEGVtHbje3mO86mYN3noaS0w/zpUjBPgV+KEQKBgQDsp6VTmDIqHFTp2cC2
14 | yrDMxRznif92EGv7ccJDZtbTC37mAuf2J7x5b6AiE1EfxEXyGYzSk99sCns+GbL1
15 | EHABUt5pimDCl33b6XvuccQNpnJ0MfM5eRX9Ogyt/OKdDRnQsvrTPNCWOyJjvG01
16 | HQM4mfxaBBnxnvl5meH2pyG/ZQKBgQDA87DnyqEFhTDLX5c1TtwHSRj2xeTPGKG0
17 | GyxOJXcxR8nhtY9ee0kyLZ14RytnOxKarCFgYXeG4IoGEc/I42WbA4sq88tZcbe4
18 | IJkdX0WLMqOTdMrdx9hMU1ytKVUglUJZBVm7FaTQjA+ArMwqkXAA5HBMtArUsfJK
19 | Ut3l0hMIjQKBgQDS1vmAZJQs2Fj+jzYWpLaneOWrk1K5yR+rQUql6jVyiUdhfS1U
20 | LUrJlh3Avh0EhEUc0I6Z/YyMITpztUmu9BoV09K7jMFwHK/RAU+cvFbDIovN4cKk
21 | bbCdjt5FFIyBB278dLjrAb+EWOLmoLVbIKICB47AU+8ZSV1SbTrYGUcD0QKBgQCA
22 | liZv4na6sg9ZiUPAr+QsKserNSiN5zFkULOPBKLRQbFFbPS1l12pRgLqNCu1qQV1
23 | 9H5tt6arSRpSfy5FB14gFxV4s23yFrnDyF2h2GsFH+MpEq1bbaI1A10AvUnQ5AeK
24 | QemRpxPmM2DldMK/H5tPzO0WAOoy4r/ATkc4sG4kxQKBgBL9neT0TmJtxlYGzjNc
25 | jdJXs3Q91+nZt3DRMGT9s0917SuP77+FdJYocDiH1rVa9sGG8rkh1jTdqliAxDXw
26 | Im5IGS/0OBnkaN1nnGDk5yTiYxOutC5NSj7ecI5Erud8swW6iGqgz2ioFpGxxIYq
27 | RlgTv/6mVt41KALfKrYIkVLw
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/publicKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "n":"livFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm-ntyIv1p4kE1sPEQO73-HY8-Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF_F9-KEBWkwVta-PZ37bwqSE4sCb1soZFrVz_UT_LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv_3Lw50bAkbT4HeLFxTx4flEoZLKO_g0bAoV2uqBhkA9xnQ",
4 | "e":"AQAB",
5 | "kid": "key1"
6 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/publicKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
3 | Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
4 | TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
5 | UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
6 | AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
7 | sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
8 | nQIDAQAB
9 | -----END RSA PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/publicKeySet.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty":"RSA",
5 | "n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ",
6 | "e":"AQAB",
7 | "kid": "key2"
8 | },
9 | {
10 | "kty":"RSA",
11 | "n":"livFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm-ntyIv1p4kE1sPEQO73-HY8-Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF_F9-KEBWkwVta-PZ37bwqSE4sCb1soZFrVz_UT_LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv_3Lw50bAkbT4HeLFxTx4flEoZLKO_g0bAoV2uqBhkA9xnQ",
12 | "e":"AQAB",
13 | "kid": "key1"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/publicSingleKeySetWithoutKid.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty":"RSA",
5 | "n":"livFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm-ntyIv1p4kE1sPEQO73-HY8-Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF_F9-KEBWkwVta-PZ37bwqSE4sCb1soZFrVz_UT_LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv_3Lw50bAkbT4HeLFxTx4flEoZLKO_g0bAoV2uqBhkA9xnQ",
6 | "e":"AQAB"
7 | }
8 | ]
9 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/rs256PrivateKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"RSA",
3 | "n":"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ",
4 | "e":"AQAB",
5 | "d":"AvIDTlsK_priQLTwEQf5IVf2Xl638Q7dHdXyDC-oAAPmv1GcqRVH7Wm5oAPW_CZQfWhV55WRVaJzP8AhksyD5NcslH79hQZT4NT6xgApGYecrvmseuZ4dfR-e1cxXTRNBxaoXvwSiv4LuOPHmC8XGX712AhOoCGKiZp1WFqqkKwTpkgJEApJFVb-XRIKQa0YaRKpJsJ534pLMwTh7LoPLM4BCaBVbRfHzH2H5L3TSJP718kyCuxg3z2p9Y7zIOLTmgFdeR0_kd_xKUFZ2ByN3SKlC0IWlLUSiMPsGYExRpZTMZHKyD939gv-2_Z-bOYfKlYNIvAmQH_8CcX2I039LQ",
6 | "p":"104AjPaxZoi_BiMBODlChnZOvRJT071PdkeZ283uyrdW8qqKD9q8FTMgUXzKoboHtUiHbJbLOobPmPDh93839rq7dTdCNzNVOuLmE-V3_bmaShdzvxEIazwPf6AvjbEZAc-zu2RS4SNkp1LbzgSl9nINSlF7t6Lkl6T28PYULys",
7 | "q":"om5ooyzxa4ZJ-dU0ODsEb-Bmz6xwb27xF9aEhBYJprHeoNs2QM1D64_A39weD9MYwBux4-ivshCJ0dVKEbDujJRLnzf-ssrasA6CFyaaCT4DKtq1oWb9rcG-2LQd5Bm9PttrUrSUNqitr085IYikaLEz7UU6gtXPoC8UOcJ4cSc",
8 | "dp":"DeWE95Q8oweUfMrpmz1m49LjBiUWsAX6CQJaFevWy9LFk-gZ_Sf7F8sy_M93LLUbJkJGK2YYO_DTmWWC0Dyv2gb3bntglLuFdsWKYCJhekjugnW9DMoGpxU7Utt99kFGAe3sBd5V0x47sukQMt3t8FgwL2nO-G1VH8yP-8GGT_0",
9 | "dq":"TGBeE1wuqMCcSD1YMJiPnYuGzF_o_nzMIMldxj4Wi6tXY4uwFwhtx3Xw21JFUGuSV8KuAtyGwNPF-kSwb2Eiyjdw140c1jVMXzxzLy-XfoEKPDxa62niHrHba0pGQ9tWgRfrfxgqGQl3odc-peX6aL_qCsdim-KtnkSE3iPzPkE",
10 | "qi":"Jzp5KnT24y0wOoPUn_11S3ZcYl0i03dkaH4c5zR02G1MJG9K017juurx2aXVTctOzrj7O226EUiL1Qbq3QtnWFDDGY6vNZuqzJM7AMXsvp1djq_6fEVhxCIOgfJbmhb3mkG82rxn4et9o_TNr6mvEmHzG15sHbvZbAnn4GeqToY",
11 | "kid":"rsakey"
12 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/secretKey.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "kty":"oct",
3 | "k":"Fdh9u8rINxfivbrianbbVT1u232VQBZYKx1HGAGPt2I"
4 | }
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/server-keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smallrye/smallrye-jwt/b43b673fb4cdfb06a7a9224b0b09529a4e8d9027/testsuite/basic/src/test/resources/server-keystore.jks
--------------------------------------------------------------------------------
/testsuite/basic/src/test/resources/signatureJwkSet.jwk:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty":"RSA",
5 | "n":"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ",
6 | "e":"AQAB",
7 | "kid": "rsakey"
8 | },
9 |
10 | {
11 | "kty":"EC",
12 | "x":"weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ",
13 | "y":"e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck",
14 | "crv":"P-256",
15 | "kid": "eckey"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/testsuite/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | 4.0.0
20 |
21 |
22 | io.smallrye
23 | smallrye-jwt-parent
24 | 4.6.3-SNAPSHOT
25 |
26 |
27 | pom
28 | smallrye-jwt-testsuite-parent
29 | SmallRye: MicroProfile JWT - Testsuite Parent
30 |
31 |
32 | 2.3.1
33 | 3.1.1
34 | 6.2.2.Final
35 | 3.0.1.Final
36 |
37 | 6.0.5.Final
38 | 25.0.1.Final
39 | 5.1.3.Final
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.eclipse.microprofile.jwt
47 | microprofile-jwt-auth-tck
48 | ${version.eclipse.microprofile.jwt}
49 |
50 |
51 | org.eclipse.microprofile.jwt
52 | microprofile-jwt-auth-tck
53 | test-jar
54 | ${version.eclipse.microprofile.jwt}
55 |
56 |
57 | io.smallrye.testing
58 | smallrye-testing-bom-tck
59 | ${version.smallrye.testing}
60 | pom
61 | import
62 |
63 |
64 | io.smallrye.config
65 | smallrye-config
66 | ${version.smallrye.config}
67 | test
68 |
69 |
70 | org.jboss.resteasy
71 | resteasy-bom
72 | ${version.resteasy}
73 | pom
74 | import
75 |
76 |
77 | org.jboss.resteasy.microprofile
78 | microprofile-rest-client
79 | ${version.resteasy.client}
80 | test
81 |
82 |
83 |
84 |
85 |
86 |
87 | basic
88 | tck
89 |
90 |
91 |
92 |
93 |
94 | org.apache.maven.plugins
95 | maven-install-plugin
96 |
97 | true
98 |
99 |
100 |
101 | org.sonatype.plugins
102 | nexus-staging-maven-plugin
103 |
104 | true
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/java/io/smallrye/jwt/tck/OptionalAwareSmallRyeJWTAuthCDIExtension.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.tck;
2 |
3 | import io.smallrye.jwt.auth.cdi.SmallRyeJWTAuthCDIExtension;
4 |
5 | public class OptionalAwareSmallRyeJWTAuthCDIExtension extends SmallRyeJWTAuthCDIExtension {
6 | // TODO - radcortez - This should be changed in the original extension. This is how Elytron is doing it.
7 | // Maybe because difference between 1.0 and 1.1? Right now it doesn't make sense to keeo it as is, since it will fail the TCK.
8 | @Override
9 | protected boolean registerOptionalClaimTypeProducer() {
10 | return true;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/java/io/smallrye/jwt/tck/SmallRyeJWTArchiveProcessor.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.tck;
2 |
3 | import java.util.Map;
4 |
5 | import jakarta.enterprise.inject.spi.Extension;
6 |
7 | import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
8 | import org.jboss.arquillian.test.spi.TestClass;
9 | import org.jboss.shrinkwrap.api.Archive;
10 | import org.jboss.shrinkwrap.api.ArchivePath;
11 | import org.jboss.shrinkwrap.api.Node;
12 | import org.jboss.shrinkwrap.api.spec.WebArchive;
13 |
14 | public class SmallRyeJWTArchiveProcessor implements ApplicationArchiveProcessor {
15 | @Override
16 | public void process(Archive> applicationArchive, TestClass testClass) {
17 | if (applicationArchive instanceof WebArchive) {
18 | WebArchive war = (WebArchive) applicationArchive;
19 | war.addClass(OptionalAwareSmallRyeJWTAuthCDIExtension.class);
20 | war.addClass(SmallRyeJWTAuthJaxRsFeature.class);
21 | war.addAsServiceProvider(Extension.class, OptionalAwareSmallRyeJWTAuthCDIExtension.class);
22 |
23 | // MP Config in wrong place - See https://github.com/eclipse/microprofile/issues/46.
24 | Map content = war.getContent(object -> object.get().matches(".*META-INF/.*"));
25 | content.forEach((archivePath, node) -> {
26 | if (node.getAsset() != null) {
27 | war.addAsResource(node.getAsset(), node.getPath());
28 | }
29 | });
30 |
31 | if (!war.contains("META-INF/microprofile-config.properties")) {
32 | war.addAsWebInfResource("microprofile-config-local.properties", "microprofile-config.properties");
33 | }
34 |
35 | // A few tests require the apps to be deployed in the root. Check PublicKeyAsJWKLocationURLTest and PublicKeyAsPEMLocationURLTest
36 | // Both tests set the public key location url to be in root.
37 | war.addAsWebInfResource("jboss-web.xml");
38 | war.addAsWebInfResource("jetty-web.xml");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/java/io/smallrye/jwt/tck/SmallRyeJWTAuthJaxRsFeature.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.tck;
2 |
3 | import jakarta.ws.rs.ext.Provider;
4 |
5 | /**
6 | * This is to register the JAX-RS Feature to add the SmallRye JWT Filters. This cannot be registed as a Provider
7 | * Service Loader, because it would initialize before the JAX-RS Application is available in the Context. This is
8 | * required to check the LoginModule in the Application class and provide correct registration of the filters.
9 | */
10 | @Provider
11 | public class SmallRyeJWTAuthJaxRsFeature extends io.smallrye.jwt.auth.jaxrs.SmallRyeJWTAuthJaxRsFeature {
12 | }
13 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/java/io/smallrye/jwt/tck/SmallRyeJWTExtension.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.tck;
2 |
3 | import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
4 | import org.jboss.arquillian.core.spi.LoadableExtension;
5 |
6 | public class SmallRyeJWTExtension implements LoadableExtension {
7 | @Override
8 | public void register(final ExtensionBuilder builder) {
9 | builder.service(ApplicationArchiveProcessor.class, SmallRyeJWTArchiveProcessor.class);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/java/io/smallrye/jwt/tck/TestApplication.java:
--------------------------------------------------------------------------------
1 | package io.smallrye.jwt.tck;
2 |
3 | import static jakarta.ws.rs.core.MediaType.TEXT_PLAIN;
4 |
5 | import java.io.IOException;
6 | import java.net.HttpURLConnection;
7 | import java.net.URL;
8 | import java.util.HashSet;
9 | import java.util.Set;
10 |
11 | import jakarta.enterprise.context.RequestScoped;
12 | import jakarta.servlet.annotation.WebServlet;
13 | import jakarta.servlet.http.HttpServlet;
14 | import jakarta.servlet.http.HttpServletRequest;
15 | import jakarta.servlet.http.HttpServletResponse;
16 | import jakarta.ws.rs.ApplicationPath;
17 | import jakarta.ws.rs.GET;
18 | import jakarta.ws.rs.Path;
19 | import jakarta.ws.rs.client.ClientBuilder;
20 | import jakarta.ws.rs.client.WebTarget;
21 | import jakarta.ws.rs.core.Response;
22 |
23 | import org.jboss.arquillian.container.test.api.Deployment;
24 | import org.jboss.arquillian.container.test.api.RunAsClient;
25 | import org.jboss.arquillian.test.api.ArquillianResource;
26 | import org.jboss.arquillian.testng.Arquillian;
27 | import org.jboss.shrinkwrap.api.ArchivePaths;
28 | import org.jboss.shrinkwrap.api.ShrinkWrap;
29 | import org.jboss.shrinkwrap.api.asset.EmptyAsset;
30 | import org.jboss.shrinkwrap.api.spec.WebArchive;
31 | import org.testng.Assert;
32 | import org.testng.annotations.Test;
33 |
34 | public class TestApplication extends Arquillian {
35 | /**
36 | * The base URL for the container under test
37 | */
38 | @ArquillianResource
39 | private URL baseURL;
40 |
41 | @Deployment
42 | public static WebArchive createDeployment() {
43 | return ShrinkWrap
44 | .create(WebArchive.class)
45 | .addClass(TestServlet.class)
46 | .addClass(RestApplication.class)
47 | .addClass(TestEndpoint.class)
48 | .addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));
49 | }
50 |
51 | @Test
52 | @RunAsClient
53 | public void servlet() {
54 | String uri = baseURL.toExternalForm() + "servlet";
55 | WebTarget echoEndpointTarget = ClientBuilder.newClient().target(uri);
56 | Response response = echoEndpointTarget.request(TEXT_PLAIN).get();
57 | Assert.assertEquals(response.getStatus(), HttpURLConnection.HTTP_OK);
58 | }
59 |
60 | @Test
61 | @RunAsClient
62 | public void rest() {
63 | String uri = baseURL.toExternalForm() + "rest";
64 | WebTarget echoEndpointTarget = ClientBuilder.newClient().target(uri);
65 | Response response = echoEndpointTarget.request(TEXT_PLAIN).get();
66 | Assert.assertEquals(response.getStatus(), HttpURLConnection.HTTP_OK);
67 | }
68 |
69 | @WebServlet(urlPatterns = "/servlet")
70 | public static class TestServlet extends HttpServlet {
71 | @Override
72 | protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
73 | resp.getWriter().write("hello");
74 | }
75 | }
76 |
77 | @ApplicationPath("/rest")
78 | public static class RestApplication extends jakarta.ws.rs.core.Application {
79 | @Override
80 | public Set> getClasses() {
81 | final HashSet> classes = new HashSet<>();
82 | classes.add(TestEndpoint.class);
83 | return classes;
84 | }
85 | }
86 |
87 | @RequestScoped
88 | @Path("/")
89 | public static class TestEndpoint {
90 | @GET
91 | public String hello() {
92 | return "hello";
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension:
--------------------------------------------------------------------------------
1 | io.smallrye.jwt.tck.SmallRyeJWTExtension
2 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/resources/arquillian.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | ${jacocoArgLine}
9 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/resources/jboss-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | /
8 |
9 |
10 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/resources/jetty-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /
5 |
6 |
--------------------------------------------------------------------------------
/testsuite/tck/src/test/resources/microprofile-config-local.properties:
--------------------------------------------------------------------------------
1 | mp.jwt.verify.publickey.location=publicKey.pem
2 | mp.jwt.verify.issuer=https://server.example.com
3 |
--------------------------------------------------------------------------------