@Override
    public String resolveUsernameInternal(final RegisteredServiceUsernameProviderContext context) {
        var principalId = context.getPrincipal().getId();
        val originalPrincipalAttributes = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        originalPrincipalAttributes.putAll(context.getPrincipal().getAttributes());
        LOGGER.debug("Original principal attributes available for selection of username attribute [{}] are [{}].",
            usernameAttribute, originalPrincipalAttributes);
        val releasePolicyAttributes = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

        FunctionUtils.doIfNull(context.getReleasingAttributes(),
            __ -> releasePolicyAttributes.putAll(getPrincipalAttributesFromReleasePolicy(context)),
            releasePolicyAttributes::putAll);

        LOGGER.debug("Attributes resolved by the release policy available for selection of username attribute [{}] are [{}].",
            usernameAttribute, releasePolicyAttributes);

        if (StringUtils.isBlank(usernameAttribute)) {
            LOGGER.warn("No username attribute is defined for service [{}]. CAS will fall back onto using the default principal id. "
                        + "This is likely a mistake in the configuration of the registered service definition.", context.getRegisteredService().getName());
        } else if (releasePolicyAttributes.containsKey(usernameAttribute)) {
            LOGGER.debug("Attribute release policy for registered service [{}] contains an attribute for [{}]",
                context.getRegisteredService().getServiceId(), usernameAttribute);
            val value = releasePolicyAttributes.get(usernameAttribute);
            principalId = CollectionUtils.wrap(value).getFirst().toString();
        } else if (originalPrincipalAttributes.containsKey(usernameAttribute)) {
            LOGGER.debug("The selected username attribute [{}] was retrieved as a direct "
                         + "principal attribute and not through the attribute release policy for service [{}]. "
                         + "CAS is unable to detect new attribute values for [{}] after authentication unless the attribute "
                         + "is explicitly authorized for release via the service attribute release policy.",
                usernameAttribute, context.getRegisteredService(), usernameAttribute);
            val value = originalPrincipalAttributes.get(usernameAttribute);
            principalId = CollectionUtils.wrap(value).getFirst().toString();
        } else {
            LOGGER.info("Principal [{}] does not have an attribute [{}] among attributes [{}] so CAS cannot "
                        + "provide the user attribute the service expects. "
                        + "CAS will instead return the default principal id [{}]. Ensure the attribute selected as the username "
                        + "is allowed to be released by the service attribute release policy.", principalId, usernameAttribute, releasePolicyAttributes, principalId);
        }
        LOGGER.debug("Principal id to return for [{}] is [{}]. The default principal id is [{}].", context.getService().getId(),
            principalId, context.getPrincipal().getId());
        return principalId.trim();
    }
Determines the username for this registered service based on a principal attribute.
If the attribute is not found, default principal id is returned.

@author Misagh Moayyed
@since 4.1.0
core/cas-server-core-services-api/src/main/java/org/apereo/cas/services/PrincipalAttributeRegisteredServiceUsernameProvider.java