Es gibt kein solches Ereignis in Java EE. Noch. Als Teil von JSR375 wird die Container-verwaltete Sicherheit vollständig überarbeitet, da sie derzeit scattered über verschiedene Containerimplementierungen hinweg und nicht cross-container-kompatibel ist. Dies wird in dieser Java EE 8 Security API Präsentation dargestellt.
Es ist bereits eine Referenzimplementierung der Sicherheits-API in Bearbeitung, Soteria, die unter anderem von meinem Kollegen Arjan Tijms entwickelt wurde. Mit der neuen Security API wird CDI verwendet, um Authentifizierungsereignisse auszulösen, die Sie einfach @Observes
. Die Diskussion der Spezifikation erfolgte in this mailing list thread. In Soteria ist es noch nicht konkret umgesetzt.
Bis dahin unter der Annahme FORM
basierte Authentifizierung, wobei der Benutzerprinzipal intern in der Sitzung gespeichert ist, ist Ihre beste Wette manuell ein Servlet-Filter einchecken, wenn ein Benutzer Principal in der Anfrage während Ihrer Darstellung des angemeldeten Benutzers vorhanden ist fehlt in der HTTP-Sitzung.
@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);
}
Sie beachten Sie, dass auf /j_security_check
einen Filter Registrierung ist nicht garantiert, als anständiger Container wird es handhaben innen zu arbeiten, bevor die ersten Filter betroffen sind, aus offensichtlichen Sicherheitsgründen (vom Benutzer bereitgestellten Filter kann die Anfrage in eine manipulieren schlechter Weg, entweder versehentlich oder bewusst).
Wenn Sie jedoch einen Java EE-Server verwenden, der den Undertow Servletcontainer verwendet, wie WildFly, dann gibt es eine sauberere Möglichkeit, seine internen Benachrichtigungsereignisse anzuhängen und dann benutzerdefinierte CDI-Ereignisse auszulösen.Dies ist in this blog von Arjan Tijms konkretisiert. Wie im Blog gezeigt, können Sie schließlich mit einer CDI Bean wie folgt enden:
@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
}
}
Ich hasse SO dafür, dass ich nicht die Chance bekomme, mehr als einmal zu upvoten! Sagte, dass, Undertow-Lösung wird Ihre Webapp nicht vollständig portabel, das ist etwas, was ich gerade vermeiden möchte.An dieser Stelle ist das Hinzufügen eines Filters für eine Reihe von URLs wahrscheinlich die Lösung, die ich anwenden werde. Ich war nur etwas besorgt wegen des Overheads, der von einem so weit verbreiteten Filter kommen könnte, aber am Ende des Tages am meisten von der Zeit wird es nur zu einer nicht verifizierten if-Bedingung führen ... denkst du, es wäre ein "akzeptabler Overhead"? –
:) SO hat das Konzept von [Bounties] (http://meta.stackexchange.com/questions/16065/how-does-the-boundy-system-work). Darüber hinaus haben einige Benutzer eine Wunschliste oder einen Link auf ihr Profil. Was den Overhead betrifft, ist das wirklich vernachlässigbar. Ein paar Nanosekunden vielleicht. Es gibt in einer vollwertigen Webanwendung viel bessere Dinge zu optimieren. – BalusC