WindowsSSONAuthenticator.java
- /**
- * Originally contributed by eMation (www.emation.pt)
- */
- package org.itracker.services.authentication.adsson;
- import org.apache.log4j.Logger;
- import org.itracker.model.User;
- import org.itracker.UserException;
- import org.itracker.model.UserPreferences;
- import org.itracker.services.UserService;
- import org.itracker.services.authentication.DefaultAuthenticator;
- import org.itracker.services.exceptions.AuthenticatorException;
- import org.itracker.model.util.UserUtilities;
- import javax.servlet.http.HttpServletRequest;
- import java.rmi.RemoteException;
- import java.util.Date;
- /**
- * Single Sign On class with Windows
- * <p/>
- * Gets an authentication from jcifs web filter, gets user information from
- * active directory, creates or updates the user with that information if needed
- *
- * @author Ricardo Trindade (ricardo.trindade@emation.pt)
- */
- public abstract class WindowsSSONAuthenticator extends DefaultAuthenticator {
- private static final Logger logger = Logger.getLogger(WindowsSSONAuthenticator.class);
- private static String TEMPLATE_USER = "TemplateUser";
- /**
- * @see org.itracker.ejb.authentication.AbstractPluggableAuthenticator#checkLogin(java.lang.String,
- * java.lang.Object, int, int)
- */
- public User checkLogin(String login, Object authentication, int authType, int reqSource)
- throws AuthenticatorException {
- User userModel;
- try {
- // this authenticator only handles authType=AUTH_TYPE_REQUEST
- // (HttpServletRequest)
- if (authType != AUTH_TYPE_REQUEST || !(authentication instanceof HttpServletRequest)) {
- logger.error("Only http request authentication supported by this single sign on class. Received "
- + authType);
- throw new AuthenticatorException(
- "Only http request authentication supported by this single sign on class",
- AuthenticatorException.INVALID_AUTHENTICATION_TYPE);
- }
- UserService userService = getUserService();
- // validate we're really using jcifs, and we
- // have a valid authentication object
- // TODO: get user from jcifs
- String theLogin = ((HttpServletRequest) authentication).getRemoteUser();
- if (theLogin == null) {
- throw new AuthenticatorException("User obtained from jcifs is null. Check that jcifs is active",
- AuthenticatorException.CUSTOM_ERROR);
- }
- // sometimes jcifs sends the username in the form of DOMAIN\USER
- if (theLogin.indexOf("\\") > 0) {
- theLogin = theLogin.substring(theLogin.indexOf("\\") + 1);
- }
- if (!theLogin.equals(login)) {
- // should an exception be thrown here?
- AuthenticatorException ex = new AuthenticatorException("User obtained from authenticator does not match, got " + theLogin + ", expected " + login + ".",
- AuthenticatorException.CUSTOM_ERROR);
- logger.warn("checkLogin: checking login for " + login + " but got " + theLogin + " in authentication " + authentication, ex);
- throw ex;
- }
- userModel = updateOrCreateUser(theLogin, userService);
- return userModel;
- } catch (RemoteException ex) {
- logger.error("pt_PT", ex);
- throw new AuthenticatorException(ex.getMessage(), AuthenticatorException.SYSTEM_ERROR, ex);
- } catch (UserException ex) {
- logger.error("pt_PT", ex);
- throw new AuthenticatorException(ex.getMessage(), AuthenticatorException.SYSTEM_ERROR, ex);
- } catch (AuthenticatorException ex) {
- logger.error("pt_PT", ex);
- throw new AuthenticatorException(ex.getMessage(), AuthenticatorException.SYSTEM_ERROR, ex);
- }
- }
- /**
- * Checks if the user needs creating or updating, and if so, do it
- */
- private User updateOrCreateUser(String login, UserService userService) throws RemoteException, UserException,
- AuthenticatorException {
- User userModel;
- // check if the user already exists in ITracker
- // if he already exists, and needs updating, update him
- // if not, create him
- userModel = userService.getUserByLogin(login);
- if (null == userModel) {
- userModel = createUser(login, userService);
- } else {
- // user exists, update if needed
- // get user info from authentication source
- if (needsUpdate(userModel, getExternalUserInfo(login))) {
- // update user here...
- // userService.updateUser();
- // get updated version
- userModel = userService.getUserByLogin(login);
- userModel = updateUser(userModel, getExternalUserInfo(login));
- userService.updateUser(userModel);
- }
- }
- return userModel;
- }
- /**
- * Updates parts of profile that are obtained from external source
- */
- private User updateUser(User oldUserModel, User newUserModel) {
- oldUserModel.setEmail(newUserModel.getEmail());
- oldUserModel.setFirstName(newUserModel.getFirstName());
- oldUserModel.setLastName(newUserModel.getLastName());
- oldUserModel.setLastModifiedDate(new Date());
- oldUserModel.setSuperUser(newUserModel.isSuperUser());
- return (oldUserModel);
- }
- /**
- * Create a user in the ITracker database
- */
- private User createUser(String login, UserService userService) throws RemoteException, UserException,
- AuthenticatorException {
- // doesn't exist, create
- User userModel = getExternalUserInfo(login);
- userModel.setRegistrationType(UserUtilities.REGISTRATION_TYPE_ADMIN);
- userModel.setStatus(UserUtilities.STATUS_ACTIVE);
- userModel = userService.createUser(userModel);
- // if this user is a super user, there is no need to set default
- // permissions
- // if not, set default permissions
- if (!userModel.isSuperUser()) {
- setDefaultPermissions(userModel, userService);
- }
- return userModel;
- }
- /**
- * Set the default user permissions
- * <p/>
- * Default user permissions are the same as those of a user called
- * "TemplateUser"
- */
- private void setDefaultPermissions(User userModel, UserService userService) throws RemoteException,
- AuthenticatorException, UserException {
- User templateUser = userService.getUserByLogin(TEMPLATE_USER);
- if (templateUser == null) {
- String errorMessage = "TemplateUser not found. Create a user called template user, new permissions are copied from him to new users";
- logger.error(errorMessage);
- throw new AuthenticatorException(errorMessage, AuthenticatorException.CUSTOM_ERROR);
- }
- // set permissions
- userService.setUserPermissions(userModel.getId(), userService.getPermissionsByUserId(templateUser.getId()));
- // set preferences
- UserPreferences preferences = templateUser.getPreferences();
- preferences.setUser(userModel);
- userService.updateUserPreferences(preferences);
- }
- /**
- * Checks if a given internal user needs updating, by comparing him with the
- * external user data source
- *
- * @param localUser The local User
- * @param remoteUser The remote User
- * @return true if the user needs updating, false otherwise
- */
- private boolean needsUpdate(User localUser, User remoteUser) {
- if (!(localUser.getEmail().equals(remoteUser.getEmail())))
- return true;
- if (!(localUser.getFirstName().equals(remoteUser.getFirstName())))
- return true;
- if (!(localUser.getLastName().equals(remoteUser.getLastName())))
- return true;
- if (localUser.isSuperUser() != remoteUser.isSuperUser())
- return true;
- return (false);
- }
- protected abstract User getExternalUserInfo(String login) throws AuthenticatorException;
- /*
- * (non-Javadoc)
- *
- * @see org.itracker.ejb.authentication.AbstractPluggableAuthenticator#allowProfileUpdates(org.itracker.model.deprecatedmodels.User,
- * java.lang.Object, int, int)
- */
- public boolean allowProfileUpdates(User user, Object authentication, int authType, int reqSource)
- throws AuthenticatorException {
- return true;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.itracker.ejb.authentication.AbstractPluggableAuthenticator#allowPasswordUpdates(org.itracker.model.deprecatedmodels.User,
- * java.lang.Object, int, int)
- */
- public boolean allowPasswordUpdates(User user, Object authentication, int authType, int reqSource)
- throws AuthenticatorException {
- return false;
- }
- }