У меня была эта проблема сегодня, и через три часа, похоже, мне удалось ее решить.
Я вызываю 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 выглядит недокументированным на самом деле.
Надеюсь, это поможет.