2

Newbie question... I've successfully implemented custom handlers and service (Custom User Details Service, Authentication Success, Authentication Failure) and everything working fine. I've now also implemented functionality that will lock an account (for a certain amount of time) if they fail authentication 3 concurrent times.

I'm now moving on to handle the scenario when a user attempts to authenticate when they have an account lock. If the lock is active > authentication should not be attempted and user redirected to locked account page/error. If the lock has expired > the lock should be removed and authentication proceeds as normal

In the case where the account lock is active - I’ve tried implementing this in my Custom Authentication Success Handler but despite successfully forwarding the user to an account lock error page – it’s too late as the application has already authenticated the user and the user is successfully able to access secure pages directly (which is obviously wrong as their account should be locked).

I started playing around but I thought I'd check on here first for a more standard/elegant solution/approach. Should I be performing this check and actions in the Custom User Details Service or is there a pre-Authentication handler that I could implement before the user even hits Custom User Details Service? Any help or advice on where/how I could handle this will be much appreciated

Simon Tilbury
  • 37
  • 1
  • 1
  • 5

3 Answers3

8

In your UserDetails implementations, pass true to the following values

  1. isAccountNonExpired()
  2. isAccountNonLocked()
  3. isCredentialsNonExpired()

For more details you can check the public void check(UserDetails user) in AbstractUserDetailsAuthenticationProvider class. Hope this helps somebody.

Vikram
  • 368
  • 3
  • 12
1

Use the following four methods as true in the UserDetails implementation class in order to prevent locking of your test account.

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • I had the same problem as the original question. Setting the 4 methods to `true` fixed the login issue. Can I have those 4 methods set to `true` in, let's say production? I had the impression that setting it to return `false` should be the default value. I haven't read a lot about it yet though. – heisenberg Jul 13 '21 at 13:56
0

There is built-in LockedException. It will be thrown by AuthenticationManager if UserDetails.isAccountNonLocked() == false. So you can perform your check in UserDetailsService.loadUserByUsername(...) method. Just pass false value for accountNonExpired parameter when you create new User object.

Maksym Demidas
  • 7,707
  • 1
  • 29
  • 36