package org.apereo.cas.integration.pac4j.authentication.handler.support;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.handler.PrincipalNameTransformer;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
import org.pac4j.core.credentials.authenticator.Authenticator;
import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.security.auth.login.AccountNotFoundException;
import java.security.GeneralSecurityException;
/**
* Pac4j authentication handler which works on a CAS username / password credential
* and uses a pac4j authenticator and profile creator to play authentication.
*
* @author Jerome Leleu
* @since 4.2.0
*/
public class UsernamePasswordWrapperAuthenticationHandler
extends AbstractWrapperAuthenticationHandler<UsernamePasswordCredential, UsernamePasswordCredentials> {
private static final Logger LOGGER = LoggerFactory.getLogger(UsernamePasswordWrapperAuthenticationHandler.class);
/**
* The underlying pac4j authenticator.
*/
protected Authenticator<UsernamePasswordCredentials> authenticator = new SimpleTestUsernamePasswordAuthenticator();
/**
* PasswordEncoder to be used by subclasses to encode passwords for
* comparing against a resource.
*/
private PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance();
/**
* PrincipalNameTransformer to be used by subclasses to transform the principal name.
*/
private PrincipalNameTransformer principalNameTransformer = formUserId -> formUserId;
public UsernamePasswordWrapperAuthenticationHandler(final String name, final ServicesManager servicesManager, final PrincipalFactory principalFactory,
final Integer order) {
super(name, servicesManager, principalFactory, order);
}
@Override
protected UsernamePasswordCredentials convertToPac4jCredentials(final UsernamePasswordCredential casCredential)
throws GeneralSecurityException, PreventedException {
LOGGER.debug("CAS credentials: [{}]", casCredential);
final String username = this.principalNameTransformer.transform(casCredential.getUsername());
if (username == null) {
throw new AccountNotFoundException("Username is null.");
}
final String password = this.passwordEncoder.encode(casCredential.getPassword());
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password, getClass().getSimpleName());
LOGGER.debug("pac4j credentials: [{}]", credentials);
return credentials;
}
@Override
protected Authenticator<UsernamePasswordCredentials> getAuthenticator(final Credential credential) {
return this.authenticator;
}
public void setAuthenticator(final Authenticator<UsernamePasswordCredentials> authenticator) {
this.authenticator = authenticator;
}
@Override
protected Class<UsernamePasswordCredential> getCasCredentialsType() {
return UsernamePasswordCredential.class;
}
public PasswordEncoder getPasswordEncoder() {
return this.passwordEncoder;
}
public void setPasswordEncoder(final PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
public PrincipalNameTransformer getPrincipalNameTransformer() {
return this.principalNameTransformer;
}
public void setPrincipalNameTransformer(final PrincipalNameTransformer principalNameTransformer) {
this.principalNameTransformer = principalNameTransformer;
}
}