package org.apereo.cas.support.saml; import org.apache.cxf.sts.token.realm.SAMLRealmCodec; import org.apache.wss4j.common.saml.SAMLKeyInfo; import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.cert.X509Certificate; /** * This is {@link SamlAssertionRealmCodec}. * Parse the realm from a SAML assertion. * @author Misagh Moayyed * @since 5.1.0 */ public class SamlAssertionRealmCodec implements SAMLRealmCodec { private static final Logger LOGGER = LoggerFactory.getLogger(SamlAssertionRealmCodec.class); private final String realm; private boolean uppercase = true; public SamlAssertionRealmCodec(final String realm) { this.realm = realm; } @Override public String getRealmFromToken(final SamlAssertionWrapper assertion) { final SAMLKeyInfo ki = assertion.getSignatureKeyInfo(); final X509Certificate[] certs = ki.getCerts(); final String parsed = parseCNValue(certs[0].getSubjectX500Principal().getName()); LOGGER.debug("Realm parsed from certificate CN of the SAML assertion: [{}]", parsed); if (parsed.equals(realm)) { return parsed; } LOGGER.warn("Retrieved realm from CN of SAML assertion certificate [{}] does not match the CAS realm [{}]. " + "Beware that realm mismatch does requires configuration to implement realm relationships or identity mapping", parsed, realm); return parsed; } private String parseCNValue(final String name) { final int len = name.indexOf(",") > 0 ? name.indexOf(",") : name.length(); String realm = name.substring(name.indexOf("CN=") + "CN=".length(), len); if (uppercase) { realm = realm.toUpperCase(); } return realm; } }