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;
}
}