If you are using the FormAuthenticationFilter (the default), you can
also put some logic in your view layer to display the error message.
Ki automatically adds the fully qualified class name of the exception
that was thrown as a request attribute that you can key off of. The
request attribute is based on the "failureKeyAttribute" property of
the filter, so you can adjust in your ini by setting
"authc.failureKeyAttribute=myAttribute" The default attribute name is
"jsecLoginFailure".
By default it is set to the fully qualified classname of the exception
that was thrown during authentication. This would allow you to do
something like (simple JSP example):
<c:if test="${jsecLoginFailure eq
'org.jsecurity.authc.IncorrectCredentialsException'}">
<span class="errors">The password you entered is incorrect.</span>
</c:if>
To do something more custom when authentication fails (but still using
the built-in filter), you could always extend FormAuthenticationFilter
and override the setFailureAttribute(...) method or
onLoginFailure(...) method.
Jeremy
On Apr 6, 2009, at 12:23 PM, Kalle Korhonen wrote:
(Had accidentally sent to dev list, moving to user list).
On Mon, Apr 6, 2009 at 6:07 AM, Jeremy Haile <[email protected]>
wrote:
How authentication failures are displayed to the user is generally
application specific. Usually applications catch
AuthenticationException or some of its subclasses if more granular
reporting is required. They then translate those exceptions into a
validation message and display it to the user. Also, for security
reasons, it's generally not a good idea to tell the user whether
they entered a non-existant username or an incorrect password.
Thanks for reply, Jeremy. Yes, that's obvious.
The simplest example may look like this:
try {
subject.login(...);
} catch (AuthenticationException e) {
// Add something to the request to communicate the login
failure to the user
}
You could add additional catch blocks above the
AuthenticationException to catch different subclass exceptions and
give more specific error messages.
Exactly - that's what I meant when I said "handle login myself".
Exception handling is straight-forwarded in this case. If it wasn't
clear from my previous example, the question was: "How does the
application obtain the failure reason if Ki filtered is configured
to run before the application filters and handles the
authentication"? From what I gathered, the answer is either "not
meant to do so" or "up to you to implement", in which case an
exception specific error-page may be the best solution.
To obtain the originally requested URL from Ki, call
WebUtils.getSavedRequest(...) which will give you back a
SavedRequest object describing the original request. This can be
used to redirect after login.
If you do not want Ki to do the authentication for you, but would
rather execute it in your web framework, you can change the "authc"
filter to pass-thru requests to your web framework. In this case,
Ki assumes that you will handle the authentication yourself which
sounds like the behavior you are after. To get this to work, add the
Ah, missed WebUtils. Yeah, if you read my description again, you'll
see that I'd rather not handle the login myself but in that case the
problem is how do I let the application know in that case why the
authentication failed. It's not simply a choice between filter
handling authentication or the application handling it. If it's
handled in the application, the request may needs to pass through
several other filters, but if it's its handled in the authentication
filter the control has not yet been passed to the lower layers.
Sounds like my solution (let framework handle the success case, but
allow failure case to go through to the application layer) has some
advantages.
Kalle
On Apr 6, 2009, at 2:04 AM, Kalle Korhonen wrote:
Is there a standard/recommend way in JSecurity/Ki to make the reason
for an
authentication failure available to the application? Similarly to
CMA, if Ki
is configured to run before the application servlet/filter, there's no
direct way to tell the application why an authentication try failed.
Is the
recommended mechanism in this case to try to use a standard
"<error-page><exception-type>" element in web.xml or something else?
The
other way around, if I create a login form and handle the
authentication in
it myself (by calling SecurityUtils.getSubject().login() ) is there
a way to
obtain the "originally requested url" from Ki that the security filter
intercepted, then redirected to login page?
Currently I implemented this so that a login form that *could*
handle login,
but a success case is directly handled by Ki. In a failure case, Ki
let's
the request through and I just re-try the authentication to get the
failure
reason. This is a little hackish and results in an unnecessary
authentication try in a failure case, but works surprisingly well
for me as
it allows me to use the "native" error message mechanisms of my web
application framework.
Kalle