我有一个JSF / Primefaces应用程序。
我现在需要支持Kerberos身份验证,并且有多个组件将使用Kerberos凭据(数据库连接,应用程序连接等)。
我需要做的是将每个需要凭据的操作包装成如下代码:
Subject.doAs(loginContext.getSubject(), new PrivilegedExceptionAction<Long>() {
@Override
public Long run() throws UnknownHostException {
// Perform operation on database for example
...
}
});
但是我需要包含数千个这样的地方。
相反,我真正想做的是包装将覆盖系统中所有操作的入口点。
我正在考虑继承FacesServlet,并且只有一个服务方法,它将超类的服务包装在这个doAs中。
这是做这样的事情的正确方法还是有更合适的JSF模式? 如果有人有这样做的例子,并且不介意分享相关代码,那就非常感激。
编辑 - 我现在看到FacesServlet是一个最终类,所以我可以将它子类化。但我仍然可以使用FacesServlet的嵌入式实例来包装它。但是我确定我必须让生命周期正确 - 有没有人以前做过这个并且可以分享经验?
答案 0 :(得分:1)
您可以通过为所有数据/ jsf请求添加过滤器来完成此操作。在转发请求之前,过滤器将验证请求是否具有Kerberos密钥/证书。
如果您想验证您的服务,那么您可以使用Spring AOP之类的东西并添加涵盖您服务的Advise
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);
}
}