Changeset 7539


Ignore:
Timestamp:
Nov 28, 2018, 4:02:32 PM (3 years ago)
Author:
Nicklas Nordborg
Message:

References #2131: Add support for installing multiple authentication managers

Added AuthenticationManager.vetoAuthenticatedUser() method. This will make it possible for authentication managers to cooperate and allow or deny users to login with more than one authentication method.

Location:
trunk/src/core/net/sf/basedb/core
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/SessionControl.java

    r7513 r7539  
    451451      tx = HibernateUtil.newTransaction(session);
    452452
    453       authUser = verifyUserExternal(session, loginRequest);
     453      List<AuthenticationManager> externalManagers = new ArrayList<>();
     454      authUser = verifyUserExternal(session, loginRequest, externalManagers);
    454455      if (authUser == null)
    455456      {
    456457        // If no user was found, use internal authentication
    457458        authUser = verifyUserInternal(session, loginRequest);
     459      }
     460     
     461      // The login seems to be ok, but we need to let external manages to throw in a veto
     462      user = HibernateUtil.loadData(session, UserData.class, authUser.getInternalId());
     463      try
     464      {
     465        for (AuthenticationManager external : externalManagers)
     466        {
     467          external.vetoAuthenticatedUser(user, authUser);
     468        }
     469      }
     470      catch (net.sf.basedb.core.authentication.AuthenticationException ex)
     471      {
     472        throw new LoginException(ex.getMessage(), ex);
    458473      }
    459474     
    460475      // The login was ok so far... check device verification
    461476      device = verifyDevice(session, loginRequest, authUser);
    462       user = HibernateUtil.loadData(session, UserData.class, authUser.getInternalId());
    463477     
    464478      // A null value means that either device verification is disabled
     
    683697  */
    684698  @SuppressWarnings("unchecked")
    685   private AuthenticatedUser verifyUserExternal(org.hibernate.Session session, LoginRequest loginRequest)
     699  private AuthenticatedUser verifyUserExternal(org.hibernate.Session session, LoginRequest loginRequest, List<AuthenticationManager> authManagers)
    686700  {
    687701    AuthenticationContext context = new AuthenticationContext(this, session, loginRequest);
     
    694708    try
    695709    {
    696       // Load all installed authentication managers and iterate until
    697       // someone returns an info object or throws an exception
     710      // Load all installed authentication managers
     711      // Call authenticate() until one returns an 'AuthenticatedUser'
     712      // All others are saved in the authManagers list for later calling vetoAuthenticatedUser()
     713      // If some manager is throwing an exception the login fails
    698714      for (AuthenticationManager auth : invoker)
    699715      {
    700         authUser = auth.authenticate();
    701         if (authUser != null)
     716        boolean add = true;
     717        if (authUser == null)
    702718        {
    703           // Found a valid login
    704           break;
     719          authUser = auth.authenticate();
     720          if (authUser != null) add = false;
    705721        }
     722        if (add) authManagers.add(auth);
    706723      }
    707724    }
  • trunk/src/core/net/sf/basedb/core/authentication/AuthenticationManager.java

    r6880 r7539  
    2323
    2424import net.sf.basedb.core.AuthenticationContext;
     25import net.sf.basedb.core.data.UserData;
    2526import net.sf.basedb.util.extensions.Action;
    2627import net.sf.basedb.util.extensions.InvokationContext;
     
    6263  public AuthenticatedUser authenticate();
    6364 
     65  /**
     66    This method is called if there are multiple installed external authentication
     67    managers and at least one of them accepted the user in the {@link #authenticate()}
     68    method. If so, all other authentication managers will get a chance to throw in
     69    a veto. For example, an administrator account may be protected with a special
     70    authentication manager (for example, YubiKey) while regular users by a simpler
     71    method (for example, OTP). If the administrator tries to login with the OTP method
     72    then the Yubikey authentication manager may veto this by throwing an
     73    {@link AuthenticationException} from this method.
     74   
     75    Note that this method is NOT called on the authentication manager that authenticated
     76    a user by returning information from the {@link #authenticate()} method.
     77   
     78    To provide backwards compatibility with existing authentication managers this
     79    method has a default implementation that doesn't do anything.
     80   
     81    @param user The user that is trying to login
     82    @param auth Information about the authentication
     83    @since 3.14
     84  */
     85  public default void vetoAuthenticatedUser(UserData user, AuthenticatedUser auth)
     86  {}
    6487 
    6588}
Note: See TracChangeset for help on using the changeset viewer.