package org.apereo.cas.adaptors.radius;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.login.FailedLoginException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* This is {@link RadiusUtils}.
*
* @author Misagh Moayyed
* @since 5.0.0
*/
public final class RadiusUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(RadiusUtils.class);
private RadiusUtils() {
}
/**
* Authenticate pair.
*
* @param username the username
* @param password the password
* @param servers the servers
* @param failoverOnAuthenticationFailure the failover on authentication failure
* @param failoverOnException the failover on exception
* @return the pair
* @throws Exception the exception
*/
public static Pair<Boolean, Optional<Map<String, Object>>> authenticate(final String username, final String password,
final List<RadiusServer> servers,
final boolean failoverOnAuthenticationFailure,
final boolean failoverOnException) throws Exception {
for (final RadiusServer radiusServer : servers) {
LOGGER.debug("Attempting to authenticate [{}] at [{}]", username, radiusServer);
try {
final RadiusResponse response = radiusServer.authenticate(username, password);
if (response != null) {
final Map<String, Object> attributes = new HashMap<>();
response.getAttributes().forEach(attribute -> attributes.put(attribute.getAttributeName(), attribute.getValue().toString()));
return Pair.of(Boolean.TRUE, Optional.of(attributes));
}
if (!failoverOnAuthenticationFailure) {
throw new FailedLoginException("Radius authentication failed for user " + username);
}
LOGGER.debug("failoverOnAuthenticationFailure enabled -- trying next server");
} catch (final Exception e) {
if (!failoverOnException) {
throw e;
}
LOGGER.warn("failoverOnException enabled -- trying next server.", e);
}
}
return Pair.of(Boolean.TRUE, Optional.empty());
}
}