Java tutorial
/* * Copyright (c) 2016, 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.saml.inbound.util; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.xerces.impl.Constants; import org.apache.xerces.util.SecurityManager; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.DefaultBootstrap; import org.opensaml.common.SAMLVersion; import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.core.Status; import org.opensaml.saml2.core.StatusCode; import org.opensaml.saml2.core.StatusMessage; import org.opensaml.saml2.core.impl.IssuerBuilder; import org.opensaml.saml2.core.impl.ResponseBuilder; import org.opensaml.saml2.core.impl.StatusBuilder; import org.opensaml.saml2.core.impl.StatusCodeBuilder; import org.opensaml.saml2.core.impl.StatusMessageBuilder; import org.opensaml.xml.ConfigurationException; import org.opensaml.xml.XMLObject; import org.opensaml.xml.io.Marshaller; import org.opensaml.xml.io.MarshallerFactory; import org.opensaml.xml.io.Unmarshaller; import org.opensaml.xml.io.UnmarshallerFactory; import org.opensaml.xml.security.x509.X509Credential; import org.opensaml.xml.signature.SignableXMLObject; import org.opensaml.xml.util.Base64; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSOutput; import org.w3c.dom.ls.LSSerializer; import org.wso2.carbon.identity.common.base.exception.IdentityException; import org.wso2.carbon.identity.saml.inbound.KeyStoreManager; import org.wso2.carbon.identity.saml.inbound.bean.SAMLConfigurations; import org.wso2.carbon.identity.saml.inbound.SAMLSSOConstants; import org.wso2.carbon.identity.saml.inbound.wrapper.SAMLResponseHandlerConfig; import org.wso2.carbon.identity.saml.inbound.builders.X509CredentialImpl; import org.wso2.carbon.identity.saml.inbound.builders.signature.DefaultSSOSigner; import org.wso2.carbon.identity.saml.inbound.builders.signature.SSOSigner; import org.wso2.carbon.identity.saml.inbound.context.SAMLMessageContext; import org.wso2.carbon.identity.saml.inbound.exception.IdentitySAML2SSOException; import org.wso2.carbon.identity.saml.inbound.validators.SAML2HTTPRedirectSignatureValidator; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; public class SAMLSSOUtil { private static int singleLogoutRetryCount = 5; private static long singleLogoutRetryInterval = 60000; // private static RealmService realmService; private static ThreadLocal tenantDomainInThreadLocal = new ThreadLocal(); private static SAML2HTTPRedirectSignatureValidator samlHTTPRedirectSignatureValidator = null; private static String sPInitSSOAuthnRequestValidatorClassName = null; private static SSOSigner ssoSigner = null; private static BundleContext bundleContext; // private static RegistryService registryService; // private static ConfigurationContextService configCtxService; private static Logger log = LoggerFactory.getLogger(SAMLSSOUtil.class); private static final String SECURITY_MANAGER_PROPERTY = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; private static final int ENTITY_EXPANSION_LIMIT = 0; private static boolean isBootStrapped = false; /** * Constructing the AuthnRequest Object from a String * * @param authReqStr Decoded AuthReq String * @return AuthnRequest Object * @throws */ public static XMLObject unmarshall(String authReqStr) throws IdentityException { InputStream inputStream = null; try { doBootstrap(); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setExpandEntityReferences(false); documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); org.apache.xerces.util.SecurityManager securityManager = new SecurityManager(); securityManager.setEntityExpansionLimit(ENTITY_EXPANSION_LIMIT); documentBuilderFactory.setAttribute(SECURITY_MANAGER_PROPERTY, securityManager); DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder(); docBuilder.setEntityResolver(new CarbonEntityResolver()); inputStream = new ByteArrayInputStream(authReqStr.trim().getBytes(StandardCharsets.UTF_8)); Document document = docBuilder.parse(inputStream); Element element = document.getDocumentElement(); UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory(); Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element); return unmarshaller.unmarshall(element); } catch (Exception e) { log.error("Error in constructing AuthRequest from the encoded String", e); throw IdentityException.error("Error in constructing AuthRequest from the encoded String ", e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.error("Error while closing the stream", e); } } } } /** * Serialize the Auth. Request * * @param xmlObject * @return serialized auth. req */ public static String marshall(XMLObject xmlObject) throws IdentityException { ByteArrayOutputStream byteArrayOutputStrm = null; try { doBootstrap(); // System.setProperty("javax.xml.parsers.DocumentBuilderFactory", // "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject); Element element = marshaller.marshall(xmlObject); byteArrayOutputStrm = new ByteArrayOutputStream(); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); LSSerializer writer = impl.createLSSerializer(); LSOutput output = impl.createLSOutput(); output.setByteStream(byteArrayOutputStrm); writer.write(element, output); return byteArrayOutputStrm.toString(StandardCharsets.UTF_8.name()); } catch (Exception e) { log.error("Error Serializing the SAML Response"); throw IdentityException.error("Error Serializing the SAML Response", e); } finally { if (byteArrayOutputStrm != null) { try { byteArrayOutputStrm.close(); } catch (IOException e) { log.error("Error while closing the stream", e); } } } } /** * Encoding the response * * @param xmlString String to be encoded * @return encoded String */ public static String encode(String xmlString) { // Encoding the message String encodedRequestMessage = Base64.encodeBytes(xmlString.getBytes(StandardCharsets.UTF_8), Base64.DONT_BREAK_LINES); return encodedRequestMessage.trim(); } /** * Decoding and deflating the encoded AuthReq * * @param encodedStr encoded AuthReq * @return decoded AuthReq */ public static String decode(String encodedStr) throws IdentityException { try { org.apache.commons.codec.binary.Base64 base64Decoder = new org.apache.commons.codec.binary.Base64(); byte[] xmlBytes = encodedStr.getBytes(StandardCharsets.UTF_8.name()); byte[] base64DecodedByteArray = base64Decoder.decode(xmlBytes); try { Inflater inflater = new Inflater(true); inflater.setInput(base64DecodedByteArray); byte[] xmlMessageBytes = new byte[5000]; int resultLength = inflater.inflate(xmlMessageBytes); if (!inflater.finished()) { throw new RuntimeException("End of the compressed data stream has NOT been reached"); } inflater.end(); String decodedString = new String(xmlMessageBytes, 0, resultLength, StandardCharsets.UTF_8.name()); if (log.isDebugEnabled()) { log.debug("Request message " + decodedString); } return decodedString; } catch (DataFormatException e) { ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64DecodedByteArray); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); InflaterInputStream iis = new InflaterInputStream(byteArrayInputStream); byte[] buf = new byte[1024]; int count = iis.read(buf); while (count != -1) { byteArrayOutputStream.write(buf, 0, count); count = iis.read(buf); } iis.close(); String decodedStr = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8); if (log.isDebugEnabled()) { log.debug("Request message " + decodedStr, e); } return decodedStr; } } catch (IOException e) { throw IdentityException.error("Error when decoding the SAML Request.", e); } } public static String decodeForPost(String encodedStr) throws IdentityException { try { org.apache.commons.codec.binary.Base64 base64Decoder = new org.apache.commons.codec.binary.Base64(); byte[] xmlBytes = encodedStr.getBytes(StandardCharsets.UTF_8.name()); byte[] base64DecodedByteArray = base64Decoder.decode(xmlBytes); String decodedString = new String(base64DecodedByteArray, StandardCharsets.UTF_8.name()); if (log.isDebugEnabled()) { log.debug("Request message " + decodedString); } return decodedString; } catch (IOException e) { throw IdentityException.error("Error when decoding the SAML Request.", e); } } public static void doBootstrap() { if (!isBootStrapped) { try { DefaultBootstrap.bootstrap(); isBootStrapped = true; } catch (ConfigurationException e) { log.error("Error in bootstrapping the OpenSAML2 library", e); } } } public static String getParameterFromQueryString(String queryString, String paraName) throws UnsupportedEncodingException { if (StringUtils.isNotBlank(queryString)) { String[] params = queryString.split("&"); if (!ArrayUtils.isEmpty(params)) { for (String param : params) { if (StringUtils.equals(param.split("=")[0], paraName)) { return URLDecoder.decode(param.split("=")[1], StandardCharsets.UTF_8.name()); } } } } return null; } public static String getNotificationEndpoint() { // String redirectURL = IdentityUtil.getProperty(IdentityConstants.ServerConfig // .NOTIFICATION_ENDPOINT); // if (StringUtils.isBlank(redirectURL)) { // redirectURL = IdentityUtil.getServerURL(SAMLSSOConstants.NOTIFICATION_ENDPOINT, false, false); // } // TODO return ""; } /** * build the error response * * @param status * @param message * @return decoded response * @throws org.wso2.carbon.identity */ public static String buildErrorResponse(String status, String message, String destination) throws IdentityException, IOException { List<String> statusCodeList = new ArrayList<String>(); statusCodeList.add(status); //Do below in the response builder Response response = buildResponse(null, statusCodeList, message, destination); String errorResp = compressResponse(SAMLSSOUtil.marshall(response)); return errorResp; } public static String buildErrorResponse(String id, List<String> statusCodes, String statusMsg, String destination) throws IdentityException { Response response = buildResponse(id, statusCodes, statusMsg, destination); return SAMLSSOUtil.encode(SAMLSSOUtil.marshall(response)); } /** * Build the error response * * @return */ public static Response buildResponse(String inResponseToID, List<String> statusCodes, String statusMsg, String destination) throws IdentityException { Response response = new ResponseBuilder().buildObject(); if (statusCodes == null || statusCodes.isEmpty()) { throw IdentityException.error("No Status Values"); } response.setIssuer(SAMLSSOUtil.getIssuer()); Status status = new StatusBuilder().buildObject(); StatusCode statusCode = null; for (String statCode : statusCodes) { statusCode = buildStatusCode(statCode, statusCode); } status.setStatusCode(statusCode); buildStatusMsg(status, statusMsg); response.setStatus(status); response.setVersion(SAMLVersion.VERSION_20); response.setID(SAMLSSOUtil.createID()); if (inResponseToID != null) { response.setInResponseTo(inResponseToID); } if (destination != null) { response.setDestination(destination); } response.setIssueInstant(new DateTime()); return response; } /** * Compresses the response String * * @param response * @return * @throws IOException */ public static String compressResponse(String response) throws IOException { Deflater deflater = new Deflater(Deflater.DEFLATED, true); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater); try { deflaterOutputStream.write(response.getBytes(StandardCharsets.UTF_8)); } finally { deflaterOutputStream.close(); } return Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES); } /** * @param tenantDomain * @return set of destination urls of resident identity provider * @throws IdentityException */ // public static List<String> getDestinationFromTenantDomain(String tenantDomain) throws IdentityException { // // List<String> destinationURLs = new ArrayList<String>(); // IdentityProvider identityProvider; // // try { // identityProvider = IdentityProviderManager.getInstance().getResidentIdP(tenantDomain); // } catch (IdentityProviderManagementException e) { // throw IdentityException.error( // "Error occurred while retrieving Resident Identity Provider information for tenant " + // tenantDomain, e); // } // // FederatedAuthenticatorConfig[] authnConfigs = identityProvider.getFederatedAuthenticatorConfigs(); // for (String value: IdentityApplicationManagementUtil.getPropertyValuesForNameStartsWith(authnConfigs, // IdentityApplicationConstants.Authenticator.SAML2SSO.NAME, IdentityApplicationConstants.Authenticator // .SAML2SSO.SSO_URL)) { // destinationURLs.add(value); // } // // if (destinationURLs.size() == 0) { // String configDestination = IdentityUtil.getProperty(IdentityConstants.ServerConfig.SSO_IDP_CLOUD_URL); // if (StringUtils.isBlank(configDestination)) { // configDestination = IdentityUtil.getServerURL(SAMLSSOConstants.IDENTITY_URL, true, true); // } // destinationURLs.add(configDestination); // } // // return destinationURLs; // } public static boolean validateACS(String tenantDomain, String issuerName, String requestedACSUrl) throws IdentityException { // TODO return true; // SSOServiceProviderConfigManager stratosIdpConfigManager = SSOServiceProviderConfigManager.getInstance(); // SAMLSSOServiceProviderDO serviceProvider = stratosIdpConfigManager.getServiceProvider(issuerName); // if (serviceProvider != null) { // return true; // } // // int tenantId; // if (StringUtils.isBlank(tenantDomain)) { // tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; // tenantId = MultitenantConstants.SUPER_TENANT_ID; // } else { // try { // tenantId = realmService.getTenantManager().getTenantId(tenantDomain); // } catch (UserStoreException e) { // throw new IdentitySAML2SSOException("Error occurred while retrieving tenant id for the domain : " + // tenantDomain, e); // } // } // // try { // PrivilegedCarbonContext.startTenantFlow(); // PrivilegedCarbonContext privilegedCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); // privilegedCarbonContext.setTenantId(tenantId); // privilegedCarbonContext.setTenantDomain(tenantDomain); // // ApplicationManagementService appInfo = ApplicationManagementService.getInstance(); // ServiceProvider application = appInfo.getServiceProviderByClientId(issuerName, SAMLSSOConstants // .SAMLFormFields.SAML_SSO, tenantDomain); // Map<String, Property> properties = new HashMap(); // for (InboundAuthenticationRequestConfig authenticationRequestConfig : application // .getInboundAuthenticationConfig().getInboundAuthenticationRequestConfigs()) { // if (StringUtils.equals(authenticationRequestConfig.getInboundAuthType(), SAMLSSOConstants // .SAMLFormFields.SAML_SSO) && StringUtils.equals(authenticationRequestConfig // .getInboundAuthKey(), issuerName)) { // for (Property property : authenticationRequestConfig.getProperties()) { // properties.put(property.getName(), property); // } // } // } // // if (StringUtils.isBlank(requestedACSUrl) || properties.get(SAMLSSOConstants.SAMLFormFields.ACS_URLS) == // null || properties.get(SAMLSSOConstants.SAMLFormFields.ACS_URLS).getValue() == null || !Arrays // .asList(properties.get(SAMLSSOConstants.SAMLFormFields.ACS_URLS).getValue().split // (SAMLSSOConstants.SAMLFormFields.ACS_SEPERATE_CHAR)).contains(requestedACSUrl)) { // String msg = "ALERT: Invalid Assertion Consumer URL value '" + requestedACSUrl + "' in the " + // "AuthnRequest message from the issuer '" + issuerName + "'. Possibly " + "an attempt for a " + // "spoofing attack"; // log.error(msg); // return false; // } else { // return true; // } // } catch (IdentityApplicationManagementException e) { // throw new IdentitySAML2SSOException("Error occurred while validating existence of SAML service provider " + // "'" + issuerName + "' in the tenant domain '" + tenantDomain + "'"); // } finally { // PrivilegedCarbonContext.endTenantFlow(); // } } public static boolean isSAMLIssuerExists(String issuerName, String tenantDomain) throws IdentitySAML2SSOException { return true; // TODO // SSOServiceProviderConfigManager stratosIdpConfigManager = SSOServiceProviderConfigManager.getInstance(); // SAMLSSOServiceProviderDO serviceProvider = stratosIdpConfigManager.getServiceProvider(issuerName); // if (serviceProvider != null) { // return true; // } // // int tenantId; // if (StringUtils.isBlank(tenantDomain)) { // tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; // tenantId = MultitenantConstants.SUPER_TENANT_ID; // } else { // try { // tenantId = realmService.getTenantManager().getTenantId(tenantDomain); // } catch (UserStoreException e) { // throw new IdentitySAML2SSOException("Error occurred while retrieving tenant id for the domain : " + // tenantDomain, e); // } // } // // try { // PrivilegedCarbonContext.startTenantFlow(); // PrivilegedCarbonContext privilegedCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); // privilegedCarbonContext.setTenantId(tenantId); // privilegedCarbonContext.setTenantDomain(tenantDomain); // // ApplicationManagementService appInfo = ApplicationManagementService.getInstance(); // ServiceProvider application = appInfo.getServiceProviderByClientId(issuerName, SAMLSSOConstants // .SAMLFormFields.SAML_SSO, tenantDomain); // if (application != null) { // for (InboundAuthenticationRequestConfig config : application.getInboundAuthenticationConfig() // .getInboundAuthenticationRequestConfigs()) { // if (StringUtils.equals(config.getInboundAuthKey(), issuerName) && StringUtils.equals(config // .getInboundAuthType(), SAMLSSOConstants.SAMLFormFields.SAML_SSO)) { // return true; // } // } // } // return false; // } catch (IdentityApplicationManagementException e) { // throw new IdentitySAML2SSOException("Error occurred while validating existence of SAML service provider " + // "'" + issuerName + "' in the tenant domain '" + tenantDomain + "'"); // } finally { // PrivilegedCarbonContext.endTenantFlow(); // } } // public static String validateTenantDomain(String tenantDomain) throws UserStoreException, IdentityException { // // if (tenantDomain != null && !tenantDomain.trim().isEmpty() && !"null".equalsIgnoreCase(tenantDomain.trim())) { // int tenantID = SAMLSSOUtil.getRealmService().getTenantManager().getTenantId(tenantDomain); // if (tenantID == -1) { // String message = "Invalid tenant domain : " + tenantDomain; // if (log.isDebugEnabled()) { // log.debug(message); // } // throw IdentityException.error(message); // } else { // return tenantDomain; // } // } // return null; // } public static BundleContext getBundleContext() { return SAMLSSOUtil.bundleContext; } public static void setBundleContext(BundleContext bundleContext) { SAMLSSOUtil.bundleContext = bundleContext; } // public static RegistryService getRegistryService() { // return registryService; // } // // public static void setRegistryService(RegistryService registryService) { // SAMLSSOUtil.registryService = registryService; // } // public static ConfigurationContextService getConfigCtxService() { // return configCtxService; // } // public static void setConfigCtxService(ConfigurationContextService configCtxService) { // SAMLSSOUtil.configCtxService = configCtxService; // } // public static HttpService getHttpService() { // return httpService; // } // public static void setHttpService(HttpService httpService) { // SAMLSSOUtil.httpService = httpService; // } // public static RealmService getRealmService() { // return realmService; // } // public static void setRealmService(RealmService realmService) { // SAMLSSOUtil.realmService = realmService; // } public static String getTenantDomainFromThreadLocal() { if (SAMLSSOUtil.tenantDomainInThreadLocal == null) { // this is the default behavior. return null; } return (String) SAMLSSOUtil.tenantDomainInThreadLocal.get(); } /** * Get the Issuer * * @return Issuer */ public static Issuer getIssuer() throws IdentityException { return getIssuerFromTenantDomain(getTenantDomainFromThreadLocal()); } public static Issuer getIssuerFromTenantDomain(String tenantDomain) throws IdentityException { Issuer issuer = new IssuerBuilder().buildObject(); String idPEntityId = SAMLConfigurations.getInstance().getIdpEntityId(); if (idPEntityId == null) { idPEntityId = "SSOService.EntityID"; } issuer.setValue(idPEntityId); issuer.setFormat(SAMLSSOConstants.NAME_ID_POLICY_ENTITY); return issuer; } public static String createID() { try { SecureRandomIdentifierGenerator generator = new SecureRandomIdentifierGenerator(); return generator.generateIdentifier(); } catch (NoSuchAlgorithmException e) { log.error("Error while building Secure Random ID", e); //TODO : throw exception and break the flow } return null; } /** * Generate the key store name from the domain name * * @param tenantDomain tenant domain name * @return key store file name */ public static String generateKSNameFromDomainName(String tenantDomain) { String ksName = tenantDomain.trim().replace(".", "-"); return ksName + ".jks"; } /** * Sign the SAML Assertion * * @param response * @param signatureAlgorithm * @param digestAlgorithm * @param cred * @return * @throws IdentityException */ public static Assertion setSignature(Assertion response, String signatureAlgorithm, String digestAlgorithm, X509Credential cred) throws IdentityException { return (Assertion) doSetSignature(response, signatureAlgorithm, digestAlgorithm, cred); } /** * Sign the SAML Response message * * @param response * @param signatureAlgorithm * @param digestAlgorithm * @param cred * @return * @throws IdentityException */ public static Response setSignature(Response response, String signatureAlgorithm, String digestAlgorithm, X509Credential cred) throws IdentityException { return (Response) doSetSignature(response, signatureAlgorithm, digestAlgorithm, cred); } /** * Generic method to sign SAML Logout Request * * @param request * @param signatureAlgorithm * @param digestAlgorithm * @param cred * @return * @throws IdentityException */ private static SignableXMLObject doSetSignature(SignableXMLObject request, String signatureAlgorithm, String digestAlgorithm, X509Credential cred) throws IdentityException { doBootstrap(); SSOSigner ssoSigner = new DefaultSSOSigner(); return ssoSigner.setSignature(request, signatureAlgorithm, digestAlgorithm, cred); } /** * Build the StatusCode for Status of Response * * @param parentStatusCode * @param childStatusCode * @return */ private static StatusCode buildStatusCode(String parentStatusCode, StatusCode childStatusCode) throws IdentityException { if (parentStatusCode == null) { throw IdentityException.error("Invalid SAML Response Status Code"); } StatusCode statusCode = new StatusCodeBuilder().buildObject(); statusCode.setValue(parentStatusCode); //Set the status Message if (childStatusCode != null) { statusCode.setStatusCode(childStatusCode); return statusCode; } else { return statusCode; } } /** * Set the StatusMessage for Status of Response * * @param statusMsg * @return */ private static Status buildStatusMsg(Status status, String statusMsg) { if (statusMsg != null) { StatusMessage statusMesssage = new StatusMessageBuilder().buildObject(); statusMesssage.setMessage(statusMsg); status.setStatusMessage(statusMesssage); } return status; } /** * Get the X509CredentialImpl object for a particular tenant * * @param tenantDomain * @param alias * @return X509CredentialImpl object containing the public certificate of * that tenant * @throws IdentitySAML2SSOException Error when creating X509CredentialImpl object */ public static X509CredentialImpl getX509CredentialImplForTenant(String tenantDomain, String alias) throws IdentitySAML2SSOException { KeyStoreManager keyStoreManager; // get an instance of the corresponding Key Store Manager instance try { keyStoreManager = KeyStoreManager.getInstance(); X509CredentialImpl credentialImpl = null; KeyStore keyStore; keyStore = keyStoreManager.getKeyStore(); java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) keyStore .getCertificate(alias); credentialImpl = new X509CredentialImpl(cert); return credentialImpl; } catch (Exception e) { throw new IdentitySAML2SSOException("Error while initializing keystore"); } } /** * Return a Array of Claims containing requested attributes and values * * @param context * @return Map with attributes and values * @throws IdentityException */ public static Map<String, String> getAttributes(SAMLMessageContext context) throws IdentityException { int index = 0; SAMLResponseHandlerConfig samlResponseHandlerConfig = context.getResponseHandlerConfig(); if (!context.isIdpInitSSO()) { if (context.getAttributeConsumingServiceIndex() == 0) { //SP has not provide a AttributeConsumingServiceIndex in the authnReqDTO if (StringUtils.isNotBlank(samlResponseHandlerConfig.getAttributeConsumingServiceIndex()) && samlResponseHandlerConfig.isEnableAttributesByDefault()) { index = Integer.parseInt(samlResponseHandlerConfig.getAttributeConsumingServiceIndex()); } else { return null; } } else { //SP has provide a AttributeConsumingServiceIndex in the authnReqDTO index = context.getAttributeConsumingServiceIndex(); } } else { if (StringUtils.isNotBlank(samlResponseHandlerConfig.getAttributeConsumingServiceIndex()) && samlResponseHandlerConfig.isEnableAttributesByDefault()) { index = Integer.parseInt(samlResponseHandlerConfig.getAttributeConsumingServiceIndex()); } else { return null; } } /* * IMPORTANT : checking if the consumer index in the request matches the * given id to the SP */ if (samlResponseHandlerConfig.getAttributeConsumingServiceIndex() == null || "".equals(samlResponseHandlerConfig.getAttributeConsumingServiceIndex()) || index != Integer.parseInt(samlResponseHandlerConfig.getAttributeConsumingServiceIndex())) { if (log.isDebugEnabled()) { log.debug("Invalid AttributeConsumingServiceIndex in AuthnRequest"); } return Collections.emptyMap(); } Map<String, String> claimsMap = new HashMap<String, String>(); // TODO // if (context.getAuthenticationResult().getSubject().getUserAttributes() != null) { // for (Map.Entry<ClaimMapping, String> entry : context.getAuthenticationResult().getSubject() // .getUserAttributes().entrySet()) { // claimsMap.put(entry.getKey().getRemoteClaim().getClaimUri(), entry.getValue()); // } // } claimsMap.put("org.wso2.test", "somevaluehere"); return claimsMap; } public static int getSingleLogoutRetryCount() { return singleLogoutRetryCount; } public static void setSingleLogoutRetryCount(int singleLogoutRetryCount) { SAMLSSOUtil.singleLogoutRetryCount = singleLogoutRetryCount; } public static long getSingleLogoutRetryInterval() { return singleLogoutRetryInterval; } public static void setSingleLogoutRetryInterval(long singleLogoutRetryInterval) { SAMLSSOUtil.singleLogoutRetryInterval = singleLogoutRetryInterval; } }