OpenId - 如何在登录前返回用户所在的URL

时间:2010-02-04 22:56:56

标签: openid

当我的网站用户点击登录时,会同时发送一个return_to网址,因此我知道在成功登录后该用户应该返回哪个页面。当我将用户重定向到他们的openid提供者时,该信息会丢失。

如何保留return_to url?

如果重要,我正在使用openid4java。

2 个答案:

答案 0 :(得分:1)

当您将用户重定向到其身份提供商时,您需要为其提供重定向或将用户重新发送回的URL。这可以是您的return_to网址。如果您需要跟踪更多URL或任何其他信息,可以将它们作为此URL的参数包含在内。

答案 1 :(得分:0)

我今天遇到了这个问题,三个小时之后,我似乎设法解决了这个问题。

我正在使用:

调用LoginServlet
out.println("<!--Open IDs login-->");
out.println("<div style=\"margin-left: 50px; margin-top: 40px; height: 60px;\"><form action=\"../web/login?identifier=https://www.google.com/accounts/o8/id&afterLoginUrl=" 
      + UsualHtmlUtils.encodeURL(returnToUrl) + "\" method=\"post\"> <input class=\"google openid_large_btn\" "
      + "style=\"background: #fff url(../images/openid-logos.png); background-position: -1px -1px;\" type=\"image\" value=\" \" /></form>");
out.println("<form action=\"../web/login?identifier=https://me.yahoo.com&afterLoginUrl=" + UsualHtmlUtils.encodeURL(returnToUrl) 
      + "\" method=\"post\"><input class=\"google openid_large_btn\" style=\"background: #fff url(../images/openid-logos.png); background-position: -1px -63px;\" type=\"image\" value=\" \" /> </form></div>");

并且实际的LoginServlet看起来如下:

import commons.StringUtils;
import commons.UsualHtmlUtils;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.openid4java.OpenIDException;
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.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;

/**
 *
 * @author mladen
 */
@WebServlet(name = "LoginServlet", urlPatterns = {"/web/login"})
public class LoginServlet extends HttpServlet {

  final static String YAHOO_ENDPOINT = "https://me.yahoo.com";
  final static String GOOGLE_ENDPOINT = "https://www.google.com/accounts/o8/id";
  private static final long serialVersionUID = 309579782731258702L;
  private ServletContext context;
  private ConsumerManager manager;

  @Override
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    context = config.getServletContext();
    this.manager = new ConsumerManager();
  }

  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException, IOException {
//log.debug("context: " + context);
    Identifier identifier = this.verifyResponse(req);
//log.debug("identifier: " + identifier);
// if openid login succeded redirect to home page using our demo account
//if your site is open to anyone without login you can do the redirect directly
    if (identifier != null) {
      //WebAuthentication pwl = new WebAuthentication();
      //pwl.login("guest", "guest");**
      String afterLoginUrl = req.getParameter("afterLoginUrl"); 
      if (afterLoginUrl == null) {
        afterLoginUrl = "../def/";
      }
      resp.sendRedirect(afterLoginUrl);
    } else {
      Logger.getLogger(this.getClass().getName()).log(Level.INFO, "attr= {0}", StringUtils.toString("login with openid failed"));
      resp.sendRedirect("../def/");
    }
  }

  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException, IOException {
    String identifier = req.getParameter("identifier");
    String afterLoginUrl = req.getParameter("afterLoginUrl");
    //req.getSession().setAttribute("afterLoginUrl", req.getRequestURL().toString());
    this.authRequest(identifier, afterLoginUrl, req, resp);
  }

  // --- placing the authentication request ---
  public String authRequest(String userSuppliedString, String afterLoginUrl,
          HttpServletRequest httpReq, HttpServletResponse httpResp)
          throws IOException {
    try {
      // configure the return_to URL where your application will receive
      // the authentication responses from the OpenID provider
      String returnToUrl = httpReq.getRequestURL().toString() + "?afterLoginUrl=" + UsualHtmlUtils.encodeURL(afterLoginUrl);

      Logger.getLogger(this.getClass().getName()).log(Level.INFO, "attr= {0}", StringUtils.toString("444 returnToUrl=" + returnToUrl));

      // --- Forward proxy setup (only if needed) ---
      // ProxyProperties proxyProps = new ProxyProperties();
      // proxyProps.setProxyName("proxy.example.com");
      // proxyProps.setProxyPort(8080);
      // 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);

      // store the discovery information in the user's session
      httpReq.getSession().setAttribute("openid-disc", discovered);

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

      FetchRequest fetch = FetchRequest.createFetchRequest();
      if (userSuppliedString.startsWith(GOOGLE_ENDPOINT)) {
        fetch.addAttribute("email", "http://axschema.org/contact/email", true);
        fetch.addAttribute("firstName",  "http://axschema.org/namePerson/first", true);
        fetch.addAttribute("lastName", "http://axschema.org/namePerson/last", true);
      } else if (userSuppliedString.startsWith(YAHOO_ENDPOINT)) {
        fetch.addAttribute("email", "http://axschema.org/contact/email", true);
        fetch.addAttribute("fullname", "http://axschema.org/namePerson", true);
      } else { // works for myOpenID
        fetch.addAttribute("fullname", "http://schema.openid.net/namePerson", true);
        fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);
      }

      // attach the extension to the authentication request
      authReq.addExtension(fetch);

      httpResp.sendRedirect(authReq.getDestinationUrl(true));

    } catch (OpenIDException e) {
      // present error to the user
    }

    return null;
  }

  // --- processing the authentication response ---
  public Identifier verifyResponse(HttpServletRequest httpReq) {
    try {
      // extract the parameters from the authentication response
      // (which comes in as a HTTP request from the OpenID provider)
      ParameterList response = new ParameterList(httpReq.getParameterMap());

      // retrieve the previously stored discovery information
      DiscoveryInformation discovered = (DiscoveryInformation) httpReq.getSession().getAttribute("openid-disc");

      // extract the receiving URL from the HTTP request
      StringBuffer receivingURL = httpReq.getRequestURL();
      String queryString = httpReq.getQueryString();
      if (queryString != null && queryString.length() > 0) {
        receivingURL.append("?").append(httpReq.getQueryString());
      }

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

      // examine the verification result and extract the verified
      // identifier
      Identifier verified = verification.getVerifiedId();
      if (verified != null) {
        AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();

        if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
          FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);

          List emails = fetchResp.getAttributeValues("email");
          String email = (String) emails.get(0);
          Logger.getLogger(this.getClass().getName()).log(Level.INFO, "OpenIdlogin done with email: {0}", email);

          Map<String, List<String>> respAttributes = fetchResp.getAttributes();
          Logger.getLogger(this.getClass().getName()).log(Level.INFO, "attr= {0}", StringUtils.toString(respAttributes));
          //for (Map.Entry<String, List<String>> entry : respAttributes.entrySet()) {
          //Logger.getLogger(this.getClass().getName()).log(Level.INFO, "key = " + entry + ", value = " + StringUtils.toString(respAttributes));
          //  entry.getKey();
           //}
        //fetch.addAttribute("firstName",  "http://axschema.org/namePerson/first", true);
        //fetch.addAttribute("lastName", "http://axschema.org/namePerson/last", true);

        }

        return verified; // success
      }
    } catch (OpenIDException e) {
      // present error to the user
    }

    return null;
  }
}

我不明白为什么这没有记录好。 openid4java实际上看起来没有文档。

希望这有帮助。