Package er.openid

Source Code of er.openid.EROpenIDManager$EmailDelegate

package er.openid;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.log4j.Logger;
import org.openid4java.association.AssociationException;
import org.openid4java.consumer.ConsumerException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryException;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.MessageException;
import org.openid4java.message.MessageExtension;
import org.openid4java.message.Parameter;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;
import org.openid4java.message.sreg.SRegMessage;
import org.openid4java.message.sreg.SRegRequest;
import org.openid4java.util.HttpClientFactory;
import org.openid4java.util.ProxyProperties;

import com.webobjects.appserver.WOActionResults;
import com.webobjects.appserver.WOApplication;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WORedirect;
import com.webobjects.appserver.WORequest;
import com.webobjects.appserver.WOSession;
import com.webobjects.foundation.NSDictionary;

import er.extensions.appserver.ERXApplication;
import er.extensions.appserver.ERXRequest;
import er.extensions.foundation.ERXProperties;

/**
* EROpenIDManager is the primary interface to managing an OpenID connection.
*
* @property er.openid.proxyHostName the host name to use as a proxy (if necessary)
* @property er.openid.proxyPort the port to use as a proxy (if necessary)
* @property er.openid.formRedirectionPageName the name of the form redirection page to go to
*                                             (defaults to EROFormRedirectionPage, should implement IEROFormRedirectionPage)
* @property er.openid.requireSecureReturnURL whether to require secure return URL; default is true
* @property er.openid.disableRealmVerifier whether to disable realm verifier. see OpenID 2.0 specification.
*
* @author mschrag
*/
public class EROpenIDManager {
  public static final Logger log = Logger.getLogger(EROpenIDManager.class);

  private static final String DISCOVERY_INFO_KEY = "openIDDiscoveryInfo";
  private static EROpenIDManager _openIDManager;
  private ConsumerManager _manager;
  private EROpenIDManager.Delegate _delegate;

  /**
   * EROpenIDManager delegate
   */
  public static interface Delegate {
    /**
     * Returns OpenID message extensions for the fetch request. These message extensions will be sent to the OP
     * as requests for additional information.
     *
     * @param userSuppliedString the string the user supplied
     * @param request the WORequest
     * @param context the WOContext
     * @return a FetchRequest
     * @throws MessageException
     */
    public List<MessageExtension> createFetchMessageExtensions(String userSuppliedString, WORequest request, WOContext context) throws MessageException;
 
    /**
     * Returns an OpenID fetch request.
     * 
     * @param userSuppliedString the string the user supplied
     * @param request the WORequest
     * @param context the WOContext
     * @return a FetchRequest
     * @throws MessageException
     * @deprecated Replaced by {@link #createFetchMessageExtensions(String, WORequest, WOContext)}
     */
    @Deprecated
    public MessageExtension createFetchRequest(String userSuppliedString, WORequest request, WOContext context) throws MessageException;

    /**
     * Called after a response is received from the OpenID server.
     * 
     * @param verification the original verification result
     * @param eroResponse the EROResponse wrapper
     * @param request the WORequest
     * @param context the WOContext
     */
    public void responseReceived(VerificationResult verification, EROResponse eroResponse, WORequest request, WOContext context);

    /**
     * Returns the URL that the OpenID provider should come back to after authentication.
     *
     * @param request the WORequest
     * @param context the WOContext
     * @return the URL that the OpenID provider should come back to after authentication
     */
    public String returnToUrl(WORequest request, WOContext context);

    /**
     * Gives the delegate an opportunity to rewrite the receiving URL from the return
     * request after authentication.  This may be necessary if you are using rewrite
     * rules on your webserver, and the returnToUrl does not match the URL that
     * WebObjects may see in the WORequest.
     *
     * @param request the WORequest
     * @param context the WOContext
     * @return the rewritten URL
     */
    public String rewriteReceivingUrl(WORequest request, WOContext context);
  }

  /**
   * The default delegate implementation.
   */
  public static class DefaultDelegate implements EROpenIDManager.Delegate {

    @SuppressWarnings("unused")
    public List<MessageExtension> createFetchMessageExtensions(String userSuppliedString, WORequest request, WOContext context) throws MessageException {
      MessageExtension fetchRequest = this.createFetchRequest(userSuppliedString, request, context);
      ArrayList<MessageExtension> exts = new ArrayList<MessageExtension>();
      if (fetchRequest != null)
          exts.add(fetchRequest);
      return exts;
    }

    @SuppressWarnings("unused")
    @Deprecated
    public MessageExtension createFetchRequest(String userSuppliedString, WORequest request, WOContext context) throws MessageException {
      return null;
    }

    public void responseReceived(VerificationResult verification, EROResponse eroResponse, WORequest request, WOContext context) {
      // DO NOTHING
    }

    public String returnToUrl(WORequest request, WOContext context) {
      String returnToUrl;
      boolean requireSecureReturnURL = ERXProperties.booleanForKeyWithDefault("er.openid.requireSecureReturnURL", true);
      if (requireSecureReturnURL) {
        returnToUrl = context.directActionURLForActionNamed("ERODirectAction/openIDResponse", null, true, true);
      } else {
        returnToUrl = context.directActionURLForActionNamed("ERODirectAction/openIDResponse", NSDictionary.EmptyDictionary);
      }
      EROpenIDManager.log.debug("Return to URL: " + returnToUrl);
      return returnToUrl;
    }

    public String rewriteReceivingUrl(WORequest request, WOContext context) {
      StringBuffer receivingUrlBuffer = new StringBuffer();
      int serverPort = 0;
      String serverPortStr = request._serverPort();
      if (serverPortStr != null) {
        serverPort = Integer.parseInt(serverPortStr);
      }
      request._completeURLPrefix(receivingUrlBuffer, ERXRequest.isRequestSecure(request), serverPort);
      receivingUrlBuffer.append(request.uri());
      return receivingUrlBuffer.toString();
    }
  }

  /**
   * A simple delegate implementation that requests the user's email address. This is for example purposes only and
   * this code is not suitable for production use. To utilize this particular delegate, the client should ask the
   * EROResponse for a list of MessageExtensions. Then the client should iterate through those and retrieve the
   * specific extension parameter using methods appropriate to the type of the MessageExtension. For instance, if
   * the MessageExtension is an instance of SRegResponse, then the email parameter could be retrieved by casting the
   * MessageExtension to an SRegResponse and then using getAttributeValue("email") to retrieve the email.
   */
  public static class EmailDelegate extends EROpenIDManager.DefaultDelegate {
    @Override
    public List<MessageExtension> createFetchMessageExtensions(String userSuppliedString, WORequest request, WOContext context) throws MessageException {
      ArrayList<MessageExtension> exts = new ArrayList<MessageExtension>();
      FetchRequest fetchRequest = FetchRequest.createFetchRequest();
      fetchRequest.addAttribute("email-axschema", "http://axschema.org/contact/email", true);
      fetchRequest.addAttribute("email-openid", "http://schema.openid.net/contact/email", true);
      exts.add(fetchRequest);
      SRegRequest sregRequest = SRegRequest.createFetchRequest();
      sregRequest.addAttribute("email",true);
      exts.add(sregRequest);
      return exts;
    }
  }

  /**
   * Returns the singleton EROpenIDManager instance.
   *
   * @return the singleton EROpenIDManager instance
   */
  public static synchronized EROpenIDManager manager() {
    if (_openIDManager == null) {
      try {
        _openIDManager = new EROpenIDManager();
        _openIDManager.setDelegate(new DefaultDelegate());
      }
      catch (ConsumerException e) {
        throw new RuntimeException("Failed to create EROpenIDManager.", e);
      }
    }
    return _openIDManager;
  }

  /**
   * Constructs a new EROpenIDManager.
   *
   * @throws ConsumerException
   */
  protected EROpenIDManager() throws ConsumerException {
    _manager = new ConsumerManager();
    boolean disableRealmVerifier = ERXProperties.booleanForKeyWithDefault("er.openid.disableRealmVerifier", false);
    if (disableRealmVerifier) {
      _manager.getRealmVerifier().setEnforceRpId(false);
      EROpenIDManager.log.info("Disabling realm verifier.");
    }
  }

  /**
   * Set the delegate for this manager if you want to specify a custom
   * FetchRequest.
   *
   * @param delegate the new delegate
   */
  public void setDelegate(EROpenIDManager.Delegate delegate) {
    _delegate = delegate;
  }

  /**
   * Returns whether or not the given string looks like an OpenID auth string.
   *
   * @param userSuppliedString the string from the user
   * @return whether or not the given string looks like an OpenID auth string
   */
  public boolean isOpenIDAuth(String userSuppliedString) {
    return userSuppliedString != null && userSuppliedString.toLowerCase().startsWith("http://");
  }

  /**
   * Initiates the authentication request.
   *
   * @param userSuppliedString the string supplied by the user
   * @param realm explicit realm to use for the authRequest. Allows nulls.
   * @param request the WORequest
   * @param context the WOContext
   * @return the redirection action results
   * @throws MessageException
   * @throws DiscoveryException
   * @throws ConsumerException
   */
  public WOActionResults authRequest(String userSuppliedString, String realm, WORequest request, WOContext context) throws MessageException, DiscoveryException, ConsumerException {
    WOSession session = context.session();

    String proxyHostName = ERXProperties.stringForKey("er.openid.proxyHostName");
    if (proxyHostName != null) {
      int proxyPort = ERXProperties.intForKey("er.openid.proxyPort");
      // --- Forward proxy setup (only if needed) ---
      ProxyProperties proxyProps = new ProxyProperties();
      proxyProps.setProxyHostName(proxyHostName);
      proxyProps.setProxyPort(proxyPort);
      HttpClientFactory.setProxyProperties(proxyProps);
    }

    // perform discovery on the user-supplied identifier
    List discoveries = _manager.discover(userSuppliedString);

    // attempt to associate with the OpenID provider
    // and retrieve one service endpoint for authentication
    DiscoveryInformation discovered = _manager.associate(discoveries);

    // the next section will figure out where we go next, if anywhere.
    WOActionResults results = null;

    if (discovered != null)
    {
      // store the discovery information in the user's session
      session.setObjectForKey(discovered, EROpenIDManager.DISCOVERY_INFO_KEY);

      // configure the return_to URL where your application will receive
      // the authentication responses from the OpenID provider
      String returnToUrl = _delegate.returnToUrl(request, context);

      // obtain a AuthRequest message to be sent to the OpenID provider
      AuthRequest authReq = _manager.authenticate(discovered, returnToUrl, realm);

      // add the message extensions
      List<MessageExtension> exts = _delegate.createFetchMessageExtensions(userSuppliedString, request, context);
      for (MessageExtension ext : exts) {
        // attach the extension to the authentication request
        EROpenIDManager.log.debug("Authentication request extension: " + ext);
        authReq.addExtension(ext);
      }

      if (!discovered.isVersion2()) {
        WORedirect redirect = new WORedirect(context);
        String url = authReq.getDestinationUrl(true);
        EROpenIDManager.log.debug("Request URL: " + url);
        redirect.setUrl(url);
        results = redirect;
      }
      else {
        String formRedirectionPageName = ERXProperties.stringForKeyWithDefault("er.openid.formRedirectionPageName", EROFormRedirectionPage.class.getName());
        EROFormRedirectionPage formRedirectionPage = (EROFormRedirectionPage)WOApplication.application().pageWithName(formRedirectionPageName, context);
        formRedirectionPage.setParameters( authReq.getParameterMap() );
        String url = authReq.getDestinationUrl(false);
        EROpenIDManager.log.debug("Request URL: " + url);
        formRedirectionPage.takeValueForKey(url, "redirectionUrl");
        results = formRedirectionPage;
      }
    }

    return results;
  }

  /**
   * The callback for verifying the OpenID response.
   *
   * @param request the WORequest
   * @param context the WOContext
   * @return the OpenID response
   * @throws MessageException
   * @throws DiscoveryException
   * @throws AssociationException
   */
  public EROResponse verifyResponse(WORequest request, WOContext context) throws MessageException, DiscoveryException, AssociationException {

    WOSession session = context.session();

    // extract the parameters from the authentication response
    // (which comes in as a HTTP request from the OpenID provider)
    ParameterList responseParameters = new ParameterList();
    Enumeration formValueKeyEnum = request.formValueKeys().objectEnumerator();
    while (formValueKeyEnum.hasMoreElements()) {
      String formValueKey = (String) formValueKeyEnum.nextElement();
      String formValue = request.stringFormValueForKey(formValueKey);
      responseParameters.set(new Parameter(formValueKey, formValue));
      EROpenIDManager.log.debug("Response parameter: " + formValueKey + " => " + formValue);
    }

    // retrieve the previously stored discovery information
    DiscoveryInformation discovered = (DiscoveryInformation) session.objectForKey(EROpenIDManager.DISCOVERY_INFO_KEY);

    // extract the receiving URL from the HTTP request

    String receivingUrl = _delegate.rewriteReceivingUrl(request, context);

    // verify the response; ConsumerManager needs to be the same
    // (static) instance used to place the authentication request
    VerificationResult verification = _manager.verify(receivingUrl, responseParameters, discovered);

    // examine the verification result and extract the verified identifier
    FetchResponse fetchResponse = null;
    List<MessageExtension> messageExtensions = new ArrayList<MessageExtension>();
    Identifier identifier = verification.getVerifiedId();
    if (identifier != null) {
      AuthSuccess authSuccess = AuthSuccess.createAuthSuccess(responseParameters);
      EROpenIDManager.log.debug("AuthSucess:" + authSuccess);

      if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
        MessageExtension ext = authSuccess.getExtension(AxMessage.OPENID_NS_AX);
        messageExtensions.add(ext);
        EROpenIDManager.log.debug("MessageExtension (AX):" + ext);
        // handle backwards, deprecated compatibility
        if (ext instanceof FetchResponse && fetchResponse == null)
          fetchResponse = (FetchResponse)ext;
      }

      if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
        MessageExtension ext = authSuccess.getExtension(SRegMessage.OPENID_NS_SREG);
        messageExtensions.add(ext);
        EROpenIDManager.log.debug("MessageExtension (SREG):" + ext);
      }

      if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG11)) {
        MessageExtension ext = authSuccess.getExtension(SRegMessage.OPENID_NS_SREG11);
        messageExtensions.add(ext);
        EROpenIDManager.log.debug("MessageExtension (SREG11):" + ext);
      }
    }

    EROResponse eroResponse = new EROResponse(identifier, fetchResponse, messageExtensions);
    _delegate.responseReceived(verification, eroResponse, request, context);
    return eroResponse;
  }
}
TOP

Related Classes of er.openid.EROpenIDManager$EmailDelegate

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.