/**
* Created on 2007-4-14 00:54:50
*/
package com.ubc.servlet;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openid4java.OpenIDException;
import org.openid4java.association.AssociationSessionType;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.InMemoryConsumerAssociationStore;
import org.openid4java.consumer.InMemoryNonceVerifier;
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.FetchResponse;
import org.openid4java.message.sreg.SRegMessage;
import org.openid4java.message.sreg.SRegRequest;
import org.openid4java.message.sreg.SRegResponse;
import org.openid4java.util.HttpClientFactory;
import org.openid4java.util.ProxyProperties;
/**
* @author Sutra Zhou
*/
public class ConsumerServlet extends javax.servlet.http.HttpServlet {
/**
*
*/
private static final long serialVersionUID = -5998885243419513055L;
private static final String OPTIONAL_VALUE = "0";
private static final String REQUIRED_VALUE = "1";
private static final Log LOG = LogFactory.getLog(ConsumerServlet.class);
private ServletContext context;
private ConsumerManager manager;
/**
* {@inheritDoc}
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
context = config.getServletContext();
LOG.debug("context: " + context);
// --- Forward proxy setup (only if needed) ---
ProxyProperties proxyProps = getProxyProperties(config);
if (proxyProps != null) {
LOG.debug("ProxyProperties: " + proxyProps);
HttpClientFactory.setProxyProperties(proxyProps);
}
this.manager = new ConsumerManager();
manager.setAssociations(new InMemoryConsumerAssociationStore());
manager.setNonceVerifier(new InMemoryNonceVerifier(5000));
manager.setMinAssocSessEnc(AssociationSessionType.DH_SHA256);
}
/**
* {@inheritDoc}
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
/**
* {@inheritDoc}
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if ("true".equals(req.getParameter("is_return"))) {
processReturn(req, resp);
} else {
String identifier = req.getParameter("openid_identifier");
if (identifier != null) {
this.authRequest(identifier, req, resp);
} else {
this.getServletContext().getRequestDispatcher("/index.jsp").forward(req, resp);
}
}
}
private void processReturn(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Identifier identifier = this.verifyResponse(req);
LOG.debug("identifier: " + identifier);
if (identifier == null) {
this.getServletContext().getRequestDispatcher("/index.jsp").forward(req, resp);
} else {
req.setAttribute("identifier", identifier.getIdentifier());
this.getServletContext().getRequestDispatcher("/return.jsp").forward(req, resp);
}
}
// --- placing the authentication request ---
public String authRequest(String userSuppliedString,
HttpServletRequest httpReq, HttpServletResponse httpResp)
throws IOException, ServletException {
try {
// configure the return_to URL where your application will receive
// the authentication responses from the OpenID provider
// String returnToUrl = "http://example.com/openid";
String returnToUrl = httpReq.getRequestURL().toString()
+ "?is_return=true";
// 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);
// Attribute Exchange example: fetching the 'email' attribute
// FetchRequest fetch = FetchRequest.createFetchRequest();
SRegRequest sregReq = SRegRequest.createFetchRequest();
String[] attributes = {"nickname", "email", "fullname", "dob",
"gender", "postcode", "country", "language", "timezone"};
for (int i = 0, l = attributes.length; i < l; i++) {
String attribute = attributes[i];
String value = httpReq.getParameter(attribute);
if (OPTIONAL_VALUE.equals(value)) {
sregReq.addAttribute(attribute, false);
} else if (REQUIRED_VALUE.equals(value)) {
sregReq.addAttribute(attribute, true);
}
}
// attach the extension to the authentication request
if (!sregReq.getAttributes().isEmpty()) {
authReq.addExtension(sregReq);
}
if (!discovered.isVersion2()) {
// Option 1: GET HTTP-redirect to the OpenID Provider endpoint
// The only method supported in OpenID 1.x
// redirect-URL usually limited ~2048 bytes
httpResp.sendRedirect(authReq.getDestinationUrl(true));
return null;
} else {
// Option 2: HTML FORM Redirection (Allows payloads >2048 bytes)
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/formredirection.jsp");
httpReq.setAttribute("prameterMap", httpReq.getParameterMap());
httpReq.setAttribute("message", authReq);
// httpReq.setAttribute("destinationUrl", httpResp
// .getDestinationUrl(false));
dispatcher.forward(httpReq, httpResp);
}
} catch (OpenIDException e) {
// present error to the user
throw new ServletException(e);
}
return null;
}
// --- processing the authentication response ---
public Identifier verifyResponse(HttpServletRequest httpReq)
throws ServletException {
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(SRegMessage.OPENID_NS_SREG)) {
MessageExtension ext = authSuccess.getExtension(SRegMessage.OPENID_NS_SREG);
if (ext instanceof SRegResponse) {
SRegResponse sregResp = (SRegResponse) ext;
for (Iterator iter = sregResp.getAttributeNames().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value = sregResp.getParameterValue(name);
httpReq.setAttribute(name, value);
}
}
}
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);
List aliases = fetchResp.getAttributeAliases();
for (Iterator iter = aliases.iterator(); iter.hasNext();) {
String alias = (String) iter.next();
List values = fetchResp.getAttributeValues(alias);
if (values.size() > 0) {
LOG.debug(alias + " : " + values.get(0));
httpReq.setAttribute(alias, values.get(0));
}
}
}
return verified; // success
}
} catch (OpenIDException e) {
// present error to the user
throw new ServletException(e);
}
return null;
}
/**
* Get proxy properties from the context init params.
*
* @return proxy properties
*/
private static ProxyProperties getProxyProperties(ServletConfig config) {
ProxyProperties proxyProps;
String host = config.getInitParameter("proxy.host");
LOG.debug("proxy.host: " + host);
if (host == null) {
proxyProps = null;
} else {
proxyProps = new ProxyProperties();
String port = config.getInitParameter("proxy.port");
String username = config.getInitParameter("proxy.username");
String password = config.getInitParameter("proxy.password");
String domain = config.getInitParameter("proxy.domain");
proxyProps.setProxyHostName(host);
proxyProps.setProxyPort(Integer.parseInt(port));
proxyProps.setUserName(username);
proxyProps.setPassword(password);
proxyProps.setDomain(domain);
}
return proxyProps;
}
}