Package com.data2semantics.yasgui.server.openid

Source Code of com.data2semantics.yasgui.server.openid.OpenIdServlet$Callback

package com.data2semantics.yasgui.server.openid;

/*
* #%L
* YASGUI
* %%
* Copyright (C) 2013 Laurens Rietveld
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
*/

import com.data2semantics.yasgui.server.db.DbHelper;
import com.data2semantics.yasgui.server.fetchers.ConfigFetcher;
import com.data2semantics.yasgui.shared.StaticConfig;
import com.data2semantics.yasgui.shared.UserDetails;
import com.google.gwt.user.client.rpc.RemoteService;

import org.json.JSONException;
import org.json.JSONObject;
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.AuthSuccess;
import org.openid4java.message.MessageExtension;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.List;

/**
* 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.
*/
public final class OpenIdServlet extends HttpServlet implements RemoteService {

  private static final long serialVersionUID = 6199183013097234155L;

  public static interface Callback {
    String getOpenIdServletURL(String baseUrl);

    String getLoginURL();

    String createUniqueIdForUser(JSONObject config, String loginString) throws ClassNotFoundException, FileNotFoundException, JSONException, SQLException, IOException;

    void saveIdentifierForUniqueId(File configDir, UserDetails userDetails) throws ClassNotFoundException, FileNotFoundException, JSONException, SQLException, IOException, ParseException;
  }

  private static Callback callback = new OpenIdCallback();

  public static final String authParameter = "app-openid-auth";
  public static final String appBaseUrl = "appBaseUrl";
  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() throws ConsumerException {
    manager = new ConsumerManager();
  }

  /**
   * <b>Note</b>: 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, String baseUrl, boolean inDebugMode) {
    // 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.
    String url = MessageFormat.format("{3}?{1}=true&{2}={0}&{4}={5}", openIdName, authParameter, nameParameter,
        callback.getOpenIdServletURL(baseUrl), appBaseUrl, baseUrl);
    if (inDebugMode) {
      url += "&" + StaticConfig.DEBUG_ARGUMENT_KEY + "=" + StaticConfig.DEBUG_ARGUMENT_VALUE;

    }
    return url;
  }

  /**
   * 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 }
   * @throws IOException
   * @throws SQLException
   * @throws JSONException
   * @throws FileNotFoundException
   * @throws ClassNotFoundException
   * @throws ParseException
   */
  public static UserDetails getRequestUserInfo(File configDir, HttpServletRequest request) throws ClassNotFoundException, FileNotFoundException, JSONException, SQLException, IOException, ParseException {
    UserDetails userDetails = new UserDetails();
    userDetails.setOpenId(HttpCookies.getCookieValue(request, openIdCookieName));
    userDetails.setUniqueId(HttpCookies.getCookieValue(request, uniqueIdCookieName));
    if (userDetails.getOpenId() != null && userDetails.getUniqueId() != null) {
      //get more info
      DbHelper db = new DbHelper(configDir, request);
      userDetails = db.getUserDetails(userDetails);
    }
   
   
    return userDetails;
  }

  /**
   * 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))) {
      System.out.println("trying to authenticate");
      try {
        authenticate(request, response);
      } catch (Exception e) {
        e.printStackTrace();
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
      }
    }
    if (request.getParameter("logOut") != null) {
      System.out.println("logging out");
      logOut(request, response);
    } else {
      try {
        System.out.println("verify authenticatation");
        verify(request, response);
      } catch (Exception e) {
        e.printStackTrace();
//        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
      }
    }
  }

  private void logOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
    System.out.println("logging out");
    String returnUrl = request.getParameter(appBaseUrl);
    if (request.getParameter(StaticConfig.DEBUG_ARGUMENT_KEY) != null) {
      returnUrl += "?" + StaticConfig.DEBUG_ARGUMENT_KEY + "="
          + request.getParameter(StaticConfig.DEBUG_ARGUMENT_KEY);
    }
    System.out.println("resetting cookies");
    HttpCookies.resetCookie(request, response, openIdCookieName);
    HttpCookies.resetCookie(request, response, uniqueIdCookieName);
    System.out.println("sending redirect url");
    response.sendRedirect(returnUrl);

  }

  /**
   * Discovers the OpenID provider from the provided user string, and starts
   * an authentication process against it.
   *
   * This is done in three steps:
   * <ol>
   * <li>Discover the OpenID provider URL</li>
   * <li>Create a unique cookie and send it to the user, so that after the
   * provider redirects the user back we'll know what to do with him.</li>
   * <li>Redirect the user to the provider URL, supplying the verification URL
   * as a return point.</li>
   * </ol>
   *
   * @param request
   *            The request for the OpenID authentication.
   * @param response
   *            The response, used to redirect the user.
   *
   * @throws IOException
   *             Occurs when a redirection is not successful.
   * @throws ServletException
   *             Wrapping an OpenID exception.
   * @throws JSONException
   * @throws ParseException
   * @throws SQLException
   * @throws ClassNotFoundException
   */
  private void authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException,
      ServletException, ParseException, JSONException, ClassNotFoundException, SQLException {
    final String loginString = request.getParameter(nameParameter);
    System.out.println("in authenticate");
    try {
      System.out.println("resetting cookies");
      HttpCookies.resetCookie(request, response, uniqueIdCookieName);
      HttpCookies.resetCookie(request, response, openIdCookieName);
     
      System.out.println("creating unique id");
      String uuid = callback.createUniqueIdForUser(ConfigFetcher.getJsonObjectFromPath(getServletContext().getRealPath("/")), loginString);
      HttpCookies.setCookie(request, response, uniqueIdCookieName, uuid);

      // perform discovery on the user-supplied identifier
      System.out.println("discovering");
      @SuppressWarnings("rawtypes")
      List discoveries = manager.discover(loginString);

      // attempt to associate with the OpenID provider
      // and retrieve one service endpoint for authentication
      System.out.println("retrieve single authentication endpoint");
      DiscoveryInformation discovered = manager.associate(discoveries);
     
      System.out.println("obtaining authrequest");
      // obtain a AuthRequest message to be sent to the OpenID provider
      String returnUrl = callback.getOpenIdServletURL(request.getParameter(appBaseUrl));
      if (request.getParameter(StaticConfig.DEBUG_ARGUMENT_KEY) != null) {
        returnUrl += "?" + StaticConfig.DEBUG_ARGUMENT_KEY + "="
            + request.getParameter(StaticConfig.DEBUG_ARGUMENT_KEY);
      }
      System.out.println("authenticate cookies");
      AuthRequest authReq = manager.authenticate(discovered, returnUrl, null);
      System.out.println("fetch request");
      FetchRequest fetch = FetchRequest.createFetchRequest();
      System.out.println("fetching attributes");
      fetch.addAttribute("oiFirstName", "http://schema.openid.net/namePerson/first", true);
      fetch.addAttribute("oiLastName", "http://schema.openid.net/namePerson/last", true);
      fetch.addAttribute("aFirstName", "http://axschema.org/namePerson/first", true);
      fetch.addAttribute("aLastName", "http://axschema.org/namePerson/last", true);
      fetch.addAttribute("aFullName", "http://axschema.org/namePerson", true);
      fetch.addAttribute("aNickName", "http://axschema.org/namePerson/friendly", true);
      fetch.addAttribute("oiNickName", "http://openid.net/schema/namePerson/friendly", true);
      fetch.addAttribute("aEmail", "http://axschema.org/contact/email", true);
      fetch.addAttribute("oiEmail", "http://schema.openid.net/contact/email", true);
     
      System.out.println("adding extension");
      authReq.addExtension(fetch);
      // redirect to OpenID for authentication
      System.out.println("sending redirect");
      response.sendRedirect(authReq.getDestinationUrl(true));
    } catch (OpenIDException e) {
      System.out.println("oid exception!");
      e.printStackTrace();
      throw new ServletException("Login string probably caused an error. loginString = " + loginString, e);
    }
  }

  /**
   * Checks the response received by the OpenID provider, and saves the user
   * identifier for later use if the authentication was sucesssful.
   *
   * <b>Note</b>: While confusing, the OpenID provider's response is in fact
   * encapsulated within the request; this is because it is the provider who
   * requested the page, and sent the response as parameters.
   *
   * This is done in three steps:
   * <ol>
   * <li>Verify the OpenID resposne.</li>
   * <li>If verification was successful, retrieve the OpenID identifier of the
   * user and save it for later use.</li>
   * <li>Redirect the user back to the main page of the application, together
   * with a cookie containing his OpneID identifier.</li>
   * </ol>
   *
   * @param request
   *            The request, containing the OpenID provider's response as
   *            parameters.
   * @param response
   *            The response, used to redirect the user back to the
   *            application page.
   * @throws IOException
   * @throws JSONException
   * @throws ParseException
   * @throws FileNotFoundException
   * @throws ServletException
   * @throws SQLException
   * @throws ClassNotFoundException
   * @throws Exception
   */
  private void verify(HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException, ParseException, JSONException, IOException, ServletException, ClassNotFoundException, SQLException {
    System.out.println("verifying");
    try {

      // extract the parameters from the authentication response
      // (which comes in as a HTTP request from the OpenID provider)
      ParameterList responseParams = new ParameterList(request.getParameterMap());
      System.out.println("extract receiving url");
      // extract the receiving URL from the HTTP request
      StringBuffer receivingURL = request.getRequestURL();
      String queryString = request.getQueryString();
      if (queryString != null && queryString.length() > 0)
        receivingURL.append("?").append(request.getQueryString());
     
      // verify the response; ConsumerManager needs to be the same
      // (static) instance used to place the authentication request
      System.out.println("actual verify");
      VerificationResult verification = manager.verify(receivingURL.toString(), responseParams, null);
      // examine the verification result and extract the verified
      // identifier
      System.out.println("getting verified id");
      Identifier id = verification.getVerifiedId();
     
      if (id != null) {
        System.out.println("id found");
        UserDetails userDetails = new UserDetails();
        userDetails.setUniqueId(HttpCookies.getCookieValue(request, uniqueIdCookieName));
        userDetails.setOpenId(id.getIdentifier());
        AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
        System.out.println("retrieved auth response");
        if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
          System.out.println("doing stuff for auth extension");
          MessageExtension ext = authSuccess.getExtension(AxMessage.OPENID_NS_AX);

          if (ext instanceof FetchResponse) {
            FetchResponse fetchResp = (FetchResponse) ext;
            System.out.println("adding attributes to user details");
            userDetails = addAttributes(fetchResp, userDetails);
          }

        }
        System.out.println("setting id cookie");
        HttpCookies.setCookie(request, response, openIdCookieName, id.getIdentifier());
        System.out.println("saving identifies for unique id");
        callback.saveIdentifierForUniqueId(new File(getServletContext().getRealPath("/")), userDetails);
      } else {
        System.out.println("id not found");
      }
      String url = callback.getLoginURL();
      if (request.getParameter(StaticConfig.DEBUG_ARGUMENT_KEY) != null) {
        url += "?" + StaticConfig.DEBUG_ARGUMENT_KEY + "="
            + request.getParameter(StaticConfig.DEBUG_ARGUMENT_KEY);
      }
      System.out.println("sending redirect url");
      response.sendRedirect(url);
    } catch (OpenIDException e) {
      throw new ServletException("Could not verify identity", e);
    }
  }

  private UserDetails addAttributes(FetchResponse fetchResp, UserDetails userDetails) {
    if (fetchResp.getAttributeValue("aFirstName") != null) {
      userDetails.setFirstName(fetchResp.getAttributeValue("aFirstName"));
    } else {
      userDetails.setFirstName(fetchResp.getAttributeValue("oiFirstName"));
    }
    if (fetchResp.getAttributeValue("aLastName") != null) {
      userDetails.setLastName(fetchResp.getAttributeValue("aLastName"));
    } else {
      userDetails.setLastName(fetchResp.getAttributeValue("oiLastName"));
    }
    if (fetchResp.getAttributeValue("aEmail") != null) {
      userDetails.setEmail(fetchResp.getAttributeValue("aEmail"));
    } else {
      userDetails.setEmail(fetchResp.getAttributeValue("oiEmail"));
    }
    userDetails.setFullName(fetchResp.getAttributeValue("aFullName"));
    if (fetchResp.getAttributeValue("aNickName") != null) {
      userDetails.setNickName(fetchResp.getAttributeValue("aNickName"));
    } else {
      userDetails.setNickName(fetchResp.getAttributeValue("oiNickName"));
    }
    return userDetails;
  }

}
TOP

Related Classes of com.data2semantics.yasgui.server.openid.OpenIdServlet$Callback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.