Additional event when user not found. Contributed by Karel Miarka.

This commit is contained in:
Ben Alex 2004-08-12 00:07:08 +00:00
parent 89aa894015
commit da5469fed0
5 changed files with 84 additions and 9 deletions

View File

@ -30,7 +30,8 @@ contributions to the Acegi Security System for Spring project:
* Ray Krueger is a current member of the development team. * Ray Krueger is a current member of the development team.
* Karel Miarka contributed a fix for EH-CACHE NPEs. * Karel Miarka contributed a fix for EH-CACHE NPEs and additional event
handling for DaoAuthenticationProvider.
* Anyone else I've forgotten (please let me know so I can correct this). * Anyone else I've forgotten (please let me know so I can correct this).

View File

@ -20,12 +20,14 @@ import net.sf.acegisecurity.AuthenticationException;
import net.sf.acegisecurity.AuthenticationServiceException; import net.sf.acegisecurity.AuthenticationServiceException;
import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.DisabledException; import net.sf.acegisecurity.DisabledException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.UserDetails; import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.AuthenticationProvider; import net.sf.acegisecurity.providers.AuthenticationProvider;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.cache.NullUserCache; import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureDisabledEvent; import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureDisabledEvent;
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailurePasswordEvent; import net.sf.acegisecurity.providers.dao.event.AuthenticationFailurePasswordEvent;
import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureUsernameNotFoundEvent;
import net.sf.acegisecurity.providers.dao.event.AuthenticationSuccessEvent; import net.sf.acegisecurity.providers.dao.event.AuthenticationSuccessEvent;
import net.sf.acegisecurity.providers.encoding.PasswordEncoder; import net.sf.acegisecurity.providers.encoding.PasswordEncoder;
import net.sf.acegisecurity.providers.encoding.PlaintextPasswordEncoder; import net.sf.acegisecurity.providers.encoding.PlaintextPasswordEncoder;
@ -190,7 +192,19 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
if (user == null) { if (user == null) {
cacheWasUsed = false; cacheWasUsed = false;
user = getUserFromBackend(username);
try {
user = getUserFromBackend(username);
} catch (BadCredentialsException ex) {
if (this.context != null) {
context.publishEvent(new AuthenticationFailureUsernameNotFoundEvent(
authentication,
new User(username, "*****", false,
new GrantedAuthority[0])));
}
throw ex;
}
} }
if (!user.isEnabled()) { if (!user.isEnabled()) {

View File

@ -0,0 +1,40 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.providers.dao.event;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.UserDetails;
/**
* Application event which indicates authentication failure due to nonexistent
* username. <code>AuthenticationFailureUsernameNotFoundEvent.getUser()</code>
* returns an instance of <code>User</code>, where the username is filled by
* the <code>String</code> provided at login attempt. The other properties are
* set to non-<code>null</code> values without any meaning.
*
* @author Karel Miarka
*/
public class AuthenticationFailureUsernameNotFoundEvent
extends AuthenticationEvent {
//~ Constructors ===========================================================
// ~ Constructors ===========================================================
public AuthenticationFailureUsernameNotFoundEvent(
Authentication authentication, UserDetails user) {
super(authentication, user);
}
}

View File

@ -45,7 +45,8 @@ public class LoggerListener implements ApplicationListener {
AuthenticationFailurePasswordEvent authEvent = (AuthenticationFailurePasswordEvent) event; AuthenticationFailurePasswordEvent authEvent = (AuthenticationFailurePasswordEvent) event;
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled()) {
logger.warn("Authentication failed due to incorrect password for user: " logger.warn(
"Authentication failed due to incorrect password for user: "
+ authEvent.getUser().getUsername() + "; details: " + authEvent.getUser().getUsername() + "; details: "
+ authEvent.getAuthentication().getDetails()); + authEvent.getAuthentication().getDetails());
} }
@ -62,6 +63,17 @@ public class LoggerListener implements ApplicationListener {
} }
} }
if (event instanceof AuthenticationFailureUsernameNotFoundEvent) {
AuthenticationFailureUsernameNotFoundEvent authEvent = (AuthenticationFailureUsernameNotFoundEvent) event;
if (logger.isWarnEnabled()) {
logger.warn(
"Authentication failed due to nonexistent username: "
+ authEvent.getUser().getUsername() + "; details: "
+ authEvent.getAuthentication().getDetails());
}
}
if (event instanceof AuthenticationSuccessEvent) { if (event instanceof AuthenticationSuccessEvent) {
AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event; AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;

View File

@ -1018,22 +1018,31 @@
<listitem> <listitem>
<para><literal>AuthenticationFailureDisabledEvent</literal> is <para><literal>AuthenticationFailureDisabledEvent</literal> is
published when an authentication request is unsuccessful because published when an authentication request is unsuccessful because
the returned <literal>User</literal> is disabled. This is normally the returned <literal>UserDetails</literal> is disabled. This is
the case when an account is locked.</para> normally the case when an account is locked.</para>
</listitem>
<listitem>
<para><literal>AuthenticationFailureUsernameNotFoundEvent</literal>
is published when an authentication request is unsuccessful
because the <literal>AuthenticationDao</literal> could not locate
the <literal>UserDetails</literal>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><literal>AuthenticationFailurePasswordEvent</literal> is <para><literal>AuthenticationFailurePasswordEvent</literal> is
published when an authentication request is unsuccessful because published when an authentication request is unsuccessful because
the presented password did not match that in the the presented password did not match that in the
<literal>User</literal>.</para> <literal>UserDetails</literal>.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para>Each event contains two objects: the <para>Each event contains two objects: the
<literal>Authentication</literal> object that represented the <literal>Authentication</literal> object that represented the
authentication request, and the <literal>UserDetails</literal> object authentication request, and the <literal>UserDetails</literal> object
that was found in response to the authentication request. The that was found in response to the authentication request (clearly the
latter will be a dummy object in the case of
<literal>AuthenticationFailureUsernameNotFoundEvent</literal>). The
<literal>Authentication</literal> interface provides a <literal>Authentication</literal> interface provides a
<literal>getDetails()</literal> method which often includes <literal>getDetails()</literal> method which often includes
information that event consumers may find useful (eg the TCP/IP information that event consumers may find useful (eg the TCP/IP
@ -1150,8 +1159,7 @@
<title>JaasAuthenticationProvider</title> <title>JaasAuthenticationProvider</title>
<para>The <literal>JaasAuthenticationProvider</literal> attempts to <para>The <literal>JaasAuthenticationProvider</literal> attempts to
authenticate a users principal and credentials through JAAS. authenticate a users principal and credentials through JAAS.</para>
</para>
<para>Lets assume we have a JAAS login configuration file, <para>Lets assume we have a JAAS login configuration file,
<literal>/WEB-INF/login.conf</literal>, with the following <literal>/WEB-INF/login.conf</literal>, with the following