-
-
Save Kasha/4780223 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ 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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment