|
40 | 40 | import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.EmptyAuthorizationInfo;
|
41 | 41 | import org.elasticsearch.xpack.core.security.support.Exceptions;
|
42 | 42 | import org.elasticsearch.xpack.core.security.user.AnonymousUser;
|
| 43 | +import org.elasticsearch.xpack.core.security.user.AsyncSearchUser; |
43 | 44 | import org.elasticsearch.xpack.core.security.user.SystemUser;
|
44 | 45 | import org.elasticsearch.xpack.core.security.user.User;
|
| 46 | +import org.elasticsearch.xpack.core.security.user.XPackSecurityUser; |
| 47 | +import org.elasticsearch.xpack.core.security.user.XPackUser; |
45 | 48 | import org.elasticsearch.xpack.security.audit.AuditTrail;
|
46 | 49 | import org.elasticsearch.xpack.security.audit.AuditTrailService;
|
47 | 50 | import org.elasticsearch.xpack.security.audit.AuditUtil;
|
48 | 51 | import org.elasticsearch.xpack.security.authc.support.RealmUserLookup;
|
49 | 52 | import org.elasticsearch.xpack.security.support.SecurityIndexManager;
|
50 | 53 |
|
51 | 54 | import java.util.ArrayList;
|
| 55 | +import java.util.Arrays; |
52 | 56 | import java.util.Collections;
|
53 | 57 | import java.util.LinkedHashMap;
|
54 | 58 | import java.util.List;
|
@@ -657,7 +661,8 @@ void finishAuthentication(User finalUser) {
|
657 | 661 | logger.debug("user [{}] is disabled. failing authentication", finalUser);
|
658 | 662 | listener.onFailure(request.authenticationFailed(authenticationToken));
|
659 | 663 | } else {
|
660 |
| - final Authentication finalAuth = new Authentication(finalUser, authenticatedBy, lookedupBy); |
| 664 | + final Authentication finalAuth = new Authentication( |
| 665 | + maybeMergeAnonymousRolesForUser(finalUser), authenticatedBy, lookedupBy); |
661 | 666 | writeAuthToContext(finalAuth);
|
662 | 667 | }
|
663 | 668 | }
|
@@ -690,6 +695,44 @@ void writeAuthToContext(Authentication authentication) {
|
690 | 695 | private void authenticateToken(AuthenticationToken token) {
|
691 | 696 | this.consumeToken(token);
|
692 | 697 | }
|
| 698 | + |
| 699 | + private User maybeMergeAnonymousRolesForUser(User user) { |
| 700 | + if (SystemUser.is(user) || XPackUser.is(user) || XPackSecurityUser.is(user) || AsyncSearchUser.is(user)) { |
| 701 | + return user; |
| 702 | + } else if (isAnonymousUserEnabled && anonymousUser.equals(user) == false) { |
| 703 | + if (anonymousUser.roles().length == 0) { |
| 704 | + throw new IllegalStateException("anonymous is only enabled when the anonymous user has roles"); |
| 705 | + } |
| 706 | + User userWithMergedRoles = new User(user.principal(), |
| 707 | + mergeAnonymousRoles(user.roles()), |
| 708 | + user.fullName(), |
| 709 | + user.email(), |
| 710 | + user.metadata(), |
| 711 | + user.enabled() |
| 712 | + ); |
| 713 | + if (user.isRunAs()) { |
| 714 | + final User authenticatedUserWithMergedRoles = new User( |
| 715 | + user.authenticatedUser().principal(), |
| 716 | + mergeAnonymousRoles(user.authenticatedUser().roles()), |
| 717 | + user.authenticatedUser().fullName(), |
| 718 | + user.authenticatedUser().email(), |
| 719 | + user.authenticatedUser().metadata(), |
| 720 | + user.authenticatedUser().enabled() |
| 721 | + ); |
| 722 | + userWithMergedRoles = new User(userWithMergedRoles, authenticatedUserWithMergedRoles); |
| 723 | + } |
| 724 | + return userWithMergedRoles; |
| 725 | + } else { |
| 726 | + return user; |
| 727 | + } |
| 728 | + } |
| 729 | + |
| 730 | + private String[] mergeAnonymousRoles(String[] existingRoles) { |
| 731 | + String[] mergedRoles = new String[existingRoles.length + anonymousUser.roles().length]; |
| 732 | + System.arraycopy(existingRoles, 0, mergedRoles, 0, existingRoles.length); |
| 733 | + System.arraycopy(anonymousUser.roles(), 0, mergedRoles, existingRoles.length, anonymousUser.roles().length); |
| 734 | + return mergedRoles; |
| 735 | + } |
693 | 736 | }
|
694 | 737 |
|
695 | 738 | abstract static class AuditableRequest {
|
|
0 commit comments