package auth.openid; import com.google.gwt.user.client.rpc.RemoteService; import org.openid4java.OpenIDException; import org.openid4java.consumer.ConsumerException; import org.openid4java.consumer.ConsumerManager; import org.openid4java.consumer.VerificationResult; import org.openid4java.discovery.DiscoveryInformation; import org.openid4java.discovery.Identifier; import org.openid4java.message.AuthRequest; import org.openid4java.message.ParameterList; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.text.MessageFormat; import java.util.List; import util.HttpCookies; import util.DependencyInjection; /** * Created by IntelliJ IDEA. * User: aviadbendov * Date: Apr 18, 2008 * Time: 9:27:03 PM * * A servlet incharge of the OpenID authentication process, from authentication to verification. */ @SuppressWarnings({"GwtInconsistentSerializableClass"}) public final class OpenIDServlet extends HttpServlet implements RemoteService { public static interface Callback { String getOpenIdServletURL(); String getLoginURL(); String createUniqueIdForUser(String user); void saveIdentifierForUniqueId(String uniqueId, Identifier identifier); } private static Callback callback = DependencyInjection.createInstnace(Callback.class); public static final String authParameter = "app-openid-auth"; public static final String nameParameter = "app-openid-name"; public static final String openIdCookieName = "app-openid-identifier"; public static final String uniqueIdCookieName = "app-openid-uniqueid"; private final ConsumerManager manager; public OpenIDServlet() { try { manager = new ConsumerManager(); } catch (ConsumerException e) { throw new RuntimeException("Error creating consumer manager", e); } } /** * Note: In a normal servlet environment, this method would probably * redirect the response itself. However, since GWT servlets do not allow for * such behavior, a path to this servlet is returned and the redirection is done * on the client side. * @param openIdName The OpenID identifier the user provided. * @return The URL the browser should be redirected to. */ public static String getAuthenticationURL(String openIdName) { // This is where a redirect for the response was supposed to occur; however, since GWT doesn't allow that // on responses coming from a GWT servlet, only a redirect via the web page is made. return MessageFormat.format("{3}?{1}=true&{2}={0}", openIdName, authParameter, nameParameter, callback.getOpenIdServletURL()); } /** * Returns the unique cookie and the OpenID identifier saved on the user's * browser. * * The servlet should be the only entity accessing and manipulating these cookies, * so it is also in-charge of fetching them when needed. * @param request The user's request to extract the cookies from. * @return Array containing { UniqueId, OpenID-Identifier } */ public static String[] getRequestUserInfo(HttpServletRequest request) { return new String[] { HttpCookies.getCookieValue(request, openIdCookieName), HttpCookies.getCookieValue(request, uniqueIdCookieName) }; } /** * Implements the GET method by either sending it to an OpenID authentication or verification * mechanism. * * Checks the parameters of the GET method; if they contain the "authParameter" set to true, * the authentication process is performed. If not, the verification process is performed * (the parameters in the verification process are controlled by the OpenID provider). * * @param request The request sent to the servlet. Might come from the GWT application or * the OpenID provider. * * @param response The response sent to the user. Generally used to redirect the user to the next * step in the OpenID process. * * @throws ServletException Usually wrapping an OpenID process exception. * @throws IOException Usually when redirection could not be performed. */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (Boolean.valueOf(request.getParameter(authParameter))) { authenticate(request, response); } else { verify(request, response); } } /** * Discovers the OpenID provider from the provided user string, and starts an authentication process * against it. * * This is done in three steps: *