1 package com.atlassian.asap.it;
2
3 import com.atlassian.asap.api.Jwt;
4 import com.atlassian.asap.api.JwtBuilder;
5 import com.atlassian.asap.api.SigningAlgorithm;
6 import com.atlassian.asap.api.client.http.AuthorizationHeaderGenerator;
7 import com.atlassian.asap.core.client.http.AuthorizationHeaderGeneratorImpl;
8 import com.atlassian.asap.core.keys.KeyProvider;
9 import com.atlassian.asap.core.keys.PemReader;
10 import com.atlassian.asap.core.keys.publickey.ClasspathPublicKeyProvider;
11 import org.apache.http.HttpHeaders;
12 import org.apache.http.HttpResponse;
13 import org.apache.http.HttpStatus;
14 import org.apache.http.client.HttpClient;
15 import org.apache.http.client.methods.HttpGet;
16 import org.apache.http.client.utils.HttpClientUtils;
17 import org.apache.http.impl.client.HttpClients;
18 import org.junit.After;
19 import org.junit.Test;
20
21 import javax.annotation.Nullable;
22 import java.io.IOException;
23 import java.net.URI;
24 import java.security.PublicKey;
25 import java.util.Optional;
26
27 import static org.hamcrest.Matchers.is;
28 import static org.junit.Assert.assertThat;
29
30
31
32
33
34 public abstract class BaseIntegrationTest {
35 protected static final String AUDIENCE = "test-resource-server";
36
37 protected static final String ISSUER1 = "issuer1";
38 protected static final String ISSUER2 = "issuer2";
39 protected static final String ISSUER1_RSA_KEY_ID = "issuer1/rsa-key-for-tests";
40 protected static final String ISSUER1_EC_KEY_ID = "issuer1/es256-key-for-tests";
41 protected static final String ISSUER1_ONLY_PRIV_KEY_RSA_KEY_ID = "issuer1/only-private-key-for-tests";
42 protected static final String ISSUER2_RSA_KEY_ID = "issuer2/rsa-key-for-tests";
43 protected static final KeyProvider<PublicKey> PUBLIC_KEY_PROVIDER =
44 new ClasspathPublicKeyProvider("/publickeyrepo/", new PemReader());
45
46 protected static final String RESOURCE = "resource";
47
48 protected static final String UNAUTHORIZED_SUBJECT = "unauthorized-subject";
49
50 private HttpClient httpClient = HttpClients.createDefault();
51
52 protected abstract URI getUrlForResourceName(String resourceName);
53
54 @After
55 public void shutdownHttpClient() {
56 HttpClientUtils.closeQuietly(httpClient);
57 }
58
59 private String generateAuthorizationHeader(Jwt jwt) throws Exception {
60 AuthorizationHeaderGenerator authorizationHeaderGenerator =
61 AuthorizationHeaderGeneratorImpl.createDefault(URI.create("classpath:///privatekeys/"));
62
63 return authorizationHeaderGenerator.generateAuthorizationHeader(jwt);
64 }
65
66 private HttpResponse executeRequestWithJwt(String resourceName, Jwt jwt) throws Exception {
67 String authorizationHeader = generateAuthorizationHeader(jwt);
68 return executeRequestWithAuthorization(resourceName, authorizationHeader);
69 }
70
71 private HttpResponse executeRequestWithAuthorization(String resourceName,
72 @Nullable String authorizationHeader) throws IOException {
73 HttpGet getRequest = new HttpGet(getUrlForResourceName(resourceName));
74 getRequest.setHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
75 return httpClient.execute(getRequest);
76 }
77
78
79
80
81
82
83 @Test
84 public void shouldRejectRequestWithoutAuthenticationHeader() throws Exception {
85 HttpResponse response = executeRequestWithAuthorization(RESOURCE, null);
86
87 assertUnauthorized(response);
88 }
89
90
91
92
93
94
95 @Test
96 public void shouldRejectRequestWithBasicAuth() throws Exception {
97 HttpResponse response = executeRequestWithAuthorization(RESOURCE, "Basic foobar");
98
99 assertUnauthorized(response);
100 }
101
102
103
104
105
106
107 @Test
108 public void shouldRejectRequestWithMalformedToken() throws Exception {
109 HttpResponse response = executeRequestWithAuthorization(RESOURCE, "Bearer this-is-not-jwt");
110
111 assertUnauthorized(response);
112 }
113
114
115
116
117
118
119 @Test
120 public void shouldAcceptRequestWithValidRS256Token() throws Exception {
121 Jwt jwt = JwtBuilder.newJwt()
122 .keyId(ISSUER1_RSA_KEY_ID)
123 .issuer(ISSUER1)
124 .audience(AUDIENCE)
125 .build();
126
127 HttpResponse response = executeRequestWithJwt(RESOURCE, jwt);
128
129 assertOk(response);
130 }
131
132
133
134
135
136
137 @Test
138 public void shouldAcceptRequestWithValidPS256Token() throws Exception {
139 Jwt jwt = JwtBuilder.newJwt()
140 .algorithm(SigningAlgorithm.PS256)
141 .keyId(ISSUER1_RSA_KEY_ID)
142 .issuer(ISSUER1)
143 .audience(AUDIENCE)
144 .build();
145
146 HttpResponse response = executeRequestWithJwt(RESOURCE, jwt);
147
148 assertOk(response);
149 }
150
151
152
153
154
155
156 @Test
157 public void shouldAcceptRequestWithValidES256Token() throws Exception {
158 Jwt jwt = JwtBuilder.newJwt()
159 .algorithm(SigningAlgorithm.ES256)
160 .keyId(ISSUER1_EC_KEY_ID)
161 .issuer(ISSUER1)
162 .audience(AUDIENCE)
163 .build();
164
165 HttpResponse response = executeRequestWithJwt(RESOURCE, jwt);
166
167 assertOk(response);
168 }
169
170
171
172
173
174
175 @Test
176 public void shouldRejectRequestWithUnauthorizedSubject() throws Exception {
177 Jwt jwt = JwtBuilder.newJwt()
178 .keyId(ISSUER1_RSA_KEY_ID)
179 .issuer(ISSUER1)
180 .audience(AUDIENCE)
181 .subject(Optional.of(UNAUTHORIZED_SUBJECT))
182 .build();
183
184 HttpResponse response = executeRequestWithJwt(RESOURCE, jwt);
185
186 assertForbidden(response);
187 }
188
189
190
191
192
193
194 @Test
195 public void shouldRejectRequestIfPublicKeyCannotBeFound() throws Exception {
196 Jwt jwt = JwtBuilder.newJwt()
197 .keyId(ISSUER1_ONLY_PRIV_KEY_RSA_KEY_ID)
198 .issuer(ISSUER1)
199 .audience(AUDIENCE)
200 .build();
201
202 HttpResponse response = executeRequestWithJwt(RESOURCE, jwt);
203
204 assertUnauthorized(response);
205 }
206
207
208
209
210
211
212 @Test
213 public void shouldRejectRequestWithUnauthorizedIssuer() throws Exception {
214 Jwt jwt = JwtBuilder.newJwt()
215 .keyId(ISSUER2_RSA_KEY_ID)
216 .issuer(ISSUER2)
217 .audience(AUDIENCE)
218 .subject(Optional.of(ISSUER1))
219 .build();
220
221 HttpResponse response = executeRequestWithJwt(RESOURCE, jwt);
222
223 assertForbidden(response);
224 }
225
226 private static void assertOk(HttpResponse response) {
227 assertThat(response.getStatusLine().getStatusCode(), is(HttpStatus.SC_OK));
228 }
229
230 private static void assertUnauthorized(HttpResponse response) {
231 assertThat(response.getStatusLine().getStatusCode(), is(HttpStatus.SC_UNAUTHORIZED));
232 }
233
234 private static void assertForbidden(HttpResponse response) {
235 assertThat(response.getStatusLine().getStatusCode(), is(HttpStatus.SC_FORBIDDEN));
236 }
237 }