我有一个JSF/Primefaces应用程序
我现在需要支持Kerberos身份验证,并且有多个组件将使用Kerberos凭据(数据库连接、应用程序连接等)。
我需要做的是用这样的代码包装每个需要凭证的操作:
Subject.doAs(loginContext.getSubject(), new PrivilegedExceptionAction<Long>() {
@Override
public Long run() throws UnknownHostException {
// Perform operation on database for example
...
}
});
但是有成千上万个这样的地方我需要包装。
相反,我真正想做的是包装入口点,它将涵盖系统中的所有操作。
我正在考虑子类化FacesServlet,只是有一个服务方法,将超类的服务包装在这个doa中。
这样做是正确的吗?还是有更合适的JSF模式?如果有人有这样做的例子,不介意分享相关代码,非常感谢。
编辑-我现在看到FacesServlet是一个最终类,所以我不能继承它。但是我仍然可以用一个FacesServlet的嵌入式实例来包装它。但我确信我必须把生命周期弄对——以前有人这样做过吗,可以分享经验吗?
您可以为所有的data/jsf请求添加一个过滤器。过滤器将在转发请求之前验证请求是否具有Kerberos密钥/证书。
如果你想验证你的服务,那么你可以使用像Spring AOP这样的东西,并添加覆盖你的服务的advice
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class KerberosAspectJoinPoint {
@Before("execution(public void com.service...*(*))")
public void kerberosAdvice(JoinPoint joinPoint){
//Verify Authentication and throw error;
}
}
或者您可以通过创建注释并将注释添加到您的服务方法来进行选择您想要验证,
public @interface VerifyAuth {
}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class KerberosAspectJoinPoint {
@Before("@annotation(com.test.VerifyAuth)")
public void myAdvice(){
//Verify Authentication and throw error;
}
}
但是如果你打算覆盖应用程序中的所有内容,那么在过滤器中进行验证似乎是web应用程序的好地方。
class LoginFilter implements Filter {
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws
IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
Subject.doAs(lc.getSubject(), new LoginAction(chain,
request,response));
}
}
class LoginAction implements java.security.PrivilegedAction {
private HttpServletRequest request;
private HttpServletResponse response;
private FilterChain chain;
public LoginAction(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) {
this.request = request;
this.response = response;
this.chain = chain;
}
public Object run() {
doForward(request, response, chain);
return null;
}
private static void doForward (HttpServletRequest request,
HttpServletResponse response, FilterChain chain) {
chain.doFilter(request, response);
}
}