package org.pac4j.http.client.indirect;
import org.pac4j.core.client.IndirectClient;
import org.pac4j.core.redirect.RedirectAction;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.credentials.authenticator.Authenticator;
import org.pac4j.core.exception.CredentialsException;
import org.pac4j.core.exception.HttpAction;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.creator.ProfileCreator;
import org.pac4j.core.util.CommonHelper;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
import org.pac4j.core.credentials.extractor.BasicAuthExtractor;
/**
* <p>This class is the client to authenticate users through HTTP basic auth. It was previously named: <code>BasicAuthClient</code>.</p>
* <p>For authentication, the user is redirected to the callback url. If the user is not authenticated by basic auth, a
* specific exception : {@link HttpAction} is returned which must be handled by the application to force
* authentication.</p>
*
* @author Jerome Leleu
* @since 1.8.0
*/
public class IndirectBasicAuthClient extends IndirectClient<UsernamePasswordCredentials, CommonProfile> {
private String realmName = "authentication required";
public IndirectBasicAuthClient() {}
public IndirectBasicAuthClient(final Authenticator usernamePasswordAuthenticator) {
defaultAuthenticator(usernamePasswordAuthenticator);
}
public IndirectBasicAuthClient(final String realmName, final Authenticator usernamePasswordAuthenticator) {
this.realmName = realmName;
defaultAuthenticator(usernamePasswordAuthenticator);
}
public IndirectBasicAuthClient(final Authenticator usernamePasswordAuthenticator, final ProfileCreator profileCreator) {
defaultAuthenticator(usernamePasswordAuthenticator);
defaultProfileCreator(profileCreator);
}
@Override
protected void clientInit(final WebContext context) {
CommonHelper.assertNotBlank("realmName", this.realmName);
defaultRedirectActionBuilder(webContext -> RedirectAction.redirect(computeFinalCallbackUrl(webContext)));
defaultCredentialsExtractor(new BasicAuthExtractor(getName()));
}
@Override
protected UsernamePasswordCredentials retrieveCredentials(final WebContext context) throws HttpAction {
CommonHelper.assertNotNull("credentialsExtractor", getCredentialsExtractor());
CommonHelper.assertNotNull("authenticator", getAuthenticator());
final UsernamePasswordCredentials credentials;
try {
// retrieve credentials
credentials = getCredentialsExtractor().extract(context);
logger.debug("credentials : {}", credentials);
if (credentials == null) {
throw HttpAction.unauthorized("Requires authentication", context, this.realmName);
}
// validate credentials
getAuthenticator().validate(credentials, context);
} catch (final CredentialsException e) {
throw HttpAction.unauthorized("Requires authentication", context, this.realmName);
}
return credentials;
}
public String getRealmName() {
return realmName;
}
public void setRealmName(String realmName) {
this.realmName = realmName;
}
@Override
public String toString() {
return CommonHelper.toString(this.getClass(), "callbackUrl", this.callbackUrl, "name", getName(),
"realmName", this.realmName, "extractor", getCredentialsExtractor(), "authenticator", getAuthenticator(),
"profileCreator", getProfileCreator());
}
}