1 package de.dlr.shepard.common.filters; 2 3 import static org.junit.jupiter.api.Assertions.assertEquals; 4 import static org.mockito.ArgumentMatchers.any; 5 import static org.mockito.Mockito.never; 6 import static org.mockito.Mockito.verify; 7 import static org.mockito.Mockito.when; 8 9 import de.dlr.shepard.BaseTestCase; 10 import de.dlr.shepard.auth.apikey.entities.ApiKey; 11 import de.dlr.shepard.auth.apikey.services.ApiKeyService; 12 import de.dlr.shepard.auth.security.ApiKeyLastSeenCache; 13 import de.dlr.shepard.auth.security.JWTPrincipal; 14 import de.dlr.shepard.auth.security.JWTSecurityContext; 15 import de.dlr.shepard.auth.security.RolesList; 16 import de.dlr.shepard.auth.users.entities.User; 17 import de.dlr.shepard.common.util.PKIHelper; 18 import io.jsonwebtoken.Jwts; 19 import io.quarkus.test.InjectMock; 20 import io.quarkus.test.component.QuarkusComponentTest; 21 import io.quarkus.test.component.TestConfigProperty; 22 import jakarta.inject.Inject; 23 import jakarta.ws.rs.container.ContainerRequestContext; 24 import jakarta.ws.rs.core.Response; 25 import jakarta.ws.rs.core.SecurityContext; 26 import jakarta.ws.rs.core.UriInfo; 27 import java.net.URI; 28 import java.net.URISyntaxException; 29 import java.security.KeyFactory; 30 import java.security.NoSuchAlgorithmException; 31 import java.security.PrivateKey; 32 import java.security.PublicKey; 33 import java.security.spec.InvalidKeySpecException; 34 import java.security.spec.PKCS8EncodedKeySpec; 35 import java.security.spec.X509EncodedKeySpec; 36 import java.util.Base64; 37 import java.util.Date; 38 import java.util.UUID; 39 import org.apache.commons.lang3.time.DateUtils; 40 import org.junit.jupiter.api.BeforeAll; 41 import org.junit.jupiter.api.BeforeEach; 42 import org.junit.jupiter.api.Test; 43 import org.mockito.ArgumentCaptor; 44 import org.mockito.Captor; 45 46 @QuarkusComponentTest 47 @TestConfigProperty( 48 key = "oidc.public", 49 value = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiAxFyffvM0oiga3h2E7XpHtJvu1vTodrn9Y426FOv80YJcMwPkaI5tXY5hnLjgOwsVNSBv9wAhLL4bUfP+TVhdg4dijD2H/3FamheQaPmduimytzQjlHIIfFuZidH12ZyUrOWfDxiHiRFQ3Dd8dlS7MbIsWt/qBIg16ZZazTJTiaSyP/qH305x9iRjrtGRmvE2VMOdc5EhujFMJnQWWgwOnv2C9U9KIchkPCz+TAL4kKJ79BUi4b0+jxL5Cbgyt0bMo27Zx0zQjU7f0ynFIllqZ6new3Q8HYbr4AIkca4pMjfKWrTHkrQBL2cEXHLIHt86C17goKteToqDjphkwImwIDAQAB" 50 ) 51 @TestConfigProperty(key = "oidc.role", value = "test_role") 52 public class JWTFilterTest extends BaseTestCase { 53 54 private static PrivateKey privateKey; 55 private static PublicKey publicKey; 56 57 @InjectMock 58 ContainerRequestContext context; 59 60 @InjectMock 61 UriInfo uriInfo; 62 63 @InjectMock 64 PKIHelper pkiHelper; 65 66 @InjectMock 67 ApiKeyService apiKeyService; 68 69 @InjectMock 70 ApiKeyLastSeenCache apiKeyLastSeenCache; 71 72 @Inject 73 JWTFilter filter; 74 75 @Captor 76 ArgumentCaptor<Response> responseCaptor; 77 78 @Captor 79 ArgumentCaptor<SecurityContext> scCaptor; 80 81 @BeforeAll 82 public static void createKeys() throws NoSuchAlgorithmException, InvalidKeySpecException { 83 var privateString = 84 "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCIDEXJ9+8zSiKBreHYTteke0m+7W9Oh2uf1jjboU6/zRglwzA+Rojm1djmGcuOA7CxU1IG/3ACEsvhtR8/5NWF2Dh2KMPYf/cVqaF5Bo+Z26KbK3NCOUcgh8W5mJ0fXZnJSs5Z8PGIeJEVDcN3x2VLsxsixa3+oEiDXpllrNMlOJpLI/+offTnH2JGOu0ZGa8TZUw51zkSG6MUwmdBZaDA6e/YL1T0ohyGQ8LP5MAviQonv0FSLhvT6PEvkJuDK3RsyjbtnHTNCNTt/TKcUiWWpnqd7DdDwdhuvgAiRxrikyN8patMeStAEvZwRccsge3zoLXuCgq15OioOOmGTAibAgMBAAECggEABBqirFIPZDOzUMgnDPhr5ulVMy5EclEBfSPgOTfngT+1n8YAmZBVJumCjoZuro0L8n159v4TqexZPCjTlYDYtB3urhnStqA9muiwF0+MW27Vu+qWooPJ0oBmBZBGBSE0t27LRMlQ7/X7InB02hMoyhzQD7943TqGlXfwFrIc+H1uXN8MrB4boRX71/yEPT8hv8nWB0FLcgfwtl1l+81otJFveMO/RLStHUH3Auomb/Hh4u96H6S6lUZ8TJ6+8jh2LXmg/RpsqHIWhDbZaNQJE1YdySe3bijov3s/PISaE8pRec6l6KaYkUuFUa6RoGP1RnopsFuN+EeLRMXTRtxgEQKBgQDDB1YRjE7YAYUqeuohhMgx9Ms39zsJGrs6KHE4uWtJFR/Jo3Kq093ykGA+IO+DK/IhBXGzy53SIQ9J7WEONpMmaahY6/Bkhn2nRI9biNaPCovHeO+nIpwtIdTUQLg/d+om+jC2My0YLGk71A5TRkIBPBE9NirbITxibo6jwWWOwwKBgQCylI1fx6f1gdEAP0qM7/LVLrZU3Qx+Q9rPcGG2FI1gWYu69o3JBGpSXqKcAc9hxtFVBaOGpaj9sB8+fPfMXWAvM7c808eL0zOmDC6RlQs0N4XmpV/vUeurgkLQfgB4sfUXbVWHQNsAkvB64BVbbmWFEcHzaBMytb2whvU9hcExSQKBgQCDuSjAoWt/KUev8WTBTtWIKDY5jpopBA0AsuAF1/ZGXiYiImsIRiDZ+/mE/OnIRp46/1pUfWoSypFw9Qtgdivc/e/eXzz2KIAlwYCx6jJAWnceOuhiklW5heghk7Td6TgVK1ZLOTVz5ksNRaSHSiS6gL+EAFnhtwj50oI0yCK30QKBgF7k028HADhUYEQaXbogs1AW/2p+/+mEkxxR4opHx4xgaQDTjSo5P2o/wXbW+2VAqfHdCjU9iFwuH5wr+d1N7ROIDqGzA8FIXJSquoA/y/FWY7/ZNu5MAMhlcq2plwSLw+pL/fveOcHHUyRoONEaC7Y3ZnG6ZyE2M/M+88hab/uJAoGARSSJgG3rRz8hcfQEfopo3rzdeAMY0ws+fXlHp6u51PP+238rB0Y+/b/NeHzwwuqeIxqVTcbd5E8Va7KESPuuzfIQtKbGuVwFpZzWHmROt312AoxeSwRDpOQibpfBAF59D40+SCl6N64whiVoEgJvOQGYB6BIcunIhSpLSD2YId4="; 85 var publicString = 86 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiAxFyffvM0oiga3h2E7XpHtJvu1vTodrn9Y426FOv80YJcMwPkaI5tXY5hnLjgOwsVNSBv9wAhLL4bUfP+TVhdg4dijD2H/3FamheQaPmduimytzQjlHIIfFuZidH12ZyUrOWfDxiHiRFQ3Dd8dlS7MbIsWt/qBIg16ZZazTJTiaSyP/qH305x9iRjrtGRmvE2VMOdc5EhujFMJnQWWgwOnv2C9U9KIchkPCz+TAL4kKJ79BUi4b0+jxL5Cbgyt0bMo27Zx0zQjU7f0ynFIllqZ6new3Q8HYbr4AIkca4pMjfKWrTHkrQBL2cEXHLIHt86C17goKteToqDjphkwImwIDAQAB"; 87 var keyFactory = KeyFactory.getInstance("RSA"); 88 89 byte[] privateDecoded = Base64.getDecoder().decode(privateString); 90 PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(privateDecoded); 91 privateKey = keyFactory.generatePrivate(privateSpec); 92 93 byte[] publicDecoded = Base64.getDecoder().decode(publicString); 94 X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(publicDecoded); 95 publicKey = keyFactory.generatePublic(publicSpec); 96 } 97 98 @BeforeEach 99 public void setUpKeys() throws IllegalAccessException { 100 when(pkiHelper.getPublicKey()).thenReturn(publicKey); 101 } 102 103 @BeforeEach 104 public void setUpUriInfo() throws URISyntaxException { 105 URI uri = new URI("http://localhost:8080/shepard/api/projects"); 106 URI baseUri = new URI("http://localhost:8080/shepard/api"); 107 String relativePath = "/projects"; 108 when(uriInfo.getPath()).thenReturn(relativePath); 109 when(uriInfo.getAbsolutePath()).thenReturn(uri); 110 when(uriInfo.getBaseUri()).thenReturn(baseUri); 111 when(context.getUriInfo()).thenReturn(uriInfo); 112 when(context.getMethod()).thenReturn("GET"); 113 } 114 115 @Test 116 public void testFilterCORS() throws URISyntaxException { 117 when(context.getMethod()).thenReturn("OPTIONS"); 118 filter.filter(context); 119 verify(context, never()).abortWith(any()); 120 } 121 122 @Test 123 public void testFilterPublic_publicRoute() throws URISyntaxException { 124 when(uriInfo.getPath()).thenReturn("/versionz"); 125 filter.filter(context); 126 verify(context, never()).abortWith(any()); 127 } 128 129 @Test 130 public void testFilterPublic_privateRoute() throws URISyntaxException { 131 when(uriInfo.getPath()).thenReturn("/versionsz"); 132 filter.filter(context); 133 verify(context).abortWith(any()); 134 } 135 136 @Test 137 public void testFilterNoHeader() throws URISyntaxException { 138 when(context.getHeaderString("Authorization")).thenReturn(null); 139 filter.filter(context); 140 verify(context).abortWith(responseCaptor.capture()); 141 assertEquals(401, responseCaptor.getValue().getStatus()); 142 } 143 144 @Test 145 public void testFilterWrongHeader() { 146 when(context.getHeaderString("Authorization")).thenReturn("sehr falsch"); 147 filter.filter(context); 148 verify(context).abortWith(responseCaptor.capture()); 149 assertEquals(401, responseCaptor.getValue().getStatus()); 150 } 151 152 @Test 153 public void testFilterTokenExpired() throws InvalidKeySpecException, NoSuchAlgorithmException { 154 Date now = DateUtils.addMinutes(new Date(), -10); 155 Date future = DateUtils.addMinutes(new Date(), -5); 156 157 String jws = Jwts.builder() 158 .setSubject("Bob") 159 .setAudience("account") 160 .setExpiration(future) 161 .setNotBefore(now) 162 .setIssuedAt(new Date()) 163 .setId(UUID.randomUUID().toString()) 164 .claim("azp", "testcase") 165 .claim("name", "MyName") 166 .claim("preferred_username", "MyUserName") 167 .claim("given_name", "MyFirstName") 168 .claim("family_name", "MyLastName") 169 .claim("email", "MyEMail") 170 .claim("realm_access", new RolesList(new String[] { "test_role" })) 171 .signWith(privateKey) 172 .compact(); 173 174 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 175 filter.filter(context); 176 verify(context).abortWith(responseCaptor.capture()); 177 assertEquals(401, responseCaptor.getValue().getStatus()); 178 } 179 180 @Test 181 public void testFilterMissingSubject() throws InvalidKeySpecException, NoSuchAlgorithmException { 182 Date now = new Date(); 183 Date future = DateUtils.addMinutes(now, 5); 184 UUID keyId = UUID.randomUUID(); 185 186 String jws = Jwts.builder() 187 .setAudience("account") 188 .setExpiration(future) 189 .setNotBefore(now) 190 .setIssuedAt(new Date()) 191 .setId(keyId.toString()) 192 .claim("azp", "testcase") 193 .claim("name", "MyName") 194 .claim("preferred_username", "MyUserName") 195 .claim("given_name", "MyFirstName") 196 .claim("family_name", "MyLastName") 197 .claim("email", "MyEMail") 198 .claim("realm_access", new RolesList(new String[] { "test_role" })) 199 .signWith(privateKey) 200 .compact(); 201 202 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 203 filter.filter(context); 204 verify(context).abortWith(responseCaptor.capture()); 205 assertEquals(401, responseCaptor.getValue().getStatus()); 206 } 207 208 @Test 209 public void testFilterEmptySubject() throws InvalidKeySpecException, NoSuchAlgorithmException { 210 Date now = new Date(); 211 Date future = DateUtils.addMinutes(now, 5); 212 UUID keyId = UUID.randomUUID(); 213 214 String jws = Jwts.builder() 215 .setAudience("account") 216 .setExpiration(future) 217 .setNotBefore(now) 218 .setIssuedAt(new Date()) 219 .setId(keyId.toString()) 220 .claim("azp", "testcase") 221 .claim("name", "MyName") 222 .claim("preferred_username", "MyUserName") 223 .claim("given_name", "MyFirstName") 224 .claim("family_name", "MyLastName") 225 .claim("email", "MyEMail") 226 .claim("realm_access", new RolesList(new String[] { "test_role" })) 227 .claim("sub", "") 228 .signWith(privateKey) 229 .compact(); 230 231 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 232 filter.filter(context); 233 verify(context).abortWith(responseCaptor.capture()); 234 assertEquals(401, responseCaptor.getValue().getStatus()); 235 } 236 237 @Test 238 public void testFilterMissingRole() throws InvalidKeySpecException, NoSuchAlgorithmException { 239 Date now = new Date(); 240 Date future = DateUtils.addMinutes(now, 5); 241 UUID keyId = UUID.randomUUID(); 242 243 String jws = Jwts.builder() 244 .setSubject("Bob") 245 .setAudience("account") 246 .setExpiration(future) 247 .setNotBefore(now) 248 .setIssuedAt(new Date()) 249 .setId(keyId.toString()) 250 .claim("azp", "testcase") 251 .claim("name", "MyName") 252 .claim("preferred_username", "MyUserName") 253 .claim("given_name", "MyFirstName") 254 .claim("family_name", "MyLastName") 255 .claim("email", "MyEMail") 256 .signWith(privateKey) 257 .compact(); 258 259 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 260 filter.filter(context); 261 verify(context).abortWith(responseCaptor.capture()); 262 assertEquals(401, responseCaptor.getValue().getStatus()); 263 } 264 265 @Test 266 public void testFilterWrongRole() throws InvalidKeySpecException, NoSuchAlgorithmException { 267 Date now = new Date(); 268 Date future = DateUtils.addMinutes(now, 5); 269 UUID keyId = UUID.randomUUID(); 270 271 String jws = Jwts.builder() 272 .setSubject("Bob") 273 .setAudience("account") 274 .setExpiration(future) 275 .setNotBefore(now) 276 .setIssuedAt(new Date()) 277 .setId(keyId.toString()) 278 .claim("azp", "testcase") 279 .claim("name", "MyName") 280 .claim("preferred_username", "MyUserName") 281 .claim("given_name", "MyFirstName") 282 .claim("family_name", "MyLastName") 283 .claim("email", "MyEMail") 284 .claim("realm_access", new RolesList(new String[] { "wrong_role" })) 285 .signWith(privateKey) 286 .compact(); 287 288 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 289 filter.filter(context); 290 verify(context).abortWith(responseCaptor.capture()); 291 assertEquals(401, responseCaptor.getValue().getStatus()); 292 } 293 294 @Test 295 @TestConfigProperty(key = "oidc.role", value = "") 296 public void testFilterNoRoleConfigured() 297 throws InvalidKeySpecException, NoSuchAlgorithmException, IllegalAccessException { 298 Date now = new Date(); 299 Date future = DateUtils.addMinutes(now, 5); 300 UUID keyId = UUID.randomUUID(); 301 302 String jws = Jwts.builder() 303 .setSubject("Bob") 304 .setAudience("account") 305 .setExpiration(future) 306 .setNotBefore(now) 307 .setIssuedAt(new Date()) 308 .setId(keyId.toString()) 309 .claim("azp", "testcase") 310 .claim("name", "MyName") 311 .claim("preferred_username", "MyUserName") 312 .claim("given_name", "MyFirstName") 313 .claim("family_name", "MyLastName") 314 .claim("email", "MyEMail") 315 .claim("realm_access", new RolesList(new String[] { "another_role" })) 316 .signWith(privateKey) 317 .compact(); 318 319 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 320 filter.filter(context); 321 verify(context, never()).abortWith(any()); 322 } 323 324 @Test 325 public void testFilterSucessful() throws InvalidKeySpecException, NoSuchAlgorithmException { 326 Date now = new Date(); 327 Date future = DateUtils.addMinutes(now, 5); 328 UUID keyId = UUID.randomUUID(); 329 330 String jws = Jwts.builder() 331 .setSubject("Bob") 332 .setAudience("account") 333 .setExpiration(future) 334 .setNotBefore(now) 335 .setIssuedAt(new Date()) 336 .setId(keyId.toString()) 337 .claim("azp", "testcase") 338 .claim("name", "MyName") 339 .claim("preferred_username", "MyUserName") 340 .claim("given_name", "MyFirstName") 341 .claim("family_name", "MyLastName") 342 .claim("email", "MyEMail") 343 .claim("realm_access", new RolesList(new String[] { "test_role" })) 344 .signWith(privateKey) 345 .compact(); 346 347 JWTPrincipal principal = new JWTPrincipal("account", "testcase", "Bob", keyId.toString(), new String[0]); 348 JWTSecurityContext securityContext = new JWTSecurityContext(context.getSecurityContext(), principal); 349 350 when(context.getHeaderString("Authorization")).thenReturn("Bearer " + jws); 351 filter.filter(context); 352 verify(context, never()).abortWith(any()); 353 verify(context).setSecurityContext(scCaptor.capture()); 354 assertEquals(securityContext.getUserPrincipal(), scCaptor.getValue().getUserPrincipal()); 355 } 356 357 @Test 358 public void testFilterSucessfulApiKey() throws InvalidKeySpecException, NoSuchAlgorithmException { 359 Date now = new Date(); 360 UUID uid = UUID.randomUUID(); 361 362 String jws = Jwts.builder() 363 .setSubject("MyUserName") 364 .setNotBefore(now) 365 .setIssuedAt(new Date()) 366 .setId(uid.toString()) 367 .signWith(privateKey) 368 .compact(); 369 370 User user = new User("MyUserName"); 371 372 ApiKey apiKey = new ApiKey(uid); 373 apiKey.setName("MyApiKey"); 374 apiKey.setJws(jws); 375 apiKey.setBelongsTo(user); 376 377 JWTPrincipal principal = new JWTPrincipal("MyUserName", uid.toString()); 378 JWTSecurityContext securityContext = new JWTSecurityContext(context.getSecurityContext(), principal); 379 380 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 381 when(apiKeyService.getApiKey(uid)).thenReturn(apiKey); 382 383 filter.filter(context); 384 verify(context, never()).abortWith(any()); 385 verify(context).setSecurityContext(scCaptor.capture()); 386 verify(apiKeyLastSeenCache).cacheKey(uid.toString()); 387 assertEquals(securityContext.getUserPrincipal(), scCaptor.getValue().getUserPrincipal()); 388 } 389 390 @Test 391 public void testFilterMissingSubjectApiKey() throws InvalidKeySpecException, NoSuchAlgorithmException { 392 Date now = new Date(); 393 UUID uid = UUID.randomUUID(); 394 395 String jws = Jwts.builder() 396 .setNotBefore(now) 397 .setIssuedAt(new Date()) 398 .setId(uid.toString()) 399 .signWith(privateKey) 400 .compact(); 401 402 User user = new User("MyUserName"); 403 404 ApiKey apiKey = new ApiKey(uid); 405 apiKey.setName("MyApiKey"); 406 apiKey.setJws(jws); 407 apiKey.setBelongsTo(user); 408 409 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 410 when(apiKeyService.getApiKey(user.getUsername(), uid)).thenReturn(apiKey); 411 412 filter.filter(context); 413 verify(context).abortWith(responseCaptor.capture()); 414 assertEquals(401, responseCaptor.getValue().getStatus()); 415 } 416 417 @Test 418 public void testFilterEmptySubjectApiKey() throws InvalidKeySpecException, NoSuchAlgorithmException { 419 Date now = new Date(); 420 UUID uid = UUID.randomUUID(); 421 422 String jws = Jwts.builder() 423 .setNotBefore(now) 424 .setIssuedAt(new Date()) 425 .setId(uid.toString()) 426 .claim("sub", "") 427 .signWith(privateKey) 428 .compact(); 429 430 User user = new User("MyUserName"); 431 432 ApiKey apiKey = new ApiKey(uid); 433 apiKey.setName("MyApiKey"); 434 apiKey.setJws(jws); 435 apiKey.setBelongsTo(user); 436 437 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 438 when(apiKeyService.getApiKey(user.getUsername(), uid)).thenReturn(apiKey); 439 440 filter.filter(context); 441 verify(context).abortWith(responseCaptor.capture()); 442 assertEquals(401, responseCaptor.getValue().getStatus()); 443 } 444 445 @Test 446 public void testFilterNotYetValidApiKey() throws InvalidKeySpecException, NoSuchAlgorithmException { 447 Date future = DateUtils.addMinutes(new Date(), 5); 448 UUID uid = UUID.randomUUID(); 449 450 String jws = Jwts.builder() 451 .setSubject("MyUserName") 452 .setNotBefore(future) 453 .setIssuedAt(new Date()) 454 .setId(uid.toString()) 455 .signWith(privateKey) 456 .compact(); 457 458 User user = new User("MyUserName"); 459 460 ApiKey apiKey = new ApiKey(uid); 461 apiKey.setName("MyApiKey"); 462 apiKey.setJws(jws); 463 apiKey.setBelongsTo(user); 464 465 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 466 when(apiKeyService.getApiKey(user.getUsername(), uid)).thenReturn(apiKey); 467 468 filter.filter(context); 469 verify(context).abortWith(responseCaptor.capture()); 470 assertEquals(401, responseCaptor.getValue().getStatus()); 471 } 472 473 @Test 474 public void testFilterNotFoundInDBApiKey() throws InvalidKeySpecException, NoSuchAlgorithmException { 475 Date now = new Date(); 476 UUID uid = UUID.randomUUID(); 477 478 String jws = Jwts.builder() 479 .setSubject("MyUserName") 480 .setNotBefore(now) 481 .setIssuedAt(new Date()) 482 .setId(uid.toString()) 483 .signWith(privateKey) 484 .compact(); 485 486 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 487 when(apiKeyService.getApiKey("MyUserName", uid)).thenReturn(null); 488 489 filter.filter(context); 490 verify(context).abortWith(responseCaptor.capture()); 491 assertEquals(401, responseCaptor.getValue().getStatus()); 492 } 493 494 @Test 495 public void testFilterWrongFoundInDBApiKey() throws InvalidKeySpecException, NoSuchAlgorithmException { 496 Date now = new Date(); 497 UUID uid = UUID.randomUUID(); 498 499 String jws = Jwts.builder() 500 .setSubject("MyUserName") 501 .setNotBefore(now) 502 .setIssuedAt(new Date()) 503 .setId(uid.toString()) 504 .signWith(privateKey) 505 .compact(); 506 507 User user = new User("MyUserName"); 508 509 ApiKey apiKey = new ApiKey(uid); 510 apiKey.setName("MyApiKey"); 511 apiKey.setJws("Wrong"); 512 apiKey.setBelongsTo(user); 513 514 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 515 when(apiKeyService.getApiKey(user.getUsername(), uid)).thenReturn(apiKey); 516 517 filter.filter(context); 518 verify(context).abortWith(responseCaptor.capture()); 519 assertEquals(401, responseCaptor.getValue().getStatus()); 520 } 521 522 @Test 523 public void testFilterGracePeriod() throws InvalidKeySpecException, NoSuchAlgorithmException { 524 Date now = new Date(); 525 UUID uid = UUID.randomUUID(); 526 527 String jws = Jwts.builder() 528 .setSubject("MyUserName") 529 .setNotBefore(now) 530 .setIssuedAt(new Date()) 531 .setId(uid.toString()) 532 .signWith(privateKey) 533 .compact(); 534 535 JWTPrincipal principal = new JWTPrincipal("MyUserName", uid.toString()); 536 JWTSecurityContext securityContext = new JWTSecurityContext(context.getSecurityContext(), principal); 537 538 when(context.getHeaderString("X-API-KEY")).thenReturn(jws); 539 when(apiKeyLastSeenCache.isKeyCached(uid.toString())).thenReturn(true); 540 541 filter.filter(context); 542 verify(context, never()).abortWith(any()); 543 verify(context).setSecurityContext(scCaptor.capture()); 544 verify(apiKeyService, never()).getApiKey("MyUserName", uid); 545 assertEquals(securityContext.getUserPrincipal(), scCaptor.getValue().getUserPrincipal()); 546 } 547 }