Class SamlAuthentication

java.lang.Object
org.dspace.authenticate.SamlAuthentication
All Implemented Interfaces:
AuthenticationMethod

public class SamlAuthentication extends Object implements AuthenticationMethod
SAML authentication for DSpace.
Author:
Ray Lee
  • Field Details

  • Constructor Details

    • SamlAuthentication

      public SamlAuthentication()
  • Method Details

    • authenticate

      public int authenticate(Context context, String username, String password, String realm, jakarta.servlet.http.HttpServletRequest request) throws SQLException
      Authenticate the given or implicit credentials. This is the heart of the authentication method: test the credentials for authenticity, and if accepted, attempt to match (or optionally, create) an EPerson. If an EPerson is found it is set in the Context that was passed. DSpace supports authentication using NetID or email address. A user's NetID is a unique identifier from the IdP that identifies a particular user. The NetID can be of almost any form, such as a unique integer or string. In SAML, this is referred to as a Name ID. There are two ways to supply identity information to DSpace: 1) Name ID from SAML attribute (best) The Name ID-based method is superior because users may change their email address with the identity provider. When this happens DSpace will not be able to associate their new address with their old account. 2) Email address from SAML attribute (okay) In the case where a Name ID header is not available or not found DSpace will fall back to identifying a user based upon their email address. Identity Scheme Migration Strategies: If you are currently using Email based authentication (either 1 or 2) and want to upgrade to NetID based authentication then there is an easy path. Coordinate with the IdP to provide a Name ID in the SAML assertion. When a user attempts to log in, DSpace will first look for an EPerson with the passed Name ID. When this fails, DSpace will fall back to email based authentication. Then DSpace will update the user's EPerson account record to set their NetID, so all future authentications for this user will be based upon NetID. DSpace will prevent an account from switching NetIDs. If an account already has a NetID set, and a user tries to authenticate with the same email but a different NetID, the authentication will fail.
      Specified by:
      authenticate in interface AuthenticationMethod
      Parameters:
      context - DSpace context, will be modified (EPerson set) upon success.
      username - Not used by SAML-based authentication.
      password - Not used by SAML-based authentication.
      realm - Not used by SAML-based authentication.
      request - The HTTP request that started this operation.
      Returns:
      one of: SUCCESS, NO_SUCH_USER, BAD_ARGS
      Throws:
      SQLException - if a database error occurs.
    • getSpecialGroups

      public List<Group> getSpecialGroups(Context context, jakarta.servlet.http.HttpServletRequest request) throws SQLException
      Description copied from interface: AuthenticationMethod
      Get list of extra groups that user implicitly belongs to. Note that this method will be invoked regardless of the authentication status of the user (logged-in or not) e.g. a group that depends on the client network-address.

      It might make sense to implement this method by itself in a separate authentication method that just adds special groups, if the code doesn't belong with any existing auth method. The stackable authentication system was designed expressly to separate functions into "stacked" methods to keep your site-specific code modular and tidy.

      Specified by:
      getSpecialGroups in interface AuthenticationMethod
      Parameters:
      context - A valid DSpace context.
      request - The request that started this operation, or null if not applicable.
      Returns:
      array of EPerson-group IDs, possibly 0-length, but never null.
      Throws:
      SQLException - if database error
    • allowSetPassword

      public boolean allowSetPassword(Context context, jakarta.servlet.http.HttpServletRequest request, String email) throws SQLException
      Description copied from interface: AuthenticationMethod
      Should (or can) we allow the user to change their password. Note that this means the password stored in the EPerson record, so if any method in the stack returns true, the user is allowed to change it.
      Specified by:
      allowSetPassword in interface AuthenticationMethod
      Parameters:
      context - DSpace context
      request - HTTP request, in case it's needed. May be null.
      email - Username, if available. May be null.
      Returns:
      true if this method allows user to change ePerson password.
      Throws:
      SQLException - if database error
    • isImplicit

      public boolean isImplicit()
      Description copied from interface: AuthenticationMethod
      Predicate, is this an implicit authentication method. An implicit method gets credentials from the environment (such as an HTTP request or even Java system properties) rather than the explicit username and password. For example, a method that reads the X.509 certificates in an HTTPS request is implicit.
      Specified by:
      isImplicit in interface AuthenticationMethod
      Returns:
      true if this method uses implicit authentication.
    • canSelfRegister

      public boolean canSelfRegister(Context context, jakarta.servlet.http.HttpServletRequest request, String username) throws SQLException
      Description copied from interface: AuthenticationMethod
      Predicate, whether to allow new EPerson to be created. The answer determines whether a new user is created when the credentials describe a valid entity but there is no corresponding EPerson in DSpace yet. The EPerson is only created if authentication succeeds.
      Specified by:
      canSelfRegister in interface AuthenticationMethod
      Parameters:
      context - DSpace context
      request - HTTP request, in case it's needed. May be null.
      username - Username, if available. May be null.
      Returns:
      true if new ePerson should be created.
      Throws:
      SQLException - if database error
    • initEPerson

      public void initEPerson(Context context, jakarta.servlet.http.HttpServletRequest request, EPerson eperson) throws SQLException
      Description copied from interface: AuthenticationMethod
      Initialize a new EPerson record for a self-registered new user. Set any data in the EPerson that is specific to this authentication method.
      Specified by:
      initEPerson in interface AuthenticationMethod
      Parameters:
      context - DSpace context
      request - HTTP request, in case it's needed. May be null.
      eperson - newly created EPerson record - email + information from the registration form will have been filled out.
      Throws:
      SQLException - if database error
    • loginPageURL

      public String loginPageURL(Context context, jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response)
      Returns the URL in the SAML relying party service that initiates a login with the IdP, as configured.
      Specified by:
      loginPageURL in interface AuthenticationMethod
      Parameters:
      context - DSpace context, will be modified (ePerson set) upon success.
      request - The HTTP request that started this operation, or null if not applicable.
      response - The HTTP response from the servlet method.
      Returns:
      fully-qualified URL or null
      See Also:
    • getName

      public String getName()
      Description copied from interface: AuthenticationMethod
      Returns a short name that uniquely identifies this authentication method
      Specified by:
      getName in interface AuthenticationMethod
      Returns:
      The authentication method name
    • isEnabled

      public static boolean isEnabled()
      Check if the SAML plugin is enabled.
      Returns:
      true if enabled, false otherwise
    • findEPerson

      protected EPerson findEPerson(Context context, jakarta.servlet.http.HttpServletRequest request) throws SQLException, AuthorizeException
      Identify an existing EPerson based upon the SAML attributes provided on the request object. 1) Name ID from SAML attribute (best) The Name ID-based method is superior because users may change their email address with the identity provider. When this happens DSpace will not be able to associate their new address with their old account. 2) Email address from SAML attribute (okay) In the case where a Name ID header is not available or not found DSpace will fall back to identifying a user based upon their email address. If successful then the identified EPerson will be returned, otherwise null.
      Parameters:
      context - The DSpace database context
      request - The current HTTP Request
      Returns:
      The EPerson identified or null.
      Throws:
      SQLException - if database error
      AuthorizeException - if authorization error
    • registerNewEPerson

      protected EPerson registerNewEPerson(Context context, jakarta.servlet.http.HttpServletRequest request) throws SQLException, AuthorizeException
      Register a new EPerson. This method is called when no existing user was found for the NetID or email and autoregister is enabled. When these conditions are met this method will create a new EPerson object. In order to create a new EPerson object there is a minimal set of metadata required: email, first name, and last name. If we don't have access to these three pieces of information then we will be unable to create a new EPerson. Note that this method only adds the minimal metadata. Any additional metadata will need to be added by the updateEPerson method.
      Parameters:
      context - The current DSpace database context
      request - The current HTTP Request
      Returns:
      A new EPerson object or null if unable to create a new EPerson.
      Throws:
      SQLException - if database error
      AuthorizeException - if authorization error
    • updateEPerson

      protected void updateEPerson(Context context, jakarta.servlet.http.HttpServletRequest request, EPerson eperson) throws SQLException, AuthorizeException
      After we successfully authenticated a user, this method will update the user's attributes. The user's email, name, or other attribute may have been changed since the last time they logged into DSpace. This method will update the database with their most recent information. This method handles the basic DSpace metadata (email, first name, last name) along with additional metadata set using the setMetadata() methods on the EPerson object. The additional metadata mappings are defined in configuration.
      Parameters:
      context - The current DSpace database context
      request - The current HTTP Request
      eperson - The eperson object to update.
      Throws:
      SQLException - if database error
      AuthorizeException - if authorization error
    • initialize

      protected void initialize(Context context) throws SQLException
      Initialize SAML Authentication. During initalization the mapping of additional EPerson metadata will be loaded from the configuration and cached. While loading the metadata mapping this method will check the EPerson object to see if it supports the metadata field. If the field is not supported and autocreate is turned on then the field will be automatically created. It is safe to call this method multiple times.
      Parameters:
      context - context
      Throws:
      SQLException - if database error
    • checkIfEPersonMetadataFieldExists

      protected boolean checkIfEPersonMetadataFieldExists(Context context, String metadataName) throws SQLException
      Check if a metadata field for an EPerson is available.
      Parameters:
      metadataName - The name of the metadata field.
      context - context
      Returns:
      True if a valid metadata field, otherwise false.
      Throws:
      SQLException - if database error
    • autoCreateEPersonMetadataField

      protected boolean autoCreateEPersonMetadataField(Context context, String metadataName) throws SQLException
      Automatically create a new metadata field for an EPerson
      Parameters:
      context - context
      metadataName - The name of the new metadata field.
      Returns:
      True if successful, otherwise false.
      Throws:
      SQLException - if database error
    • isUsed

      public boolean isUsed(Context context, jakarta.servlet.http.HttpServletRequest request)
      Description copied from interface: AuthenticationMethod
      Get whether the authentication method is being used.
      Specified by:
      isUsed in interface AuthenticationMethod
      Parameters:
      context - The DSpace context
      request - The current request
      Returns:
      whether the authentication method is being used.
    • canChangePassword

      public boolean canChangePassword(Context context, EPerson ePerson, String currentPassword)
      Description copied from interface: AuthenticationMethod
      Check if the given current password is valid to change the password of the given ePerson
      Specified by:
      canChangePassword in interface AuthenticationMethod
      Parameters:
      context - The DSpace context
      ePerson - the ePerson related to the password change
      currentPassword - The current password to check
      Returns:
      true if the provided password matches with current password