
org.picketlink.social.openid.OpenIDProcessor Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.picketlink.social.openid;
import org.apache.catalina.Realm;
import org.apache.catalina.Session;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.log4j.Logger;
import org.openid4java.consumer.ConsumerException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryException;
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.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;
import org.picketlink.common.util.StringUtil;
import org.picketlink.social.standalone.oauth.OpenIDAliasMapper;
import org.picketlink.social.standalone.oauth.OpenIdPrincipal;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Processor for the OpenID interaction
*
* @author Anil Saldhana
* @since Sep 22, 2011
*/
public class OpenIDProcessor {
protected static Logger log = Logger.getLogger(OpenIDProcessor.class);
protected boolean trace = log.isTraceEnabled();
public static final String AUTH_TYPE = "authType";
private ConsumerManager openIdConsumerManager;
private FetchRequest fetchRequest;
private String openIdServiceUrl = null;
private String returnURL = null;
private String requiredAttributes, optionalAttributes = null;
private boolean initialized = false;
protected List roles = new ArrayList();
public static ThreadLocal cachedPrincipal = new ThreadLocal();
public static ThreadLocal> cachedRoles = new ThreadLocal>();
public static String EMPTY_PASSWORD = "EMPTY";
private enum STATES {
AUTH,
AUTHZ,
FINISH
}
;
private enum Providers {
GOOGLE("https://www.google.com/accounts/o8/id"),
YAHOO("https://me.yahoo.com/"),
MYSPACE("myspace.com"),
MYOPENID(
"https://myopenid.com/");
private String name;
Providers(String name) {
this.name = name;
}
String get() {
return name;
}
}
public OpenIDProcessor(String theReturnURL, String requiredAttributes, String optionalAttributes) {
this.returnURL = theReturnURL;
this.requiredAttributes = requiredAttributes;
this.optionalAttributes = optionalAttributes;
}
/**
* Return whether the processor has initialized
*
* @return
*/
public boolean isInitialized() {
return initialized;
}
/**
* Initialize the processor
*
* @param requiredRoles
*
* @throws MessageException
* @throws ConsumerException
*/
public void initialize(List requiredRoles) throws MessageException, ConsumerException {
if (openIdConsumerManager == null) {
openIdConsumerManager = new ConsumerManager();
}
fetchRequest = FetchRequest.createFetchRequest();
// Work on the required attributes
if (StringUtil.isNotNull(requiredAttributes)) {
List tokens = StringUtil.tokenize(requiredAttributes);
for (String token : tokens) {
fetchRequest.addAttribute(token, OpenIDAliasMapper.get(token), true);
}
}
// Work on the optional attributes
if (StringUtil.isNotNull(optionalAttributes)) {
List tokens = StringUtil.tokenize(optionalAttributes);
for (String token : tokens) {
String type = OpenIDAliasMapper.get(token);
if (type == null) {
log.error("Null Type returned for " + token);
}
fetchRequest.addAttribute(token, type, false);
}
}
roles.addAll(requiredRoles);
initialized = true;
}
@SuppressWarnings("unchecked")
public boolean prepareAndSendAuthRequest(Request request, Response response) throws IOException {
// Figure out the service url
String authType = request.getParameter(AUTH_TYPE);
if (authType == null || authType.length() == 0) {
authType = (String) request.getSession().getAttribute(AUTH_TYPE);
}
determineServiceUrl(authType);
String openId = openIdServiceUrl;
Session session = request.getSessionInternal(true);
if (openId != null) {
session.setNote("openid", openId);
List discoveries;
try {
discoveries = openIdConsumerManager.discover(openId);
} catch (DiscoveryException e) {
throw new RuntimeException(e);
}
DiscoveryInformation discovered = openIdConsumerManager.associate(discoveries);
session.setNote("discovery", discovered);
try {
AuthRequest authReq = openIdConsumerManager.authenticate(discovered, returnURL);
// Add in required attributes
authReq.addExtension(fetchRequest);
String url = authReq.getDestinationUrl(true);
response.sendRedirect(url);
request.getSession().setAttribute("STATE", STATES.AUTH.name());
return false;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return false;
}
@SuppressWarnings("unchecked")
public Principal processIncomingAuthResult(Request request, Response response, Realm realm) throws IOException {
Principal principal = null;
Session session = request.getSessionInternal(false);
if (session == null) {
throw new RuntimeException("wrong lifecycle: session was null");
}
// extract the parameters from the authentication response
// (which comes in as a HTTP request from the OpenID provider)
ParameterList responseParamList = new ParameterList(request.getParameterMap());
// retrieve the previously stored discovery information
DiscoveryInformation discovered = (DiscoveryInformation) session.getNote("discovery");
if (discovered == null) {
throw new RuntimeException("discovered information was null");
}
// extract the receiving URL from the HTTP request
StringBuffer receivingURL = request.getRequestURL();
String queryString = request.getQueryString();
if (queryString != null && queryString.length() > 0) {
receivingURL.append("?").append(request.getQueryString());
}
// verify the response; ConsumerManager needs to be the same
// (static) instance used to place the authentication request
VerificationResult verification;
try {
verification = openIdConsumerManager.verify(receivingURL.toString(), responseParamList, discovered);
} catch (Exception e) {
throw new RuntimeException(e);
}
// examine the verification result and extract the verified identifier
Identifier identifier = verification.getVerifiedId();
if (identifier != null) {
AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
Map> attributes = null;
if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
FetchResponse fetchResp;
try {
fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
} catch (MessageException e) {
throw new RuntimeException(e);
}
attributes = fetchResp.getAttributes();
}
OpenIdPrincipal openIDPrincipal = createPrincipal(identifier.getIdentifier(), discovered.getOPEndpoint(),
attributes);
request.getSession().setAttribute("PRINCIPAL", openIDPrincipal);
String principalName = openIDPrincipal.getName();
cachedPrincipal.set(openIDPrincipal);
if (isJBossEnv()) {
cachedRoles.set(roles);
principal = realm.authenticate(principalName, EMPTY_PASSWORD);
} else {
// Create a Tomcat Generic Principal
principal = new GenericPrincipal(realm, principalName, null, roles, openIDPrincipal);
}
if (trace) {
log.trace("Logged in as:" + principal);
}
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
return principal;
}
private OpenIdPrincipal createPrincipal(String identifier, URL openIdProvider, Map> attributes) {
return new OpenIdPrincipal(identifier, openIdProvider, attributes);
}
private boolean isJBossEnv() {
Class> clazz = SecurityActions.loadClass(getClass(), "org.jboss.as.web.WebServer");
if (clazz == null) {
clazz = SecurityActions.loadClass(getClass(), "org.jboss.system.Service");
}
if (clazz != null) {
return true;
}
return false;
}
private void determineServiceUrl(String service) {
openIdServiceUrl = Providers.GOOGLE.get();
if (StringUtil.isNotNull(service)) {
if ("google".equals(service)) {
openIdServiceUrl = Providers.GOOGLE.get();
} else if ("yahoo".equals(service)) {
openIdServiceUrl = Providers.YAHOO.get();
} else if ("myspace".equals(service)) {
openIdServiceUrl = Providers.MYSPACE.get();
} else if ("myopenid".equals(service)) {
openIdServiceUrl = Providers.MYOPENID.get();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy