Java EE身份验证:如何捕获登录事件?
给定为
Java Web应用程序定义的FORM类型的身份验证机制,如何在重定向到请求的资源之前捕获登录执行的事件?是否有任何类型的监听器,我可以在用户登录时将我的代码执行?
我觉得定义过滤器不是最好的解决方案,因为过滤器链接到资源,即使用户已经过身份验证并要求资源,也会调用过滤器.我想知道是否只有登录事件触发了一些类/方法. 解决方法
Java EE中没有这样的事件.然而.作为
JSR375的一部分,容器管理的安全性将完全重做,因为它在不同的容器实现中目前是
scattered,并且不是跨容器兼容的.这在
Java EE 8 Security API演示文稿中有所概述.
已经有一个正在进行的安全API的参考实现,Soteria,由我的同伴Arjan Tijms开发.使用新的Security API,CDI将用于触发您只能@Observes的身份验证事件.关于规范的讨论发生在this mailing list thread.它尚未在Soteria中具体实施. 在此之前,假设基于FORM的身份验证(其中用户主体在内部存储在会话中),最好的办法是手动检查servlet过滤器,如果请求中存在用户主体,而您的登录用户的表示不存在HTTP会话. @Override public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) { HttpServletRequest request = (HttpServletRequest) req; String username = request.getRemoteUser(); if (username != null && request.getSession().getAttribute("user") == null) { // First-time login. You can do your thing here. User user = yourUserService.find(username); request.getSession().setAttribute("user",user); } chain.doFilter(req,res); } 请注意,在/ j_security_check上注册过滤器不能保证工作,因为一个像样的容器会在第一个过滤器被命中之前在内部处理它,出于明显的安全原因(用户提供的过滤器可能会以错误的方式操纵请求,无论是意外还是awarely). 如果您碰巧使用Java EE服务器使用Undertow servletcontainer,例如WildFly,那么有一种更干净的方式来挂钩其内部通知事件,然后触发自定义CDI事件.这是在Arjan Tijms的this blog充实.如博客所示,你最终可以得到一个像这样的CDI bean: @SessionScoped public class SessionAuthListener implements Serializable { private static final long serialVersionUID = 1L; public void onAuthenticated(@Observes AuthenticatedEvent event) { String username = event.getUserPrincipal().getName(); // Do something with name,e.g. audit,// load User instance into session,etc } public void onLoggedOut(@Observes LoggedOutEvent event) { // take some action,null out User,etc } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |