package org.apereo.cas.support.saml.authentication; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apereo.cas.authentication.AuthenticationTransaction; import org.apereo.cas.authentication.Credential; import org.apereo.cas.authentication.HttpBasedServiceCredential; import org.apereo.cas.authentication.UsernamePasswordCredential; import org.apereo.cas.authentication.AuthenticationBuilder; import org.apereo.cas.authentication.metadata.BaseAuthenticationMetadataPopulator; import java.util.HashMap; import java.util.Map; /** * AuthenticationMetaDataPopulator to retrieve the Authentication Type. * <p> * Note: Authentication Methods are exposed under the key: * {@code samlAuthenticationStatement::authMethod} in the Authentication * attributes map. * * @author Scott Battaglia * @author Marvin S. Addison * @since 3.1 */ public class SamlAuthenticationMetaDataPopulator extends BaseAuthenticationMetadataPopulator { /** The Constant ATTRIBUTE_AUTHENTICATION_METHOD. */ public static final String ATTRIBUTE_AUTHENTICATION_METHOD = "samlAuthenticationStatementAuthMethod"; /** The Constant AUTHN_METHOD_PASSWORD. */ public static final String AUTHN_METHOD_PASSWORD = "urn:oasis:names:tc:SAML:1.0:am:password"; /** The Constant AUTHN_METHOD_SSL_TLS_CLIENT. */ public static final String AUTHN_METHOD_SSL_TLS_CLIENT = "urn:ietf:rfc:2246"; /** The Constant AUTHN_METHOD_X509_PUBLICKEY. */ public static final String AUTHN_METHOD_X509_PUBLICKEY = "urn:oasis:names:tc:SAML:1.0:am:X509-PKI"; /** The Constant AUTHN_METHOD_UNSPECIFIED. */ public static final String AUTHN_METHOD_UNSPECIFIED = "urn:oasis:names:tc:SAML:1.0:am:unspecified"; private Map<String, String> authenticationMethods = new HashMap<>(); /** * Instantiates a new SAML authentication meta data populator. */ public SamlAuthenticationMetaDataPopulator() { this.authenticationMethods.put( HttpBasedServiceCredential.class.getName(), AUTHN_METHOD_SSL_TLS_CLIENT); this.authenticationMethods.put( UsernamePasswordCredential.class.getName(), AUTHN_METHOD_PASSWORD); // Next two classes are in other modules, so avoid using Class#getName() to prevent circular dependency this.authenticationMethods.put( "org.apereo.cas.adaptors.trusted.authentication.principal.PrincipalBearingCredentials", AUTHN_METHOD_UNSPECIFIED); this.authenticationMethods.put( "org.apereo.cas.adaptors.x509.authentication.principal.X509CertificateCredentials", AUTHN_METHOD_X509_PUBLICKEY); } @Override public void populateAttributes(final AuthenticationBuilder builder, final AuthenticationTransaction transaction) { final String credentialsClass = transaction.getCredential().getClass().getName(); final String authenticationMethod = this.authenticationMethods.get(credentialsClass); builder.addAttribute(ATTRIBUTE_AUTHENTICATION_METHOD, authenticationMethod); } @Override public boolean supports(final Credential credential) { return true; } /** * Map of user-defined mappings. Note it is possible to override the * defaults. Mapping should be of the following type: * <pre>Package/Class Name as String -> Name SAML Type</pre> * <p> * Example: ({@code "HttpBasedServiceCredential" * -> SAMLAuthenticationStatement.AuthenticationMethod_SSL_TLS_Client}) * * @param userDefinedMappings map of user defined authentication types. */ public void setUserDefinedMappings(final Map<String, String> userDefinedMappings) { this.authenticationMethods.putAll(userDefinedMappings); } @Override public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()) .append("authenticationMethods", authenticationMethods) .toString(); } }