package org.apereo.cas.authentication; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import org.apache.commons.codec.binary.StringUtils; import org.apereo.cas.authentication.principal.PrincipalFactory; import org.apereo.cas.integration.pac4j.authentication.handler.support.UsernamePasswordWrapperAuthenticationHandler; import org.apereo.cas.services.ServicesManager; import org.pac4j.core.credentials.UsernamePasswordCredentials; import org.pac4j.core.credentials.authenticator.Authenticator; import org.pac4j.core.credentials.password.PasswordEncoder; import org.pac4j.mongo.credentials.authenticator.MongoAuthenticator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * An authentication handler to verify credentials against a MongoDb instance. * @author Misagh Moayyed * @since 4.2.0 */ public class MongoAuthenticationHandler extends UsernamePasswordWrapperAuthenticationHandler { private static final Logger LOGGER = LoggerFactory.getLogger(MongoAuthenticationHandler.class); private String collectionName; private String mongoHostUri; private String attributes; private String usernameAttribute; private String passwordAttribute; private PasswordEncoder mongoPasswordEncoder = new NoOpPasswordEncoder(); public MongoAuthenticationHandler(final String name, final ServicesManager servicesManager, final PrincipalFactory principalFactory, final String collectionName, final String mongoHostUri, final String attributes, final String usernameAttribute, final String passwordAttribute, final PasswordEncoder mongoPasswordEncoder) { super(name, servicesManager, principalFactory, null); this.collectionName = collectionName; this.mongoHostUri = mongoHostUri; this.attributes = attributes; this.usernameAttribute = usernameAttribute; this.passwordAttribute = passwordAttribute; this.mongoPasswordEncoder = mongoPasswordEncoder; } @Override protected Authenticator<UsernamePasswordCredentials> getAuthenticator(final Credential credential) { final MongoClientURI uri = new MongoClientURI(this.mongoHostUri); final MongoClient client = new MongoClient(uri); LOGGER.info("Connected to MongoDb instance @ [{}] using database [{}]", uri.getHosts(), uri.getDatabase()); final MongoAuthenticator mongoAuthenticator = new MongoAuthenticator(client, this.attributes); mongoAuthenticator.setUsersCollection(this.collectionName); mongoAuthenticator.setUsersDatabase(uri.getDatabase()); mongoAuthenticator.setUsernameAttribute(this.usernameAttribute); mongoAuthenticator.setPasswordAttribute(this.passwordAttribute); mongoAuthenticator.setPasswordEncoder(this.mongoPasswordEncoder); return mongoAuthenticator; } private static class NoOpPasswordEncoder implements PasswordEncoder { @Override public String encode(final String s) { LOGGER.debug("No password encoding shall take place by CAS"); return s; } @Override public boolean matches(final String s, final String s1) { return StringUtils.equals(s, s1); } } }