package jenkins.security;
import hudson.Extension;
import hudson.model.User;
import org.acegisecurity.Authentication;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.logging.Logger;
import static java.util.logging.Level.*;
/**
* Checks if the password given in the BASIC header matches the user's API token.
*
* @author Kohsuke Kawaguchi
* @since 1.576
*/
@Extension
public class BasicHeaderApiTokenAuthenticator extends BasicHeaderAuthenticator {
@Override
public Authentication authenticate(HttpServletRequest req, HttpServletResponse rsp, String username, String password) throws ServletException {
// attempt to authenticate as API token
User u = User.getById(username, true);
ApiTokenProperty t = u.getProperty(ApiTokenProperty.class);
if (t!=null && t.matchesPassword(password)) {
try {
return u.impersonate();
} catch (UsernameNotFoundException x) {
// The token was valid, but the impersonation failed. This token is clearly not his real password,
// so there's no point in continuing the request processing. Report this error and abort.
LOGGER.log(WARNING, "API token matched for user "+username+" but the impersonation failed",x);
throw new ServletException(x);
} catch (DataAccessException x) {
throw new ServletException(x);
}
}
return null;
}
private static final Logger LOGGER = Logger.getLogger(BasicHeaderApiTokenAuthenticator.class.getName());
}