package com.hwlcn.security.web.filter.authc;
import com.hwlcn.security.authc.AuthenticationException;
import com.hwlcn.security.authc.AuthenticationToken;
import com.hwlcn.security.authc.UsernamePasswordToken;
import com.hwlcn.security.authz.UnauthenticatedException;
import com.hwlcn.security.subject.Subject;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Arrays;
public abstract class AuthenticatingFilter extends AuthenticationFilter {
public static final String PERMISSIVE = "permissive";
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
AuthenticationToken token = createToken(request, response);
if (token == null) {
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
"must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}
try {
Subject subject = getSubject(request, response);
subject.login(token);
return onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException e) {
return onLoginFailure(token, e, request, response);
}
}
protected abstract AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception;
protected AuthenticationToken createToken(String username, String password,
ServletRequest request, ServletResponse response) {
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
return createToken(username, password, rememberMe, host);
}
protected AuthenticationToken createToken(String username, String password,
boolean rememberMe, String host) {
return new UsernamePasswordToken(username, password, rememberMe, host);
}
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception {
return true;
}
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
ServletRequest request, ServletResponse response) {
return false;
}
protected String getHost(ServletRequest request) {
return request.getRemoteHost();
}
protected boolean isRememberMe(ServletRequest request) {
return false;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
return super.isAccessAllowed(request, response, mappedValue) ||
(!isLoginRequest(request, response) && isPermissive(mappedValue));
}
protected boolean isPermissive(Object mappedValue) {
if (mappedValue != null) {
String[] values = (String[]) mappedValue;
return Arrays.binarySearch(values, PERMISSIVE) >= 0;
}
return false;
}
@Override
protected void cleanup(ServletRequest request, ServletResponse response, Exception existing) throws ServletException, IOException {
if (existing instanceof UnauthenticatedException || (existing instanceof ServletException && existing.getCause() instanceof UnauthenticatedException)) {
try {
onAccessDenied(request, response);
existing = null;
} catch (Exception e) {
existing = e;
}
}
super.cleanup(request, response, existing);
}
}