org.openid4java.infocard.sts.OpenIDTokenGeneratorHandler Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2006-2008 Sxip Identity Corporation
*/
package org.openid4java.infocard.sts;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import org.eclipse.higgins.sts.api.*;
import org.eclipse.higgins.sts.common.Fault;
import org.eclipse.higgins.sts.utilities.XMLHelper;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.ax.FetchResponse;
import org.openid4java.server.ServerAssociationStore;
import org.openid4java.server.JdbcServerAssociationStore;
import org.openid4java.server.NonceGenerator;
import org.openid4java.server.IncrementalNonceGenerator;
import org.openid4java.association.AssociationException;
import org.openid4java.association.Association;
import org.openid4java.OpenIDException;
import org.openid4java.infocard.OpenIDTokenType;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.util.Base64;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* Handle RSTs and generate RSTRs containing OpenID Tokens.
*
* @author Johnny Bufu
*/
public class OpenIDTokenGeneratorHandler
extends org.eclipse.higgins.sts.server.token.handler.TokenHandler
{
private final org.eclipse.higgins.sts.utilities.LogHelper log =
new org.eclipse.higgins.sts.utilities.LogHelper
(OpenIDTokenGeneratorHandler.class.getName());
javax.xml.namespace.QName qnameIdentityClaimType =
new javax.xml.namespace.QName(null, "ClaimType");
javax.xml.namespace.QName qnameIdentityClaimURI =
new javax.xml.namespace.QName(null, "Uri");
private boolean bConfigured = false;
// nonce generator not actually used:
// verification will remove private assoc on first use
private NonceGenerator _nonceGenerator = new IncrementalNonceGenerator();
private ServerAssociationStore _privateAssociations;
private String _opEndpoint;
private Integer _expireIn;
/**
* Protected constructor, must use TokenGeneratorHandlerFactory
*/
protected OpenIDTokenGeneratorHandler()
{
this.log.trace("TokenGeneratorHandler::TokenGeneratorHandler");
}
/* (non-Javadoc)
* @see org.eclipse.higgins.sts.IExtension#configure(java.util.Hashtable)
*/
public void configure
(final Map mapGlobalSettings,
final String strComponentName,
final Map mapComponentSettings)
{
this.log.trace("TokenGeneratorHandler::initialize");
String tableName = (String) mapComponentSettings.get("AssocTableName");
JdbcServerAssociationStore privateAssociations =
new JdbcServerAssociationStore(tableName);
boolean status = true;
try
{
InitialContext cxt = new InitialContext();
String dataSourceJndi = (String) mapComponentSettings.get("AssocDataSource");
DataSource ds = (DataSource) cxt.lookup(dataSourceJndi);
privateAssociations.setDataSource(ds);
}
catch (NamingException e)
{
log.error("Unable to load JNDI data source from context.");
status = false;
}
_privateAssociations = privateAssociations;
java.net.URI opEndpointUri =
(java.net.URI) mapComponentSettings.get("OPEndpoint");
_opEndpoint = opEndpointUri != null ? opEndpointUri.toString() : null;
_expireIn = (Integer) mapComponentSettings.get("AssocExpiry");
this.bConfigured = status;
}
/* (non-Javadoc)
* @see org.eclipse.higgins.sts.IExtension#invoke
*/
public void invoke
(final java.util.Map mapGlobalSettings,
final String strComponentName,
final java.util.Map mapComponentSettings,
final java.util.Map mapInvocationSettings,
final IConstants constants,
final ISTSRequest request,
final ISTSResponse response)
{
this.log.trace("TokenGeneratorHandler::invoke: " + strComponentName);
if (!this.bConfigured)
{
setWstFault(constants, response, "The specified request failed",
"Issue handler not configured");
return;
}
// --- load component configuration ---
final java.net.URI uriDefaultKeyType =
(java.net.URI)mapComponentSettings.get("DefaultKeyType");
this.log.trace("DefaultKeyType: " +
uriDefaultKeyType != null ? uriDefaultKeyType.toString() : null);
final java.lang.Boolean bIncludeBearerSubjectName =
(java.lang.Boolean)mapComponentSettings.get("IncludeBearerSubjectName");
this.log.trace("IncludeBearerSubjectName: " +
bIncludeBearerSubjectName != null ?
bIncludeBearerSubjectName.toString() : null);
final java.net.URI uriTokenIssuer =
(java.net.URI)mapComponentSettings.get("TokenIssuer");
this.log.trace("TokenIssuer: " + uriTokenIssuer != null ?
uriTokenIssuer.toString() : null);
if (null == uriTokenIssuer)
{
setWstFault(constants, response, "The specified request failed",
"TokenIssuer not set.");
return;
}
final java.net.URI uriSubjectNameIdentifier =
(java.net.URI)mapComponentSettings.get("SubjectNameIdentifierAttribute");
if (null != uriSubjectNameIdentifier)
this.log.trace("SubjectNameIdentifier: " +
uriSubjectNameIdentifier != null ?
uriSubjectNameIdentifier.toString() : null);
final java.net.URI uriSubjectNameIdentifierFormat =
(java.net.URI)mapComponentSettings.get("SubjectNameIdentifierFormat");
if (null != uriSubjectNameIdentifierFormat)
this.log.trace("SubjectNameIdentifierFormat: " +
uriSubjectNameIdentifierFormat != null ?
uriSubjectNameIdentifierFormat.toString() : null);
final java.lang.Boolean bEncryptToken =
(java.lang.Boolean)mapComponentSettings.get("EncryptToken");
this.log.trace("EncryptToken: " +
bEncryptToken != null ? bEncryptToken.toString() : null);
// --- extract needed data from the RST ---
final java.util.List listRST = request.getRequestSecurityTokenCollection();
final IRequestSecurityToken RST = (IRequestSecurityToken)listRST.get(0);
final org.eclipse.higgins.sts.api.ILifetime ltLifetime = RST.getLifetime();
final java.net.URI uriTokenType = RST.getTokenType();
if (uriTokenType == null ||
(! OpenIDTokenType.OPENID20_TOKEN.toString().equals(uriTokenType.toString()) &&
! OpenIDTokenType.OPENID11_TOKEN.toString().equals(uriTokenType.toString()) ) )
{
setWstFault(constants, response, "Invalid token type",
"Cannot handle tokens of type: " + uriTokenType);
return;
}
boolean compat = OpenIDTokenType.OPENID11_TOKEN.equals(uriTokenType.toString());
// appliesTo = OpenID return_to URL
final org.eclipse.higgins.sts.api.IAppliesTo appliesToRequest = RST.getAppliesTo();
java.net.URI uriAppliesTo = null;
this.log.trace("Checking for AppliesTo");
if (appliesToRequest != null)
{
this.log.trace("Found AppliesTo");
final org.eclipse.higgins.sts.api.IEndpointReference eprAppliesTo =
appliesToRequest.getEndpointReference();
uriAppliesTo = eprAppliesTo.getAddress();
}
if (uriAppliesTo == null)
{
setWstFault(constants, response, "The specified request failed",
"AppliesTo / return_url not found; required for OpenID Tokens.");
return;
}
final org.eclipse.higgins.sts.api.IDigitalIdentity digitalIdentity =
RST.getDigitalIdentity();
if (null == digitalIdentity)
{
setWstFault(constants, response, "The specified request failed",
"Digital Subject was not found");
return;
}
// --- build response ---
final OMFactory omFactory = OMAbstractFactory.getOMFactory();
final OMNamespace omIdentityNamespace = omFactory.createOMNamespace(
constants.getIdentityNamespace().toString(),"ic");
final OMNamespace omWSTrustNamespace = omFactory.createOMNamespace(
constants.getWSTrustNamespace().toString(),"wst");
final OMElement omRequestedDisplayToken = omFactory.createOMElement(
"RequestedDisplayToken", omIdentityNamespace);
final OMElement omDisplayToken = omFactory.createOMElement(
"DisplayToken", omIdentityNamespace, omRequestedDisplayToken);
OMElement omRequestedSecurityToken = omFactory.createOMElement(
"RequestedSecurityToken", omWSTrustNamespace);
final org.apache.axiom.om.OMElement omRequestedAttachedReference =
omFactory.createOMElement("RequestedAttachedReference", omWSTrustNamespace);
final org.apache.axiom.om.OMElement omRequestedUnattachedReference =
omFactory.createOMElement("RequestedUnattachedReference", omWSTrustNamespace);
final org.apache.axiom.om.OMNamespace omWSSNamespace =
omFactory.createOMNamespace(constants.getWSSecurityNamespace().toString(), "wsse");
final org.apache.axiom.om.OMElement omSecurityTokenReference1 =
omFactory.createOMElement("SecurityTokenReference",
omWSSNamespace, omRequestedAttachedReference);
final org.apache.axiom.om.OMElement omSecurityTokenReference2 =
omFactory.createOMElement("SecurityTokenReference",
omWSSNamespace, omRequestedUnattachedReference);
final org.apache.axiom.om.OMElement omKeyIdentifier1 =
omFactory.createOMElement("KeyIdentifier",
omWSSNamespace, omSecurityTokenReference1);
final org.apache.axiom.om.OMElement omKeyIdentifier2 =
omFactory.createOMElement("KeyIdentifier",
omWSSNamespace, omSecurityTokenReference2);
String keyIdentifierValueType =
"http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1";
omKeyIdentifier1.addAttribute("ValueType", keyIdentifierValueType, null);
omKeyIdentifier2.addAttribute("ValueType", keyIdentifierValueType, null);
// --- process the claims / attribute request ---
String claimedID = null;
Map attrs = new HashMap();
final java.util.List listClaims = digitalIdentity.getClaims();
final java.util.Map mapAttributeClaim =
(java.util.Map)mapGlobalSettings.get("AttributeClaimMap");
String claimTypeUri;
String value;
String displayTag;
Iterator claimsIter = listClaims.iterator();
while (claimsIter.hasNext())
{
final IClaim claim = (IClaim) claimsIter.next();
value = claim.getValues().hasNext() ?
(String) claim.getValues().next() : null;
if (value == null) continue;
claimTypeUri = claim.getType().getName().toString();
displayTag = (String) ((Map)mapAttributeClaim.get(claimTypeUri)).get("DisplayName");
if (OpenIDTokenType.OPENID_CLAIM.equals(claimTypeUri))
{
claimedID = value;
addDisplayClaim(claimTypeUri, claimedID, displayTag,
omDisplayToken, omIdentityNamespace, omFactory);
if (compat) break;
}
else if (! compat)
{
attrs.put(claimTypeUri, value);
addDisplayClaim(claimTypeUri, value, displayTag,
omDisplayToken, omIdentityNamespace, omFactory);
}
}
if (claimedID == null)
{
setWstFault(constants, response,
"Cannot process OpenID-token RST",
"No claimed identifier found.");
return;
}
Association assoc;
try
{
assoc = _privateAssociations.generate(
org.openid4java.association.Association.TYPE_HMAC_SHA1, _expireIn.intValue());
}
catch (AssociationException e)
{
setWstFault(constants, response,
"Cannot instantiate private association store",
e.getMessage());
return;
}
if (! compat && _opEndpoint == null)
{
setWstFault(constants, response,
"Cannot process OpenID-token RST",
"OP-Endpoint not configured; required for OpenID 2 messages.");
return;
}
// nonces not used: OP invalidates private assoc handle on first use
String nonce = _nonceGenerator.next();
AuthSuccess openidResp;
try
{
openidResp = AuthSuccess.createAuthSuccess(
_opEndpoint, claimedID, claimedID,
compat, uriAppliesTo.toString(), nonce,
null, assoc, false);
if (! compat)
{
FetchResponse fetchResp = FetchResponse.createFetchResponse();
fetchResp.addAttributes(attrs);
openidResp.addExtension(fetchResp);
}
// sign the message
openidResp.setSignature(assoc.sign(openidResp.getSignedText()));
}
catch (OpenIDException e)
{
setWstFault(constants, response,
"Cannot generate OpenID assertion",
e.getMessage());
return;
}
// set the attached / unattached token reference hash
MessageDigest md;
try
{
md = MessageDigest.getInstance("SHA-1");
}
catch (NoSuchAlgorithmException e)
{
setWstFault(constants, response,
"Cannot create SHA-1 hash for Requested(Un)AttachedReference",
e.getMessage());
return;
}
String sha1base64 = null;
try
{
sha1base64 = Base64.encode(
md.digest(openidResp.keyValueFormEncoding().getBytes("utf-8")));
}
catch (UnsupportedEncodingException e)
{
setWstFault(constants, response,
"Unsupported encoding for the OpenID message",
e.getMessage());
return;
}
omKeyIdentifier1.setText(sha1base64);
omKeyIdentifier2.setText(sha1base64);
//todo: move this to OMElement OpenIDToken.getToken()?
//OpenIDToken openidToken = new OpenIDToken(openidResp);
final OMNamespace omOpenIDNamespace = omFactory.createOMNamespace(
org.openid4java.message.Message.OPENID2_NS, "openid");
OMElement omOpenIDToken = omFactory.createOMElement(
"OpenIDToken", omOpenIDNamespace, omRequestedSecurityToken);
omOpenIDToken.setText(openidResp.keyValueFormEncoding());
final java.util.List listRSTR =
response.getRequestSecurityTokenResponseCollection();
if (0 == listRSTR.size())
{
listRSTR.add(new org.eclipse.higgins.sts.common.RequestSecurityTokenResponse());
}
final org.eclipse.higgins.sts.api.IRequestSecurityTokenResponse RSTR =
(org.eclipse.higgins.sts.common.RequestSecurityTokenResponse)listRSTR.get(0);
try
{
RSTR.setTokenType(uriTokenType);
RSTR.setLifetime(ltLifetime);
RSTR.setRequestedSecurityToken(
XMLHelper.toElement(omRequestedSecurityToken));
RSTR.setRequestedDisplayToken(
XMLHelper.toElement(omRequestedDisplayToken));
RSTR.setRequestedAttachedReference
(org.eclipse.higgins.sts.utilities.XMLHelper.toElement(omRequestedAttachedReference));
RSTR.setRequestedUnattachedReference
(org.eclipse.higgins.sts.utilities.XMLHelper.toElement(omRequestedUnattachedReference));
}
catch (final Exception e)
{
org.eclipse.higgins.sts.utilities.ExceptionHelper.Log(this.log,e);
setWstFault(constants, response, "The specified request failed",
"Failed to set RequestSecurityToken elements.");
}
}
private void setWstFault(IConstants constants, ISTSResponse response,
String reason, String detail)
{
final Fault fault = new Fault(
constants.getWSTrustNamespace(),
"wst", constants.getRequestFailedFaultCode(),
reason, detail);
response.setFault(fault);
}
public void addDisplayClaim(String uri, String value, String displayTag,
OMElement omParent, OMNamespace omNs, OMFactory omFactory)
{
final OMElement elemDisplayClaim = omFactory.createOMElement(
"DisplayClaim", omNs, omParent);
elemDisplayClaim.addAttribute("Uri", uri, null);
// build and set the display tag as the part after the last "/"
final OMElement elemDisplayTag = omFactory.createOMElement(
"DisplayTag", omNs, elemDisplayClaim);
if (displayTag == null || displayTag.length() == 0)
{
int lastIndex = uri.lastIndexOf("/");
displayTag = "";
if (lastIndex > -1 && uri.length() > lastIndex)
displayTag = uri.substring(lastIndex + 1);
}
elemDisplayTag.setText(displayTag);
// set the display value
final OMElement elemDisplayValue = omFactory.createOMElement(
"DisplayValue", omNs, elemDisplayClaim);
elemDisplayValue.setText(value);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy