We would like to revisit the `Authentication` class to make it provide better and easier to use interface to the consumers. 

#79809 enables run-as for all authentication schemes in addition to `realm` which is already supported. This adds more complexity to an `Authentication` object and how it should be used. For an example, building the role associated to an user now has to consider whether the user is the authenticated user or run-as user and the authentication scheme of the authenticated user. The existing `Authentication` class can answer all these question today. But its interface and internals are not aligned for these questions and the usage is error prone. For example, the `Authentication` object itself does not know whether the user has run-as. This information is kept by the `User` object. If the `User` object has an `authenticatedUser`, it's the run-as user. Otherwise it is not. But the information about realms for each `User` is directly kept in `Authentication`. Therefore, for full picture, the caller must check both `User` and `Authentication` realms and understands the nuance of their differenent combinations. 

- [x] Refactor CompositeRolesStore to separate roleDescriptors resolving (#80926)
- [ ] Move effective role descriptor checking from Resolver to CompositeRolesStore
- [x] https://github.com/elastic/elasticsearch/issues/81192
- [ ] Replace Authentication with AuthenticationContext in places other than CompositeRolesStore
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
return Objects.hash(super.hashCode(), authenticatingUser);
        }
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("RunAsUser[username=").append(principal());
            sb.append(",roles=[").append(Strings.arrayToCommaDelimitedString(roles())).append("]");
            sb.append(",fullName=").append(fullName());
            sb.append(",email=").append(email());
            sb.append(",metadata=");
            sb.append(metadata());
            if (enabled() == false) {
                sb.append(",(disabled)");
            }
            sb.append(",authenticatingUser=[").append(authenticatingUser.toString()).append("]");
            sb.append("]");
            return sb.toString();
        }
    }
    public static class AuthenticationSerializationHelper {
        private AuthenticationSerializationHelper() {}
        public static User readUserFrom(StreamInput input) throws IOException {
            final boolean isInternalUser = input.readBoolean();
            final String username = input.readString();
            if (isInternalUser) {
                if (SystemUser.NAME.equals(username)) {
                    return SystemUser.INSTANCE;
                } else if (XPackUser.NAME.equals(username)) {
                    return XPackUser.INSTANCE;
                } else if (XPackSecurityUser.NAME.equals(username)) {