|
40 | 40 | import java.util.stream.Collectors;
|
41 | 41 |
|
42 | 42 | import static java.util.Map.entry;
|
| 43 | +import static org.elasticsearch.xpack.core.security.authc.AuthenticationTestHelper.randomCrossClusterAccessSubjectInfo; |
43 | 44 | import static org.elasticsearch.xpack.core.security.authc.CrossClusterAccessSubjectInfoTests.randomRoleDescriptorsIntersection;
|
44 | 45 | import static org.hamcrest.Matchers.containsString;
|
45 | 46 | import static org.hamcrest.Matchers.equalTo;
|
@@ -139,9 +140,8 @@ public void testCanAccessResourcesOf() {
|
139 | 140 |
|
140 | 141 | public void testCrossClusterAccessCanAccessResourceOf() throws IOException {
|
141 | 142 | final String apiKeyId1 = randomAlphaOfLengthBetween(10, 20);
|
142 |
| - final CrossClusterAccessSubjectInfo crossClusterAccessSubjectInfo1 = randomValueOtherThanMany( |
143 |
| - ra -> User.isInternal(ra.getAuthentication().getEffectiveSubject().getUser()), |
144 |
| - AuthenticationTestHelper::randomCrossClusterAccessSubjectInfo |
| 143 | + final CrossClusterAccessSubjectInfo crossClusterAccessSubjectInfo1 = randomCrossClusterAccessSubjectInfo( |
| 144 | + AuthenticationTestHelper.builder().realm().build() |
145 | 145 | );
|
146 | 146 | final Authentication authentication = AuthenticationTestHelper.builder()
|
147 | 147 | .crossClusterAccess(apiKeyId1, crossClusterAccessSubjectInfo1)
|
@@ -260,7 +260,110 @@ public void testCrossClusterAccessCanAccessResourceOf() throws IOException {
|
260 | 260 | assert false : "Case number out of range";
|
261 | 261 | }
|
262 | 262 |
|
263 |
| - // TODO: Add more tests for API keys when they work as QC subject |
| 263 | + } |
| 264 | + |
| 265 | + private static Authentication randomCrossClusterAccessAuthentication( |
| 266 | + String crossClusterApiKeyId, |
| 267 | + User user, |
| 268 | + Authentication authentication |
| 269 | + ) { |
| 270 | + return AuthenticationTestHelper.builder() |
| 271 | + .crossClusterAccess(crossClusterApiKeyId, randomCrossClusterAccessSubjectInfo(authentication)) |
| 272 | + .user(user) |
| 273 | + .build(false); |
| 274 | + } |
| 275 | + |
| 276 | + public void testCrossClusterAccessCanAccessResourceOfWithApiKey() { |
| 277 | + final User user1 = randomUser(); |
| 278 | + final RealmRef realm1 = randomRealmRef(false); |
| 279 | + |
| 280 | + // Different username is different no matter which realm it is from |
| 281 | + final User user2 = randomValueOtherThanMany(u -> u.principal().equals(user1.principal()), AuthenticationTests::randomUser); |
| 282 | + // user 2 can be from either the same realm or a different realm |
| 283 | + final RealmRef realm2 = randomFrom(realm1, randomRealmRef(false)); |
| 284 | + |
| 285 | + final String apiKeyId1 = randomAlphaOfLengthBetween(10, 20); |
| 286 | + // User is irrelevant |
| 287 | + final User crossClusterUser1 = randomFrom(user1, user2, randomUser()); |
| 288 | + final String crossClusterApiKeyId1 = randomAlphaOfLengthBetween(10, 20); |
| 289 | + |
| 290 | + // Same cross cluster access authentication with the same API key is allowed. |
| 291 | + assertCanAccessResources( |
| 292 | + randomCrossClusterAccessAuthentication(crossClusterApiKeyId1, crossClusterUser1, randomApiKeyAuthentication(user1, apiKeyId1)), |
| 293 | + randomCrossClusterAccessAuthentication(crossClusterApiKeyId1, crossClusterUser1, randomApiKeyAuthentication(user1, apiKeyId1)) |
| 294 | + ); |
| 295 | + |
| 296 | + // Cluster access authentication with different API credentials keys is not allowed. |
| 297 | + final String crossClusterApiKeyId2 = randomValueOtherThan(crossClusterApiKeyId1, () -> randomAlphaOfLengthBetween(10, 20)); |
| 298 | + assertCannotAccessResources( |
| 299 | + randomCrossClusterAccessAuthentication(crossClusterApiKeyId1, crossClusterUser1, randomApiKeyAuthentication(user1, apiKeyId1)), |
| 300 | + randomCrossClusterAccessAuthentication(crossClusterApiKeyId2, crossClusterUser1, randomApiKeyAuthentication(user1, apiKeyId1)) |
| 301 | + ); |
| 302 | + |
| 303 | + // Cross cluster access with a user and its API key is not the same owner, hence not allowed. |
| 304 | + assertCannotAccessResources( |
| 305 | + randomCrossClusterAccessAuthentication(crossClusterApiKeyId1, crossClusterUser1, randomAuthentication(user1, realm1)), |
| 306 | + randomCrossClusterAccessAuthentication(crossClusterApiKeyId1, crossClusterUser1, randomApiKeyAuthentication(user1, apiKeyId1)) |
| 307 | + ); |
| 308 | + |
| 309 | + // Cross cluster access with two different API keys (regardless if the same user is owner) is not allowed. |
| 310 | + final String apiKeyId2 = randomValueOtherThanMany(id -> id.equals(apiKeyId1), () -> randomAlphaOfLengthBetween(10, 20)); |
| 311 | + assertCannotAccessResources( |
| 312 | + randomCrossClusterAccessAuthentication( |
| 313 | + crossClusterApiKeyId1, |
| 314 | + crossClusterUser1, |
| 315 | + randomApiKeyAuthentication(randomFrom(user1, user2), apiKeyId1) |
| 316 | + ), |
| 317 | + randomCrossClusterAccessAuthentication( |
| 318 | + crossClusterApiKeyId1, |
| 319 | + crossClusterUser1, |
| 320 | + randomApiKeyAuthentication(randomFrom(user1, user2), apiKeyId2) |
| 321 | + ) |
| 322 | + ); |
| 323 | + |
| 324 | + // Cross cluster access using same API key but run-as different users is not allowed. |
| 325 | + final User user3 = randomValueOtherThanMany( |
| 326 | + u -> u.principal().equals(user1.principal()) || u.principal().equals(user2.principal()), |
| 327 | + AuthenticationTests::randomUser |
| 328 | + ); |
| 329 | + assertCannotAccessResources( |
| 330 | + randomCrossClusterAccessAuthentication( |
| 331 | + crossClusterApiKeyId1, |
| 332 | + crossClusterUser1, |
| 333 | + randomApiKeyAuthentication(user1, apiKeyId1).runAs(user2, realm2) |
| 334 | + ), |
| 335 | + randomCrossClusterAccessAuthentication( |
| 336 | + crossClusterApiKeyId1, |
| 337 | + crossClusterUser1, |
| 338 | + randomApiKeyAuthentication(user1, apiKeyId1).runAs(user3, realm2) |
| 339 | + ) |
| 340 | + ); |
| 341 | + |
| 342 | + // Cross cluster access using same or different API key which run-as the same user (user3) is allowed. |
| 343 | + assertCanAccessResources( |
| 344 | + randomCrossClusterAccessAuthentication( |
| 345 | + crossClusterApiKeyId1, |
| 346 | + crossClusterUser1, |
| 347 | + randomApiKeyAuthentication(user1, apiKeyId1).runAs(user3, realm2) |
| 348 | + ), |
| 349 | + randomCrossClusterAccessAuthentication( |
| 350 | + crossClusterApiKeyId1, |
| 351 | + crossClusterUser1, |
| 352 | + randomApiKeyAuthentication(user1, apiKeyId1).runAs(user3, realm2) |
| 353 | + ) |
| 354 | + ); |
| 355 | + assertCanAccessResources( |
| 356 | + randomCrossClusterAccessAuthentication( |
| 357 | + crossClusterApiKeyId1, |
| 358 | + crossClusterUser1, |
| 359 | + randomApiKeyAuthentication(user1, apiKeyId1).runAs(user3, realm2) |
| 360 | + ), |
| 361 | + randomCrossClusterAccessAuthentication( |
| 362 | + crossClusterApiKeyId1, |
| 363 | + crossClusterUser1, |
| 364 | + randomApiKeyAuthentication(user2, apiKeyId2).runAs(user3, realm2) |
| 365 | + ) |
| 366 | + ); |
264 | 367 | }
|
265 | 368 |
|
266 | 369 | public void testTokenAccessResourceOf() {
|
@@ -569,7 +672,7 @@ public void testDomainSerialize() throws Exception {
|
569 | 672 |
|
570 | 673 | public void testCrossClusterAccessAuthentication() throws IOException {
|
571 | 674 | final String crossClusterAccessApiKeyId = ESTestCase.randomAlphaOfLength(20);
|
572 |
| - final CrossClusterAccessSubjectInfo crossClusterAccessSubjectInfo = AuthenticationTestHelper.randomCrossClusterAccessSubjectInfo(); |
| 675 | + final CrossClusterAccessSubjectInfo crossClusterAccessSubjectInfo = randomCrossClusterAccessSubjectInfo(); |
573 | 676 | final Authentication authentication = AuthenticationTestHelper.builder()
|
574 | 677 | .crossClusterAccess(crossClusterAccessApiKeyId, crossClusterAccessSubjectInfo)
|
575 | 678 | .build(false);
|
@@ -676,7 +779,7 @@ public void testToXContentWithApiKey() throws IOException {
|
676 | 779 | public void testToXContentWithCrossClusterAccess() throws IOException {
|
677 | 780 | final String apiKeyId = randomAlphaOfLength(20);
|
678 | 781 | final Authentication authentication = AuthenticationTestHelper.builder()
|
679 |
| - .crossClusterAccess(apiKeyId, AuthenticationTestHelper.randomCrossClusterAccessSubjectInfo()) |
| 782 | + .crossClusterAccess(apiKeyId, randomCrossClusterAccessSubjectInfo()) |
680 | 783 | .build(false);
|
681 | 784 | final String apiKeyName = (String) authentication.getAuthenticatingSubject()
|
682 | 785 | .getMetadata()
|
@@ -867,7 +970,7 @@ public void testToCrossClusterAccess() {
|
867 | 970 | final User creator = randomUser();
|
868 | 971 | final String apiKeyId = randomAlphaOfLength(42);
|
869 | 972 | final Authentication apiKeyAuthentication = AuthenticationTestHelper.builder().apiKey(apiKeyId).user(creator).build(false);
|
870 |
| - final CrossClusterAccessSubjectInfo crossClusterAccessSubjectInfo = AuthenticationTestHelper.randomCrossClusterAccessSubjectInfo(); |
| 973 | + final CrossClusterAccessSubjectInfo crossClusterAccessSubjectInfo = randomCrossClusterAccessSubjectInfo(); |
871 | 974 |
|
872 | 975 | final Authentication actualAuthentication = apiKeyAuthentication.toCrossClusterAccess(crossClusterAccessSubjectInfo);
|
873 | 976 |
|
|
0 commit comments