Quantcast

ExcessiveAttemptsException - How to configure

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ExcessiveAttemptsException - How to configure

UncleTupelo
Good Afternoon, I am up and running with Shiro (Spring Web App using the Vaadin framework), so all is good. Thank you all for the effort. So on to my question! Basically I want to lock a User in my Application if they have tried to sign on a number of times and keep getting the password wrong. I notice there is a ExcessiveAttemptsException class and the javadoc says:
Thrown when a system is configured to only allow a certain number of authentication attempts over a period of time and the current session has failed to authenticate successfully within that number. 
So that sounds like what I want to catch and handle (in my case the handling would update a field on a User database row to indicate the Users login was now disabled). But where is this Excessive Attempts configured - or is this an exception I would have to build and throw? If so how would I know how many times the Subject\User tried to logon? Anyway - hopefully this question isn't too stupid! Cheers Mat
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

_trunk_
This post has NOT been accepted by the mailing list yet.
Hi UncleTupelo,
   
    I had a project which is pretty much resembles to what you are in right now. What I did is on every log in attempt, a counter is being incremented and saved into the users table, the same table where I saved username and password (my application really demands it - the number of attempts allowed does not exceed even using time interval and multiple machine for log-in just like an ATM machine). So, in every validation of username and password, number of attempts is also regarded and checked. If the max number attempt is reached, the account is automatically disabled, thus, a message is prompt to the user who tries to log-in. Since my custom realm calls the validation process, its there where I throw new Account-Locked-Exception.

hope this helps.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

Les Hazlewood-2
In reply to this post by UncleTupelo
Hi Mat,

Nice to hear you're using Shiro with Vaadin - I too have a project
where I'm using both of these frameworks together, and I'm really
enjoying this combination :)

Anyway, that exception exists but it is not thrown/managed at any
point by Shiro.  It is there for your use as a convenience so you
don't have to create your own Exception class if you don't want to.
You would need to instantiate and throw it in your Realm's
doGetAuthenticationInfo method when appropriate.  The reason Shiro
can't do this automatically is that this type of logic (lock account
after a certain number of times in a certain number of minutes) is
usually entirely dependent upon your application's User data model.

There are a few ways to do this, but here are the most common 2 that I've seen:

1) Store 3 additional columns in your User table:
loginPeriodStartTimestamp, lastLoginAttemptTimestamp and
loginAttemptCount.  Based on what you configure the login period to be
before accounts are locked (5 minutes?), you can increment the login
attempt count.  If that number ever becomes greater than what your
system deems is allowed (3 tries?), then you would manually throw the
ExcessiveAttemptsException.  Then your login controller can react to
that and show an appropriate GUI message.

2)  An even easier approach than #1, but which requires more disk
storage, is to keep an event log of every login attempt. This is very
simple - you enter an event into the event log for each login attempt
with the timestamp the event occurred and the status of whether or not
the login failed for that user.  Then, determining if the account
should be locked upon login is a very simple exercise - you query your
event log to count all failed attempts for that user where the event
timestamp is newer than (now - login period).  If you receive any
count greater than your configured number (say, 3), then you throw the
exception.

Again, this is very application data-model specific, but that should
give you some ideas.

HTH,

Les

On Mon, Feb 8, 2010 at 10:17 AM, UncleTupelo <[hidden email]> wrote:

> Good Afternoon, I am up and running with Shiro (Spring Web App using the
> Vaadin framework), so all is good. Thank you all for the effort. So on to my
> question! Basically I want to lock a User in my Application if they have
> tried to sign on a number of times and keep getting the password wrong. I
> notice there is a ExcessiveAttemptsException class and the javadoc says:
>
> Thrown when a system is configured to only allow a certain number of
> authentication attempts over a period of time and the current session has
> failed to authenticate successfully within that number.
>
> So that sounds like what I want to catch and handle (in my case the handling
> would update a field on a User database row to indicate the Users login was
> now disabled). But where is this Excessive Attempts configured - or is this
> an exception I would have to build and throw? If so how would I know how
> many times the Subject\User tried to logon? Anyway - hopefully this question
> isn't too stupid! Cheers Mat
> ________________________________
> View this message in context: ExcessiveAttemptsException - How to configure
> Sent from the Shiro User mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

UncleTupelo
Cheers Gents,

That is fine - I just needed confirmation that there wasn't somewhere in Shiro I could magically stipulate the number of attempts allowed!

Les - I have an an Audit Event Table that would match the Point 2 perfectly.  Had almost forgotten about it until I read your response.

Thanks for the prompt responses.  Really is appreciated.




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

jpeeters
This post has NOT been accepted by the mailing list yet.
In reply to this post by Les Hazlewood-2
Dear Lez,

I read you successfully integrated Vaadin with Shiro and I am interested how you achieved this.

I am just looking into Shiro, since my own authorization framework is not scalable enough and I could not find any good implementation for Vaadin (e.g., the appfoundation framework has too much overhead which I do not use, and spring security is too rigid in my opinion).

Do you have some information or a proof of concept available that can guide me to integrate both technologies? I have been referred to Shiro by one of the maven authors and would love to give it a chance!

Best regards,
Johannes
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

kpenrose
In reply to this post by Les Hazlewood-2
I'm using Vaadin and have shiro authentication successfully working, but I'm trying to set up a first-time user scenario where if there is a value in the database set for first time login, I want to throw an exception from the doGetAuthentication method that is caught in the login view, which causes a change password dialog to be presented.
The problem I have is even though I have appropriated the ExcessiveAttemptsException to do this, the try-catch clause in my login presenter never catches the subclasses, it only ever catches the AuthenticationException type.  I have traced the execution, and I know that I'm throwing the right type of exception, but I only ever catch the base class.  
Here's my try-catch clause:

       try {
            subject.login(token);
            if (subject.isAuthenticated()) {
                logger.info("User Authenticated {}.", subject.getPrincipal().toString());
                loggedInEvent.fire(new UserLoggedInEvent(subject.getPrincipal().toString()));
            }
        } catch (UnknownAccountException uae) {
            logger.info("Unknown Account: {}.", uae.toString());
        } catch (ExcessiveAttemptsException eae) {
//            logger.info("User Authenticated {}.", subject.getPrincipal().toString() + " but password change required.");
//            loggedInEvent.fire(new UserLoggedInEvent(subject.getPrincipal().toString(), true));
            UI.getCurrent().getNavigator().navigateTo("PasswordChange");
        } catch (IncorrectCredentialsException e) {
            getView().showInvalidLoginNotification(e.getMessage());
        }

As you can see I don't have a catch for the AuthenticationException, which causes the Vaadin DefaultErrrorHandler to catch it, which just causes a stack trace which produces the stock message that authentication could not happen because the realm doesn't support it.
Any idea at all why the correct exception type doesn't make it to the calling code?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

lprimak
I think this has to do with multi-realm authentication strategy. I am not sure offhand which class it is but I believe that you will need to override this class to get the exception handling you need.
Take a look at the documentation and search for multi realm strategy and you will know which class to override. The default implementation hides specific exception of realm failure.



> On Jun 25, 2015, at 9:44 AM, kpenrose <[hidden email]> wrote:
>
> I'm using Vaadin and have shiro authentication successfully working, but I'm
> trying to set up a first-time user scenario where if there is a value in the
> database set for first time login, I want to throw an exception from the
> doGetAuthentication method that is caught in the login view, which causes a
> change password dialog to be presented.
> The problem I have is even though I have appropriated the
> ExcessiveAttemptsException to do this, the try-catch clause in my login
> presenter never catches the subclasses, it only ever catches the
> AuthenticationException type.  I have traced the execution, and I know that
> I'm throwing the right type of exception, but I only ever catch the base
> class.  
> Here's my try-catch clause:
>
>       try {
>            subject.login(token);
>            if (subject.isAuthenticated()) {
>                logger.info("User Authenticated {}.",
> subject.getPrincipal().toString());
>                loggedInEvent.fire(new
> UserLoggedInEvent(subject.getPrincipal().toString()));
>            }
>        } catch (UnknownAccountException uae) {
>            logger.info("Unknown Account: {}.", uae.toString());
>        } catch (ExcessiveAttemptsException eae) {
> //            logger.info("User Authenticated {}.",
> subject.getPrincipal().toString() + " but password change required.");
> //            loggedInEvent.fire(new
> UserLoggedInEvent(subject.getPrincipal().toString(), true));
>            UI.getCurrent().getNavigator().navigateTo("PasswordChange");
>        } catch (IncorrectCredentialsException e) {
>            getView().showInvalidLoginNotification(e.getMessage());
>        }
>
> As you can see I don't have a catch for the AuthenticationException, which
> causes the Vaadin DefaultErrrorHandler to catch it, which just causes a
> stack trace which produces the stock message that authentication could not
> happen because the realm doesn't support it.
> Any idea at all why the correct exception type doesn't make it to the
> calling code?
>
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/ExcessiveAttemptsException-How-to-configure-tp4534742p7580586.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

kpenrose
I'm using a single realm - jpa based, and as I said, authentication works correctly with my overloaded doAuthentication method (or whatever it's called).  And, inside that method I find that a password change is required, and I throw an ExcessiveAttemptsException, but the calling controller for my UI only catches the base class AuthenticationException.  Very strange behavior, and I can't figure it out, to say the least.
Thanks.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

Alexander Openkowski
Looking into the code that I think calls your overloaded doAuthenticate
method, it seems as if any exception that is not an
AuthenticationException is wrapped with one:

See line 214:
http://shiro.apache.org/static/1.2.3/apidocs/src-html/org/apache/shiro/authc/AbstractAuthenticator.html

I do not recall the class hierarchy right now, but I think your realm
should extend from the AbstractAuthenticator, right? So my first guess
would be that you should also overload the authenticate method and
implement your desired behaviour there? I am not sure though if
something else will break when some exceptions other than
AuthenticationExceptions escape.

On 06/26/2015 02:19 PM, kpenrose wrote:

> I'm using a single realm - jpa based, and as I said, authentication works
> correctly with my overloaded doAuthentication method (or whatever it's
> called).  And, inside that method I find that a password change is required,
> and I throw an ExcessiveAttemptsException, but the calling controller for my
> UI only catches the base class AuthenticationException.  Very strange
> behavior, and I can't figure it out, to say the least.
> Thanks.
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/ExcessiveAttemptsException-How-to-configure-tp4534742p7580589.html
> Sent from the Shiro User mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

Alessio Stalla
ExcessiveAttemptsException should extend AuthenticationException.

On Fri, Jun 26, 2015 at 2:36 PM, Alexander Openkowski <[hidden email]> wrote:
Looking into the code that I think calls your overloaded doAuthenticate
method, it seems as if any exception that is not an
AuthenticationException is wrapped with one:

See line 214:
http://shiro.apache.org/static/1.2.3/apidocs/src-html/org/apache/shiro/authc/AbstractAuthenticator.html

I do not recall the class hierarchy right now, but I think your realm
should extend from the AbstractAuthenticator, right? So my first guess
would be that you should also overload the authenticate method and
implement your desired behaviour there? I am not sure though if
something else will break when some exceptions other than
AuthenticationExceptions escape.

On 06/26/2015 02:19 PM, kpenrose wrote:
> I'm using a single realm - jpa based, and as I said, authentication works
> correctly with my overloaded doAuthentication method (or whatever it's
> called).  And, inside that method I find that a password change is required,
> and I throw an ExcessiveAttemptsException, but the calling controller for my
> UI only catches the base class AuthenticationException.  Very strange
> behavior, and I can't figure it out, to say the least.
> Thanks.
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/ExcessiveAttemptsException-How-to-configure-tp4534742p7580589.html
> Sent from the Shiro User mailing list archive at Nabble.com.




--
Alessio Stalla | Software Architect
M: +39 340 7824743 | T: +39 010 566441 | F: +39 010 8900455
[hidden email] | www.manydesigns.com

MANYDESIGNS s.r.l.
Via G. D'Annunzio, 2/51 | 16121 Genova (GE) | Italy
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

kpenrose
In reply to this post by Alexander Openkowski
You can see from the reply above from Les Hazlewood that:

Anyway, that exception exists but it is not thrown/managed at any
point by Shiro.  It is there for your use as a convenience so you
don't have to create your own Exception class if you don't want to.
You would need to instantiate and throw it in your Realm's
doGetAuthenticationInfo method when appropriate.  The reason Shiro
can't do this automatically is that this type of logic (lock account
after a certain number of times in a certain number of minutes) is
usually entirely dependent upon your application's User data model.


So here is my code for the overloaded function:

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws UnknownAccountException, ExcessiveAttemptsException, IncorrectCredentialsException {

        // null usernames are invalid
        if (token == null) {
            throw new AuthenticationException(
                    "PrincipalCollection method argument cannot be null.");
        }

        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        InventoryReportUser user = service.getUserByUsername(usernamePasswordToken
                .getUsername());

        if (user == null) {
            throw new UnknownAccountException("Could not find user");
        }
        if (user.isResetPasswordReqd()) {
            throw new ExcessiveAttemptsException("Password change required", new Throwable("Password change required")); //"Password change required");
        }

        if (getCredentialsMatcher().doCredentialsMatch(usernamePasswordToken,
                user.getAsAuthenticationInfo())) {
            return user.getAsAuthenticationInfo();
        }

        throw new IncorrectCredentialsException("Failed to authenticate");
    }

So you can see that I check for user.isResetPasswordReqd() which throws the ExcessiveAttemptsException.  However, my controller only receives the AuthenticationException.  Thing is, I can enter an invalid user id and although stepping through the execution shows me that the UnknownAccountException is thrown, I still receive the AuthenticationException type in the controller.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

Alexander Openkowski
Oh, I did not know that the ExcessiveAttemptsException is part of Shiro
and extends AuthenticationException. Did not read the thread history, sorry.

On 06/26/2015 05:00 PM, kpenrose wrote:

> You can see from the reply above from Les Hazlewood that:
>
> /Anyway, that exception exists but it is not thrown/managed at any
> point by Shiro.  It is there for your use as a convenience so you
> don't have to create your own Exception class if you don't want to.
> You would need to instantiate and throw it in your Realm's
> doGetAuthenticationInfo method when appropriate.  The reason Shiro
> can't do this automatically is that this type of logic (lock account
> after a certain number of times in a certain number of minutes) is
> usually entirely dependent upon your application's User data model.
> /
>
> So here is my code for the overloaded function:
>
>     @Override
>     protected AuthenticationInfo doGetAuthenticationInfo(
>             AuthenticationToken token) throws UnknownAccountException,
> ExcessiveAttemptsException, IncorrectCredentialsException {
>
>         // null usernames are invalid
>         if (token == null) {
>             throw new AuthenticationException(
>                     "PrincipalCollection method argument cannot be null.");
>         }
>
>         UsernamePasswordToken usernamePasswordToken =
> (UsernamePasswordToken) token;
>
>         InventoryReportUser user =
> service.getUserByUsername(usernamePasswordToken
>                 .getUsername());
>
>         if (user == null) {
>             throw new UnknownAccountException("Could not find user");
>         }
>         if (user.isResetPasswordReqd()) {
>             throw new ExcessiveAttemptsException("Password change required",
> new Throwable("Password change required")); //"Password change required");
>         }
>
>         if
> (getCredentialsMatcher().doCredentialsMatch(usernamePasswordToken,
>                 user.getAsAuthenticationInfo())) {
>             return user.getAsAuthenticationInfo();
>         }
>
>         throw new IncorrectCredentialsException("Failed to authenticate");
>     }
>
> So you can see that I check for user.isResetPasswordReqd() which throws the
> ExcessiveAttemptsException.  However, my controller only receives the
> AuthenticationException.  Thing is, I can enter an invalid user id and
> although stepping through the execution shows me that the
> UnknownAccountException is thrown, I still receive the
> AuthenticationException type in the controller.
>
>
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/ExcessiveAttemptsException-How-to-configure-tp4534742p7580592.html
> Sent from the Shiro User mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

lprimak
In reply to this post by kpenrose
It doesn't matter if you only have one realm, the logic flows through the org.apache.shiro.authc.pam.ModularRealmAuthenticator anyway.
As you can see here: http://grepcode.com/file/repo1.maven.org/maven2/com.ning/metrics.collector/1.2.1/org/apache/shiro/authc/pam/ModularRealmAuthenticator.java#197
it swallows actual Realm-thrown exception and throws it's own version of AuthenticationException.
You will have to override this behavior if you want get more granular exception handling

On Jun 26, 2015, at 8:19 AM, kpenrose wrote:

> I'm using a single realm - jpa based, and as I said, authentication works
> correctly with my overloaded doAuthentication method (or whatever it's
> called).  And, inside that method I find that a password change is required,
> and I throw an ExcessiveAttemptsException, but the calling controller for my
> UI only catches the base class AuthenticationException.  Very strange
> behavior, and I can't figure it out, to say the least.
> Thanks.
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/ExcessiveAttemptsException-How-to-configure-tp4534742p7580589.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

kpenrose
I still believe that for a single realm this isn't the case, as stated in the javadoc for the code you referenced:
If only one realm is configured (this is often the case for most applications), authentication success is naturally only dependent upon invoking this one Realm's org.apache.shiro.realm.Realm.getAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) method.

What I don't understand, is how overriding the doGetAuthenticationInfo affects this call chain.  But, I do agree that even the code for the single realm authentication throws only an AuthenticationException.  And that getAuthenticationInfo method is final, so overriding it isn't possible.

To hard to create a simple exception strategy, IMO.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ExcessiveAttemptsException - How to configure

lprimak
If you put a breakpoint in your getAuthenticationInfo()
you will notice that that the code flows through ModularRealmAuthenticator anyway,
even if it calls only one realm, exception handling is still fiddled with by ModularRealmAuthenticator

On Jun 29, 2015, at 8:55 AM, kpenrose wrote:

> I still believe that for a single realm this isn't the case, as stated in the
> javadoc for the code you referenced:
> If only one realm is configured (this is often the case for most
> applications), authentication success is naturally only dependent upon
> invoking this one Realm's
> org.apache.shiro.realm.Realm.getAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
> method.
>
> What I don't understand, is how overriding the doGetAuthenticationInfo
> affects this call chain.  But, I do agree that even the code for the single
> realm authentication throws only an AuthenticationException.  And that
> getAuthenticationInfo method is final, so overriding it isn't possible.
>
> To hard to create a simple exception strategy, IMO.
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/ExcessiveAttemptsException-How-to-configure-tp4534742p7580598.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>

Loading...