/** * Authenticate the given username/password pair, in conjunction with the onBehalfOf user. The * rules are that the username/password pair must successfully authenticate the user, and the * onBehalfOf user must exist in the user database. * * @param context * @param auth * @return a SWORD context holding the various user information * @throws SwordAuthException * @throws SwordError * @throws DSpaceSwordException */ private SwordContext authenticate(Context context, AuthCredentials auth) throws SwordAuthException, SwordError, DSpaceSwordException { String obo = auth.getOnBehalfOf(); String un = auth.getUsername(); String pw = auth.getPassword(); // smooth out the OnBehalfOf request, so that empty strings are // treated as null if ("".equals(obo)) { obo = null; } // first find out if we support on-behalf-of deposit boolean mediated = ConfigurationManager.getBooleanProperty("swordv2-server", "on-behalf-of.enable"); if (!mediated && obo != null) { // user is trying to do a mediated deposit on a repository which does not support it log.error("Attempted mediated deposit on service not configured to do so"); throw new SwordError( UriRegistry.ERROR_MEDIATION_NOT_ALLOWED, "Mediated deposit to this service is not permitted"); } log.info( LogManager.getHeader( context, "sword_authenticate", "username="******",on_behalf_of=" + obo)); try { // attempt to authenticate the primary user SwordContext sc = new SwordContext(); EPerson ep = null; boolean authenticated = false; if (this.authenticates(context, un, pw)) { // if authenticated, obtain the eperson object ep = context.getCurrentUser(); if (ep != null) { authenticated = true; sc.setAuthenticated(ep); // Set any special groups - invoke the authentication mgr. int[] groupIDs = AuthenticationManager.getSpecialGroups(context, null); for (int i = 0; i < groupIDs.length; i++) { context.setSpecialGroup(groupIDs[i]); log.debug("Adding Special Group id=" + String.valueOf(groupIDs[i])); } sc.setAuthenticatorContext(context); sc.setContext(context); } // if there is an onBehalfOfuser, then find their eperson // record, and if it exists set it. If not, then the // authentication process fails EPerson epObo = null; if (obo != null) { epObo = EPerson.findByEmail(context, obo); if (epObo == null) { epObo = EPerson.findByNetid(context, obo); } if (epObo != null) { sc.setOnBehalfOf(epObo); Context oboContext = this.constructContext(); oboContext.setCurrentUser(epObo); // Set any special groups - invoke the authentication mgr. int[] groupIDs = AuthenticationManager.getSpecialGroups(oboContext, null); for (int i = 0; i < groupIDs.length; i++) { oboContext.setSpecialGroup(groupIDs[i]); log.debug("Adding Special Group id=" + String.valueOf(groupIDs[i])); } sc.setContext(oboContext); } else { authenticated = false; throw new SwordError( UriRegistry.ERROR_TARGET_OWNER_UNKNOWN, "unable to identify on-behalf-of user: "******"sword_unable_to_set_user", "username="******"Unable to authenticate with the supplied credentials"); } else { // FIXME: this shouldn't ever happen now, but may as well leave it in just in case // there's a bug elsewhere log.info( LogManager.getHeader( context, "sword_unable_to_set_on_behalf_of", "username="******",on_behalf_of=" + obo)); throw new SwordAuthException("Unable to authenticate the onBehalfOf account"); } } return sc; } catch (SQLException e) { log.error("caught exception: ", e); throw new DSpaceSwordException( "There was a problem accessing the repository user database", e); } catch (AuthorizeException e) { log.error("caught exception: ", e); throw new SwordAuthException("There was a problem authenticating or authorising the user", e); } }
/** * Obtain a new context object. If a context object has already been created for this HTTP * request, it is re-used, otherwise it is created. If a user has authenticated with the system, * the current user of the context is set appropriately. * * @param request the HTTP request * @return a context object */ public static Context obtainContext(HttpServletRequest request) throws SQLException { // Set encoding to UTF-8, if not set yet // This avoids problems of using the HttpServletRequest // in the getSpecialGroups() for an AuthenticationMethod, // which causes the HttpServletRequest to default to // non-UTF-8 encoding. try { if (request.getCharacterEncoding() == null) { request.setCharacterEncoding(Constants.DEFAULT_ENCODING); } } catch (Exception e) { log.error("Unable to set encoding to UTF-8.", e); } Context c = (Context) request.getAttribute("dspace.context"); if (c == null) { // No context for this request yet c = new Context(); HttpSession session = request.getSession(); // See if a user has authentication Integer userID = (Integer) session.getAttribute("dspace.current.user.id"); if (userID != null) { String remAddr = (String) session.getAttribute("dspace.current.remote.addr"); if (remAddr != null && remAddr.equals(request.getRemoteAddr())) { EPerson e = EPerson.find(c, userID.intValue()); Authenticate.loggedIn(c, request, e); } else { log.warn( "POSSIBLE HIJACKED SESSION: request from " + request.getRemoteAddr() + " does not match original " + "session address: " + remAddr + ". Authentication rejected."); } } // Set any special groups - invoke the authentication mgr. int[] groupIDs = AuthenticationManager.getSpecialGroups(c, request); for (int i = 0; i < groupIDs.length; i++) { c.setSpecialGroup(groupIDs[i]); log.debug("Adding Special Group id=" + String.valueOf(groupIDs[i])); } // Set the session ID and IP address String ip = request.getRemoteAddr(); if (useProxies == null) { useProxies = ConfigurationManager.getBooleanProperty("useProxies", false); } if (useProxies && request.getHeader("X-Forwarded-For") != null) { /* This header is a comma delimited list */ for (String xfip : request.getHeader("X-Forwarded-For").split(",")) { if (!request.getHeader("X-Forwarded-For").contains(ip)) { ip = xfip.trim(); } } } c.setExtraLogInfo("session_id=" + request.getSession().getId() + ":ip_addr=" + ip); // Store the context in the request request.setAttribute("dspace.context", c); } // Set the locale to be used Locale sessionLocale = getSessionLocale(request); Config.set(request.getSession(), Config.FMT_LOCALE, sessionLocale); c.setCurrentLocale(sessionLocale); return c; }