private String getUPNStringFromSequence(final ASN1Sequence seq) {
        val id = Optional.ofNullable(seq).map(asn1Encodables -> ASN1ObjectIdentifier.getInstance(asn1Encodables.getObjectAt(0))).orElse(null);
        if (id != null && UPN_OBJECTID.equals(id.getId())) {
            val obj = (ASN1TaggedObject) seq.getObjectAt(1);
            val primitiveObj = obj.getBaseObject();

            val func = FunctionUtils.doIf(Predicates.instanceOf(ASN1TaggedObject.class),
                () -> ASN1TaggedObject.getInstance(primitiveObj).getBaseObject(),
                () -> primitiveObj);
            val prim = func.apply(primitiveObj);

            if (prim instanceof final ASN1OctetString instance) {
                return new String(instance.getOctets(), StandardCharsets.UTF_8);
            }
            if (prim instanceof final ASN1String instance) {
                return instance.getString();
            }
        }
        return null;
    }
Get UPN String.

@param seq ASN1Sequence abstraction representing subject alternative name.
           First element is the object identifier, second is the object itself.
@return UPN string or null
support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/principal/X509UPNExtractorUtils.java