@Override
    protected String resolvePrincipalInternal(final X509Certificate certificate) {
        LOGGER.debug("Resolving principal for [{}]", certificate);
        val sb = new StringBuilder();
        val m = ATTR_PATTERN.matcher(this.principalDescriptor);
        val attrMap = new HashMap<String, AttributeContext>();
        val rdnSequence = new NameReader(certificate).readSubject();
        while (m.find()) {
            val name = m.group(1);
            if (!attrMap.containsKey(name)) {
                val values = getAttributeValues(rdnSequence, StandardAttributeType.fromName(name));
                attrMap.put(name, new AttributeContext(values));
            }
            val context = attrMap.get(name);
            m.appendReplacement(sb, context.nextValue());
        }
        m.appendTail(sb);
        return sb.toString();
    }
Gets the values of the given attribute contained in the DN.
<p><strong>NOTE:</strong> no escaping is done on special characters in the
values, which could be different from what would appear in the string
representation of the DN.</p>
Iterates sequence in reverse order as specified in section 2.1 of RFC 2253.

@param rdnSequence list of relative distinguished names
                   that contains the attributes comprising the DN.
@param attribute   Attribute whose values will be retrieved.
@return The attribute values for the given attribute in the order they
appear would appear in the string representation of the DN or an empty
array if the given attribute does not exist.
support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/principal/X509SubjectPrincipalResolver.java