/*
* Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you 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.wso2.carbon.identity.provider.saml;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasData;
import org.apache.xml.security.utils.Base64;
import org.joda.time.DateTime;
import org.opensaml.DefaultBootstrap;
import org.opensaml.xml.ConfigurationException;
import org.w3c.dom.Element;
import org.wso2.carbon.identity.provider.IdentityProviderException;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.core.model.PPIDValueDO;
import org.wso2.carbon.identity.core.model.RelyingPartyDO;
import org.wso2.carbon.identity.core.persistence.IdentityPersistenceManager;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.provider.GenericIdentityProviderData;
import org.wso2.carbon.identity.provider.IdentityProviderData;
import org.wso2.carbon.identity.provider.IdentityProviderUtil;
import org.wso2.carbon.core.util.AdminServicesUtil;
public class SAMLTokenDirector {
private final static Log log = LogFactory.getLog(SAMLTokenDirector.class);
private SAMLTokenBuilder builder = null;
private RahasData rahasData = null;
private GenericIdentityProviderData ipData = null;
static {
try {
DefaultBootstrap.bootstrap();
} catch (ConfigurationException e) {
log.error("SAMLTokenDirectorBootstrapError", e);
throw new RuntimeException(e);
}
}
public SAMLTokenDirector(SAMLTokenBuilder builder, RahasData rData,
GenericIdentityProviderData iData) throws IdentityProviderException {
this.builder = builder;
this.rahasData = rData;
this.ipData = iData;
}
public Element createSAMLToken(DateTime notBefore, DateTime notAfter, String assertionId)
throws IdentityProviderException {
SignKeyDataHolder keyDataHolder = SignKeyDataHolder.getInstance();
String signatureAlgorithm = keyDataHolder.getSignatureAlgorithm();
Element elem = null;
builder.createStatement(ipData, rahasData);
builder.createSAMLAssertion(notAfter, notBefore, assertionId);
builder.setSignature(signatureAlgorithm, keyDataHolder);
builder.marshellAndSign();
elem = builder.getSAMLasDOM();
return elem;
}
/**
* Obtain the ppid for the given user for the given rp. If this is the first time user
* requesting for a token then a new PPID value will be created.
*
* @param rahasData WS-Trust information in the issue request.
* @param name Name of the user/subject.
* @param appliesToEpr EPR element in wst:AppliesTo element.
* @return PPID value. If there's already an issued token then the ppid value will be reused.
* @throws IdentityProviderException
*/
public static String getPPID(RahasData rahasData, String name, OMElement appliesToEpr)
throws IdentityProviderException {
String appliesToHostName = IdentityProviderUtil.getAppliesToHostName(rahasData);
IdentityPersistenceManager db = null;
try {
db = IdentityPersistenceManager.getPersistanceManager();
PPIDValueDO[] ppidValueDOs = db.getPPIDValuesForUser(IdentityTenantUtil.getRegistry(
null, name), name);
PPIDValueDO ppidValueDO = null;
for (int i = 0; i < ppidValueDOs.length; i++) {
String hostName = null;
if (ppidValueDOs[i].getRelyingParty() != null) {
hostName = ppidValueDOs[i].getRelyingParty().getHostName();
} else if (ppidValueDOs[i].getPersonalRelyingParty() != null) {
hostName = ppidValueDOs[i].getPersonalRelyingParty().getIdentifier()
.getHostName();
}
// hostName is not-null on both globally trusted relying parties and
// user trusted relying parties
// Check whether the host name matches
if (appliesToHostName.equals(hostName)) {
ppidValueDO = ppidValueDOs[i];
}
}
if (ppidValueDO != null) {
// If we have already issued a PPID
// Then return that value
return ppidValueDO.getPpid();
} else {
// A new request targeted for a new RP
String newPpid = Base64.encode(UUIDGenerator.getUUID().getBytes());
ppidValueDO = new PPIDValueDO();
ppidValueDO.setUserId(name);
ppidValueDO.setPpid(newPpid);
// If the host is globally trusted
RelyingPartyDO rp = db.getGloballyTrustedRelyingParty(IdentityTenantUtil
.getRegistry(null, name), appliesToHostName);
if (rp != null) {
ppidValueDO.setRelyingParty(rp);
} else {
// Else the host MUST be personally trusted
ppidValueDO.setPersonalRelyingParty(db.getUserTrustedRelyingParty(
IdentityTenantUtil.getRegistry(), name, appliesToHostName));
}
db.createPPIDValue(IdentityTenantUtil.getRegistry(null, name), ppidValueDO);
return newPpid;
}
} catch (Exception e) {
throw new IdentityProviderException(e.getMessage(), e);
}
}
}