且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

的Java EE认证:如何捕捉登录事件?

更新时间:2023-12-04 08:37:16

有是在Java EE中没有这样的事件。然而。由于部分 JSR375 ,容器管理的安全将完全重新设计,因为它是目前在不同的容器implemantations散并为未交容器兼容。这是在这个的Java EE 8安全API presentation概括。

There's no such event in Java EE. Yet. As part of JSR375, container managed security will be totally reworked as it's currently scattered across different container implemantations and is not cross-container compatible. This is outlined in this Java EE 8 Security API presentation.

有已经是一个参考实现正在进行安全API, Soteria 的,由开发之中别人我的同胞阿尔扬Tijms。随着新的安全API,CDI将用于防火认证事件,你可以只 @Observes 。探讨规范发生在这个邮件列表线程。它没有具体的Soteria实施。

There's already a reference implementation of Security API in progress, Soteria, developed by among others my fellow Arjan Tijms. With the new Security API, CDI will be used to fire authentication events which you can just @Observes. Discussion on the specification took place in this mailing list thread. It's not yet concretely implemented in Soteria.

在此之前,假设 FORM 基于身份验证,从而用户主要存储在内部的会议上,你***的赌注是手动Servlet过滤器检查,如果有一个用户主体present请求,而登录用户的您重新presentation是在HTTP会话中缺席。

Until then, assuming FORM based authentication whereby the user principal is internally stored in the session, your best bet is manually checking in a servlet filter if there's an user principal present in the request while your representation of the logged-in user is absent in the HTTP session.

@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)。

Do note that registering a filter on /j_security_check is not guaranteed to work as a decent container will handle it internally before the first filters are hit, for obvious security reasons (user-provided filters could manipulate the request in a bad way, either accidentally or awarely).

如果你碰巧但使用Java EE服务器使用暗潮 servletcontainer,如的 WildFly ,然后有钩其内部通知事件,然后触发自定义事件CDI一个更清洁的方式。这在阿尔扬Tijms的这个博客。由于在博客中所示,您可以最终与一个CDI豆像这样结束:

If you however happen to use a Java EE server uses the Undertow servletcontainer, such as WildFly, then there's a more clean way to hook on its internal notification events and then fire custom CDI events. This is fleshed out in this blog of Arjan Tijms. As shown in the blog, you can ultimately end up with a CDI bean like this:

@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, e.g. audit, null out User, etc
    }
}