Skip to content

Instantly share code, notes, and snippets.

@jdkanani
Created December 16, 2012 06:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jdkanani/4303883 to your computer and use it in GitHub Desktop.
Save jdkanani/4303883 to your computer and use it in GitHub Desktop.
OpenID for Java Web application - Relying Party (RP)
package org.myconsumer.services;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
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 javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
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.ConsumerException;
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.MessageException;
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 org.openid4java.message.sreg.SRegMessage;
import org.openid4java.message.sreg.SRegRequest;
import org.openid4java.message.sreg.SRegResponse;
import org.openid4java.util.ProxyProperties;
/**
* ConsumerService - Relying Party Service
* NOTE: Some part of the code has been adopted from `OpenID4Java` library wiki.
* */
@Path("/")
public class ConsumerService {
private static final Log LOG = LogFactory.getLog(ConsumerService.class);
private static final String OPENID_IDENTIFIER = "openid_identifier";
private static ConsumerManager manager = null;
@Context
ServletContext context;
@Context
ServletConfig config;
static {
try {
manager = new ConsumerManager();
manager.setAssociations(new InMemoryConsumerAssociationStore());
manager.setNonceVerifier(new InMemoryNonceVerifier(5000));
manager.setMinAssocSessEnc(AssociationSessionType.DH_SHA256);
} catch (ConsumerException e) {
LOG.error(e);
}
}
@POST
@Path("/")
@Consumes("application/x-www-form-urlencoded")
public void post(@QueryParam("is_return") String is_return,
@FormParam(OPENID_IDENTIFIER) String identifier,
@Context HttpServletRequest httpRequest,
@Context HttpServletResponse httpResponse,
MultivaluedMap<String, String> params) {
try {
if ("true".equals(is_return)) {
ParameterList paramList = new ParameterList(ConsumerService.getParamMap(params));
this.processReturn(httpRequest,httpResponse,paramList);
} else {
if (identifier != null) {
this.authRequest(identifier, httpRequest, httpResponse);
} else {
context.getRequestDispatcher("/index.jsp").forward(httpRequest, httpResponse);
}
}
} catch (ServletException e) {
LOG.error(e);
} catch (IOException e) {
LOG.error(e);
}
}
private void processReturn(HttpServletRequest req,
HttpServletResponse resp,
ParameterList params)
throws ServletException, IOException {
// verify response to ensure the communication has not been tampered with
Identifier identifier = this.verifyResponse(req, resp, params);
if (identifier == null) {
context.getRequestDispatcher("/index.jsp").forward(req, resp);
} else {
req.setAttribute("identifier", identifier.getIdentifier());
context.getRequestDispatcher("/return.jsp").forward(req, resp);
}
}
@SuppressWarnings("unchecked")
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 = httpReq.getRequestURL().toString() + "?is_return=true";
// perform discovery on the user-supplied identifier
List<DiscoveryInformation> 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();
fetch.addAttribute("email", // attribute alias
"http://schema.openid.net/contact/email", // type URI
true); // required
// attach the extension to the authentication request
authReq.addExtension(fetch);
// example using Simple Registration to fetching the 'email' attribute
SRegRequest sregReq = SRegRequest.createFetchRequest();
sregReq.addAttribute("fullname", false);
sregReq.addAttribute("dob", false);
authReq.addExtension(sregReq);
if (!discovered.isVersion2()) {
httpResp.sendRedirect(authReq.getDestinationUrl(true));
return null;
} else {
RequestDispatcher dispatcher = context.getRequestDispatcher("/provider-redirection.jsp");
httpReq.setAttribute("message", authReq);
dispatcher.forward(httpReq, httpResp);
}
} catch (OpenIDException e) {
throw new ServletException(e);
}
return null;
}
// processing the authentication response
public Identifier verifyResponse(HttpServletRequest httpReq, HttpServletResponse resp, ParameterList params)
throws ServletException {
try {
// extract the parameters from the authentication response
// (which comes in as a HTTP request from the OpenID provider)
ParameterList parameterList = new ParameterList(httpReq.getParameterMap());
parameterList.addParams(params);
// 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(), parameterList, discovered);
// examine the verification result and extract the verified
// identifier
Identifier verified = verification.getVerifiedId();
if (verified != null) {
AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
receiveSimpleRegistration(httpReq, authSuccess);
receiveAttributeExchange(httpReq, authSuccess);
return verified; // success
}
} catch (OpenIDException e) {
// present error to the user
throw new ServletException(e);
}
return null;
}
/**
* @param httpReq
* @param authSuccess
* @throws MessageException
*/
private void receiveSimpleRegistration(HttpServletRequest httpReq, AuthSuccess authSuccess) throws MessageException {
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);
}
}
}
}
/**
* @param httpReq
* @param authSuccess
* @throws MessageException
*/
private void receiveAttributeExchange(HttpServletRequest httpReq, AuthSuccess authSuccess) throws MessageException {
if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
List<String> aliases = fetchResp.getAttributeAliases();
Map<String, String> attributes = new LinkedHashMap<String, String>();
for (Iterator<String> iter = aliases.iterator(); iter.hasNext();) {
String alias = (String) iter.next();
List<String> values = fetchResp.getAttributeValues(alias);
if (values.size() > 0) {
String[] arr = new String[values.size()];
values.toArray(arr);
attributes.put(alias, arr[0]);
}
}
httpReq.setAttribute("attributes", attributes);
}
}
/**
* Utility function
* */
public static Map<String, String> getParamMap (MultivaluedMap<String, String> multiValuedMap) {
Map<String, String> map = new HashMap<String, String>();
Iterator<String> keysIter = multiValuedMap.keySet().iterator();
while (keysIter.hasNext()) {
String name = (String) keysIter.next();
Object v = multiValuedMap.get(name);
String value = null;
if (v instanceof List) {
@SuppressWarnings("unchecked")
List<String> values = (List<String>) v;
if (values.size() > 1 && name.startsWith("openid."))
throw new IllegalArgumentException(
"Multiple parameters with the same name: " + values);
value = values.size() > 0 ? values.get(0).toString() : null;
}
map.put(name, value);
}
return map;
}
}
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Consumer Login</title>
</head>
<body>
<fieldset>
<legend>Consumer</legend>
<form action="consumer" method="post">
<div>
<input type="text" name="openid_identifier" style="width: 50em; margin: 5px;"/>
</div>
<div>
<button type="submit" name="login">Login</button>
</div>
</form>
</fieldset>
</body>
</html>
<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>OpenID Provider Redirection</title>
</head>
<body onload="document.forms['openid-provider-redirection'].submit();">
<form name="openid-provider-redirection" action="${message.OPEndpoint}" method="post">
<c:forEach var="parameter" items="${message.parameterMap}">
<input type="hidden" name="${parameter.key}" value="${parameter.value}"/>
</c:forEach>
<button type="submit">Continue</button>
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<%@page contentType="text/html; charset=UTF-8" import="java.util.Map" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<title>OpenId sample</title>
</head>
<body>
<div>
<div>Login Success!</div>
<div>
<fieldset>
<legend>Your OpenID</legend>
<input type="text" name="openid_identifier" value="${identifier}" style="width: 50em"/>
</fieldset>
</div>
<div id="sreg-result">
<fieldset>
<legend>Simple Registration</legend>
<table>
<tr>
<th>Fullname:</th>
<td>${fullname}</td>
</tr>
<tr>
<th>Date of birth:</th>
<td>${dob}</td>
</tr>
</table>
</fieldset>
</div>
<div id="ax-result">
<fieldset>
<legend>Attribute Exchange</legend>
<table>
<c:forEach items="${attributes}" var="attribute">
<tr>
<th>${attribute.key}:</th>
<td>${attribute.value}</td>
</tr>
</c:forEach>
</table>
</fieldset>
</div>
</div>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>openid_consumer</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.myconsumer.services</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/consumer/*</url-pattern>
</servlet-mapping>
</web-app>
@jonathanlinadv
Copy link

What is the OpenID when I want to test the codes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment