Class ShibAuthentication
- java.lang.Object
-
- org.dspace.authenticate.ShibAuthentication
-
- All Implemented Interfaces:
AuthenticationMethod
public class ShibAuthentication extends Object implements AuthenticationMethod
Shibboleth authentication for DSpace Shibboleth is a distributed authentication system for securely authenticating users and passing attributes about the user from one or more identity providers. In the Shibboleth terminology DSpace is a Service Provider which receives authentication information and then based upon that provides a service to the user. With Shibboleth DSpace will require that you use Apache installed with the mod_shib module acting as a proxy for all HTTP requests for your servlet container (typically Tomcat). DSpace will receive authentication information from the mod_shib module through HTTP headers. See for more information on installing and configuring a Shibboleth Service Provider: https://wiki.shibboleth.net/confluence/display/SHIB2/Installation See the DSpace.cfg or DSpace manual for information on how to configure this authentication module.
-
-
Field Summary
Fields Modifier and Type Field Description protected StringCOLUMN_NAME_REGEXValidate Postgres Column Namesprotected ConfigurationServiceconfigurationServiceprotected EPersonServiceePersonServiceprotected GroupServicegroupServiceprotected intMETADATA_MAX_SIZEMaximum length for eperson additional metadata fieldsprotected MetadataFieldServicemetadataFieldServiceprotected Map<String,String>metadataHeaderMapAdditional metadata mappingsprotected MetadataSchemaServicemetadataSchemaServiceprotected intNAME_MAX_SIZEMaximum length for eperson metadata fieldsprotected intPHONE_MAX_SIZE-
Fields inherited from interface org.dspace.authenticate.AuthenticationMethod
BAD_ARGS, BAD_CREDENTIALS, CERT_REQUIRED, NO_SUCH_USER, SUCCESS
-
-
Constructor Summary
Constructors Constructor Description ShibAuthentication()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description booleanallowSetPassword(Context context, javax.servlet.http.HttpServletRequest request, String email)Indicate whether or not a particular self-registering user can set themselves a password in the profile info form.intauthenticate(Context context, String username, String password, String realm, javax.servlet.http.HttpServletRequest request)Authenticate the given or implicit credentials.protected booleanautoCreateEpersonMetadataField(Context context, String metadataName)Automatically create a new metadataField for an epersonbooleancanChangePassword(Context context, EPerson ePerson, String currentPassword)Check if the given current password is valid to change the password of the given ePersonbooleancanSelfRegister(Context context, javax.servlet.http.HttpServletRequest request, String username)Indicate whether or not a particular user can self-register, based on e-mail address.protected booleancheckIfEpersonMetadataFieldExists(Context context, String metadataName)Check if a MetadataField for an eperson is available.protected StringfindAttribute(javax.servlet.http.HttpServletRequest request, String name)Find a particular Shibboleth header value and return the all values.protected EPersonfindEPerson(Context context, javax.servlet.http.HttpServletRequest request)Identify an existing EPerson based upon the shibboleth attributes provided on the request object.protected List<String>findMultipleAttributes(javax.servlet.http.HttpServletRequest request, String name)Find a particular Shibboleth hattributeeader value and return the values.protected StringfindSingleAttribute(javax.servlet.http.HttpServletRequest request, String name)Find a particular Shibboleth header value and return the first value.StringgetName()Returns a short name that uniquely identifies this authentication methodList<Group>getSpecialGroups(Context context, javax.servlet.http.HttpServletRequest request)Get list of extra groups that user implicitly belongs to.voidinitEPerson(Context context, javax.servlet.http.HttpServletRequest request, EPerson eperson)Initialize a new e-person record for a self-registered new user.protected voidinitialize(Context context)Initialize Shibboleth Authentication.static booleanisEnabled()Check if Shibboleth plugin is enabledbooleanisImplicit()Predicate, is this an implicit authentication method.booleanisUsed(Context context, javax.servlet.http.HttpServletRequest request)Get whether the authentication method is being used.StringloginPageURL(Context context, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)Get login page to which to redirect.protected EPersonregisterNewEPerson(Context context, javax.servlet.http.HttpServletRequest request)Register a new eperson object.protected intswordCompatibility(Context context, String username, String password, javax.servlet.http.HttpServletRequest request)Provide password-based authentication to enable sword compatibility.protected voidupdateEPerson(Context context, javax.servlet.http.HttpServletRequest request, EPerson eperson)After we successfully authenticated a user, this method will update the user's attributes.-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.dspace.authenticate.AuthenticationMethod
areSpecialGroupsApplicable
-
-
-
-
Field Detail
-
NAME_MAX_SIZE
protected final int NAME_MAX_SIZE
Maximum length for eperson metadata fields- See Also:
- Constant Field Values
-
PHONE_MAX_SIZE
protected final int PHONE_MAX_SIZE
- See Also:
- Constant Field Values
-
METADATA_MAX_SIZE
protected final int METADATA_MAX_SIZE
Maximum length for eperson additional metadata fields- See Also:
- Constant Field Values
-
ePersonService
protected EPersonService ePersonService
-
groupService
protected GroupService groupService
-
metadataFieldService
protected MetadataFieldService metadataFieldService
-
metadataSchemaService
protected MetadataSchemaService metadataSchemaService
-
configurationService
protected ConfigurationService configurationService
-
COLUMN_NAME_REGEX
protected final String COLUMN_NAME_REGEX
Validate Postgres Column Names- See Also:
- Constant Field Values
-
-
Method Detail
-
authenticate
public int authenticate(Context context, String username, String password, String realm, javax.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) anEPerson. If anEPersonis found it is set in theContextthat 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, string, or with Shibboleth 2.0 you can use "targeted ids". You will need to coordinate with your Shibboleth federation or identity provider. There are three ways to supply identity information to DSpace: 1) NetID from Shibboleth Header (best) The NetID-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 Shibboleth Header (okay) In the case where a NetID header is not available or not found DSpace will fall back to identifying a user based-upon their email address. 3) Tomcat's Remote User (worst) In the event that neither Shibboleth headers are found then as a last resort DSpace will look at Tomcat's remote user field. This is the least attractive option because Tomcat has no way to supply additional attributes about a user. Because of this the autoregister option is not supported if this method is used. 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. Simply enable Shibboleth to pass the NetID attribute and set the netid-header below to the correct value. When a user attempts to log in to DSpace first DSpace will look for an EPerson with the passed NetID, however 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. One thing to note is that DSpace will prevent an account from switching NetIDs. If an account already has a NetID set and then they try and authenticate with a different NetID the authentication will fail.- Specified by:
authenticatein interfaceAuthenticationMethod- Parameters:
context- DSpace context, will be modified (ePerson set) upon success.username- Username (or email address) when method is explicit. Use null for implicit method.password- Password for explicit auth, or null for implicit method.realm- Not used by Shibboleth-based authenticationrequest- The HTTP request that started this operation, or null if not applicable.- Returns:
- One of: SUCCESS, BAD_CREDENTIALS, CERT_REQUIRED, NO_SUCH_USER,
BAD_ARGS
Meaning:
SUCCESS - authenticated OK.
BAD_CREDENTIALS - user exists, but credentials (e.g. passwd) don't match
CERT_REQUIRED - not allowed to login this way without X.509 cert.
NO_SUCH_USER - user not found using this method.
BAD_ARGS - user/pw not appropriate for this method - Throws:
SQLException- if database error
-
getSpecialGroups
public List<Group> getSpecialGroups(Context context, javax.servlet.http.HttpServletRequest request)
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. DSpace is able to place users into pre-defined groups based upon values received from Shibboleth. Using this option you can place all faculty members into a DSpace group when the correct affiliation's attribute is provided. When DSpace does this they are considered 'special groups', these are really groups but the user's membership within these groups is not recorded in the database. Each time a user authenticates they are automatically placed within the pre-defined DSpace group, so if the user loses their affiliation then the next time they login they will no longer be in the group. Depending upon the shibboleth attributed use in the role-header, it may be scoped. Scoped is shibboleth terminology for identifying where an attribute originated from. For example a students affiliation may be encoded as "student@tamu.edu". The part after the @ sign is the scope, and the preceding value is the value. You may use the whole value or only the value or scope. Using this you could generate a role for students and one institution different than students at another institution. Or if you turn on ignore-scope you could ignore the institution and place all students into one group. The values extracted (a user may have multiple roles) will be used to look up which groups to place the user into. The groups are defined asauthentication.shib.role.<role-name>which is a comma separated list of DSpace groups.- Specified by:
getSpecialGroupsin interfaceAuthenticationMethod- 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.
-
allowSetPassword
public boolean allowSetPassword(Context context, javax.servlet.http.HttpServletRequest request, String email) throws SQLException
Indicate whether or not a particular self-registering user can set themselves a password in the profile info form.- Specified by:
allowSetPasswordin interfaceAuthenticationMethod- Parameters:
context- DSpace contextrequest- HTTP request, in case anything in that is used to decideemail- e-mail address of user attempting to register- Returns:
- true if this method allows user to change ePerson password.
- Throws:
SQLException- if database error
-
isImplicit
public boolean isImplicit()
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:
isImplicitin interfaceAuthenticationMethod- Returns:
- true if this method uses implicit authentication.
-
canSelfRegister
public boolean canSelfRegister(Context context, javax.servlet.http.HttpServletRequest request, String username) throws SQLException
Indicate whether or not a particular user can self-register, based on e-mail address.- Specified by:
canSelfRegisterin interfaceAuthenticationMethod- Parameters:
context- DSpace contextrequest- HTTP request, in case anything in that is used to decideusername- e-mail address of user attempting to register- Returns:
- true if new ePerson should be created.
- Throws:
SQLException- if database error
-
initEPerson
public void initEPerson(Context context, javax.servlet.http.HttpServletRequest request, EPerson eperson) throws SQLException
Initialize a new e-person record for a self-registered new user.- Specified by:
initEPersonin interfaceAuthenticationMethod- Parameters:
context- DSpace contextrequest- HTTP request, in case it's neededeperson- 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, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Get login page to which to redirect. Returns URL (as string) to which to redirect to obtain credentials (either password prompt or e.g. HTTPS port for client cert.); null means no redirect.For Shibboleth, this URL looks like (note 'target' param is URL encoded, but shown as unencoded in this example) [shibURL]?target=[dspace.server.url]/api/authn/shibboleth?redirectUrl=[dspace.ui.url]
This URL is used by the client to redirect directly to Shibboleth for authentication. The "target" param is then the location (in REST API) where Shibboleth redirects back to. The "redirectUrl" is the path/URL in the client (e.g. Angular UI) which the REST API redirects the user to (after capturing/storing any auth info from Shibboleth).
- Specified by:
loginPageURLin interfaceAuthenticationMethod- 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
-
getName
public String getName()
Description copied from interface:AuthenticationMethodReturns a short name that uniquely identifies this authentication method- Specified by:
getNamein interfaceAuthenticationMethod- Returns:
- The authentication method name
-
isEnabled
public static boolean isEnabled()
Check if Shibboleth plugin is enabled- Returns:
- true if enabled, false otherwise
-
findEPerson
protected EPerson findEPerson(Context context, javax.servlet.http.HttpServletRequest request) throws SQLException, AuthorizeException
Identify an existing EPerson based upon the shibboleth attributes provided on the request object. There are three cases where this can occurr, each as a fallback for the previous method. 1) NetID from Shibboleth Header (best) The NetID-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 Shibboleth Header (okay) In the case where a NetID header is not available or not found DSpace will fall back to identifying a user based upon their email address. 3) Tomcat's Remote User (worst) In the event that neither Shibboleth headers are found then as a last resort DSpace will look at Tomcat's remote user field. This is the least attractive option because Tomcat has no way to supply additional attributes about a user. Because of this the autoregister option is not supported if this method is used. If successful then the identified EPerson will be returned, otherwise null.- Parameters:
context- The DSpace database contextrequest- The current HTTP Request- Returns:
- The EPerson identified or null.
- Throws:
SQLException- if database errorAuthorizeException- if authorization error
-
registerNewEPerson
protected EPerson registerNewEPerson(Context context, javax.servlet.http.HttpServletRequest request) throws SQLException, AuthorizeException
Register a new eperson object. 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 object, such as the case when Tomcat's Remote User field is used to identify a particular user. 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 contextrequest- The current HTTP Request- Returns:
- A new eperson object or null if unable to create a new eperson.
- Throws:
SQLException- if database errorAuthorizeException- if authorization error
-
updateEPerson
protected void updateEPerson(Context context, javax.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 are defined by a mapping created in the dspace.cfg.- Parameters:
context- The current DSpace database contextrequest- The current HTTP Requesteperson- The eperson object to update.- Throws:
SQLException- if database errorAuthorizeException- if authorization error
-
swordCompatibility
protected int swordCompatibility(Context context, String username, String password, javax.servlet.http.HttpServletRequest request) throws SQLException
Provide password-based authentication to enable sword compatibility. Sword compatibility will allow this authentication method to work when using sword. Sword relies on username and password based authentication and is entirely incapable of supporting shibboleth. This option allows you to authenticate username and passwords for sword sessions without adding another authentication method onto the stack. You will need to ensure that a user has a password. One way to do that is to create the user via the create-administrator command line command and then edit their permissions.- Parameters:
context- The DSpace database contextusername- The usernamepassword- The passwordrequest- The HTTP Request- Returns:
- A valid DSpace Authentication Method status code.
- Throws:
SQLException- if database error
-
initialize
protected void initialize(Context context) throws SQLException
Initialize Shibboleth Authentication. During initalization the mapping of additional eperson metadata will be loaded from the DSpace.cfg 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 methods multiple times.- Parameters:
context- context- Throws:
SQLException- if database error
-
checkIfEpersonMetadataFieldExists
protected boolean checkIfEpersonMetadataFieldExists(Context context, String metadataName) throws SQLException
Check if a MetadataField 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 metadataField for an eperson- Parameters:
context- contextmetadataName- The name of the new metadata field.- Returns:
- True if successful, otherwise false.
- Throws:
SQLException- if database error
-
findAttribute
protected String findAttribute(javax.servlet.http.HttpServletRequest request, String name)
Find a particular Shibboleth header value and return the all values. The header name uses a bit of fuzzy logic, so it will first try case sensitive, then it will try lowercase, and finally it will try uppercase. This method will not interpret the header value in any way. This method will return null if value is empty.- Parameters:
request- The HTTP request to look for values in.name- The name of the attribute or header- Returns:
- The value of the attribute or header requested, or null if none found.
-
findSingleAttribute
protected String findSingleAttribute(javax.servlet.http.HttpServletRequest request, String name)
Find a particular Shibboleth header value and return the first value. The header name uses a bit of fuzzy logic, so it will first try case sensitive, then it will try lowercase, and finally it will try uppercase. Shibboleth attributes may contain multiple values separated by a semicolon. This method will return the first value in the attribute. If you need multiple values use findMultipleAttributes instead. If no attribute is found then null is returned.- Parameters:
request- The HTTP request to look for headers values on.name- The name of the header- Returns:
- The value of the header requested, or null if none found.
-
findMultipleAttributes
protected List<String> findMultipleAttributes(javax.servlet.http.HttpServletRequest request, String name)
Find a particular Shibboleth hattributeeader value and return the values. The attribute name uses a bit of fuzzy logic, so it will first try case sensitive, then it will try lowercase, and finally it will try uppercase. Shibboleth attributes may contain multiple values separated by a semicolon and semicolons are escaped with a backslash. This method will split all the attributes into a list and unescape semicolons. If no attributes are found then null is returned.- Parameters:
request- The HTTP request to look for headers values on.name- The name of the attribute- Returns:
- The list of values found, or null if none found.
-
isUsed
public boolean isUsed(Context context, javax.servlet.http.HttpServletRequest request)
Description copied from interface:AuthenticationMethodGet whether the authentication method is being used.- Specified by:
isUsedin interfaceAuthenticationMethod- Parameters:
context- The DSpace contextrequest- 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:AuthenticationMethodCheck if the given current password is valid to change the password of the given ePerson- Specified by:
canChangePasswordin interfaceAuthenticationMethod- Parameters:
context- The DSpace contextePerson- the ePerson related to the password changecurrentPassword- The current password to check- Returns:
- true if the provided password matches with current password
-
-