package org.dspace.app.xmlui.aspect.eperson; import java.io.IOException; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.acting.AbstractAction; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Redirector; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.environment.http.HttpEnvironment; import org.apache.cocoon.sitemap.PatternException; import org.apache.log4j.Logger; import org.dspace.app.xmlui.utils.AuthenticationUtil; import org.dspace.core.Context; import org.dspace.eperson.EPerson; /** * Attempt to authenticate the user based upon their presented credentials. This * action assumes that requests from the Ediauth server come from the localhost * and uses the http parameter of ea_edinaUserId as credentials. * * If the request doesn't come from the localhost then it is assumed that this * is a request from a user so a http parameter of sid is expected if a use session * exists. Otherwise it is assumed that the use is attempting to login. * * If the authentication attempt is successful then an HTTP redirect will be * sent to the browser redirecting them to their original location in the system * before authenticated or if none is supplied, back to the DSpace homepage. The * action will also return true, thus contents of the action will be executed. * * If the authentication attempt fails, the action returns false. * * Example use: * * <map:act name="EdiauthAuthenticateAction"> <map:serialize type="xml"/> </map:act> * <map:transform type="EdiauthLogin"> * * @author Ian Fieldhouse */ public class EdiauthAuthenticateAction extends AbstractAction { /** log4j category */ private static Logger log = Logger.getLogger(EdiauthAuthenticateAction.class); /** * Attempt to authenticate the user. */ public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception { Request request = ObjectModelHelper.getRequest(objectModel); String ea_edinaUserId = request.getParameter("ea_edinaUserId"); String ea_personal = request.getParameter("ea_personal"); String sid = request.getParameter("sid"); final HttpServletResponse httpResponse = (HttpServletResponse) objectModel.get(HttpEnvironment.HTTP_RESPONSE_OBJECT); /** * First check if this is a request by an end user or * the Ediauth server on the localhost */ // Determine where this request is coming from final String localIpv4 = "127.0.0.1"; final String localIpv6 = "0:0:0:0:0:0:0:1%0"; String remoteIp = request.getRemoteAddr(); log.info("Remote IP = " + remoteIp); if (remoteIp.equals(localIpv4) || remoteIp.equals(localIpv6)) { // request from Ediauth server // Skip out if no ea_edinaUserId given if (ea_edinaUserId == null){ log.info("No valid ea_edinaUserId supplied"); ediauthRedirect(httpResponse, null); } try { if (ea_personal.equals("0")){ log.info("ea_personal supplied is 0"); ediauthRedirect(httpResponse, null); } } catch (Exception e) { log.info("No valid ea_personal supplied"); ediauthRedirect(httpResponse, null); } log.info("Request from localhost so attempt to authenticate."); log.info("ea_edinaUserId supplied is: " + ea_edinaUserId); log.info("ea_personal supplied is 1"); try { Context context = AuthenticationUtil.Authenticate(objectModel,ea_edinaUserId, null, null); EPerson eperson = context.getCurrentUser(); if (eperson != null) { // The user has successfully logged in // Now determine the users session ID and send this to the EdiauthRedirect servlet String sessionId = request.getCocoonSession().getId(); ediauthRedirect(httpResponse, sessionId); // log the user out for the rest of this current request, // however they will be re-authenticated // fully when they come back from the redirect. This prevents // caching problems where part of the // request is performed fore the user was authenticated and the // other half after it succeeded. This way the user is fully // authenticated from the start of the request. context.setCurrentUser(null); //context.commit(); } } catch (SQLException sqle) { throw new PatternException("Unable to preform authentication", sqle); } } else { // request not from Ediauth server // Fail if no session id (sid) present. if (sid == null){ log.info("No sid supplied."); return null; } log.info("Request not from localhost."); Cookie cookie = new Cookie("JSESSIONID",sid); cookie.setPath(request.getContextPath()); httpResponse.addCookie(cookie); log.info("Set cookie with the JSESSIONID value set to sid ("+ sid +")."); // START GWaller 6/10/10 IssueID #303 Support for multiple licence options String redirectURL = request.getContextPath(); if (AuthenticationUtil.isInterupptedRequest(objectModel)) { // Resume the request and set the redirect target URL to // that of the originaly interrupted request. redirectURL += AuthenticationUtil.resumeInterruptedRequest(objectModel); } // END GWaller 6/10/10 IssueID #303 Support for multiple licence options httpResponse.sendRedirect(redirectURL); return new HashMap(); } return null; } private void ediauthRedirect(final HttpServletResponse httpResponse, String session_id) throws IOException { if (session_id == null) httpResponse.sendRedirect("ediauth-login-redirect"); else httpResponse.sendRedirect("ediauth-login-redirect?sid=" + session_id); } }