Well,
JSF Rule #1 is that whenever you have lots of JSF-specific code, you're probably doing it wrong. JSF was designed to mostly use POJOs and work in the background, so grabbing the FacesContext and messing around with
JEE and JSF internals is generally a red flag.
I'm sorry to say that I
still haven't read very far into the Spring Security book I won on the Ranch a while back. Mostly I just use the basic JEE standard container security, which doesn't require any user-written login code at all.
I can tell you that in JEE basic security that explicitly invoking the URL for j_security_check doesn't work, since the necessary context in the server isn't there. The server sets up the security context for j_security_check when it detects an incoming secured URL request (as defined in
web.xml) for a user who isn't currently logged in and automatically presents the login/loginfail page and processes the form data from those pages wihout any application intervention (or even knowledge - there is no JEE event for "user has logged in").
Two things to always bear in mind:
If a JSF action method returns NULL, that means that the current JSF View is to be re-presented instead of navigating to a new View. DO NOT attempt to manually dispatch, as you'll lose the JSF internal context! Secondly — and most importantly — the View name in the URL is not always going to be the the View that will be presented. In JSF, the URL is more of a session anchor than an absolute indicator of what page will display and the URL view name will often lag behind.
That last part is very important, since JEE container security keys off the incoming URL and NOT on the page to be displayed, so when they don't match, a potential security hazard exists. This is avoided by using the "redirect" option on internal View navigations.