the SAML (the xml security header you are building) maybe lacking a subject or lacking KeyInfo
or lacking namespace http://www.w3.org/2000/09/xmldsig# see below XML-Signature Syntax and Processing<http://www.w3.org/2000/09/xmldsig#> www.w3.org This document has been reviewed by W3C Members and other interested parties and has been endorsed by the Director as a W3C Recommendation. It is a stable document and ... RequestData data = new RequestData(); data.setSigCrypto(userCrypto); //only works when signature crypto ok data.setWssConfig(getWsConfig()); //only works when wsconfig is ok SAMLKeyInfo samlKeyInfo = SAMLUtil.getCredentialFromSubject( //assertion does not contain subject will cause stop assertion, data, wsDocInfo, getWsConfig().isWsiBSPCompliant() ); if (samlKeyInfo != null) { publicKey = samlKeyInfo.getPublicKey(); certs = samlKeyInfo.getCerts(); wsDocInfo.setCrypto(userCrypto); public static SAMLKeyInfo getCredentialFromSubject( org.opensaml.saml1.core.Assertion assertion, //subject inside assertion maybe null RequestData data, WSDocInfo docInfo, boolean bspCompliant samlSubject = attrStmt.getSubject() // if this causes null subject throw 'no subject' Exception if (samlSubject == null) { throw new WSSecurityException( WSSecurityException.FAILURE, "invalidSAMLToken", new Object[] {"for Signature (no Subject)"} ); } //you never get this far if subject is null //even if subject!=null look at these checks which will fubar your ability to get certificates Element sub = samlSubject.getSubjectConfirmation().getDOM(); Element keyInfoElement = WSSecurityUtil.getDirectChildElement(sub, "KeyInfo", WSConstants.SIG_NS); //u are lacking 'KeyInfo' //http://www.w3.org/2000/09/xmldsig# //if you are lacking this namespace assignment you wont get certs XML-Signature Syntax and Processing<http://www.w3.org/2000/09/xmldsig#> www.w3.org This document has been reviewed by W3C Members and other interested parties and has been endorsed by the Director as a W3C Recommendation. It is a stable document and ... if (keyInfoElement != null) { return getCredentialFromKeyInfo(keyInfoElement, data, docInfo, bspCompliant); } //then the code below would never be executed since you dont have certs public static SAMLKeyInfo getCredentialFromKeyInfo( Element keyInfoElement, RequestData data, WSDocInfo docInfo, boolean bspCompliant ) throws WSSecurityException { // // First try to find an EncryptedKey, BinarySecret or a SecurityTokenReference via DOM // Node node = keyInfoElement.getFirstChild(); while (node != null) { if (Node.ELEMENT_NODE == node.getNodeType()) { QName el = new QName(node.getNamespaceURI(), node.getLocalName()); if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)) { EncryptedKeyProcessor proc = new EncryptedKeyProcessor(); List<WSSecurityEngineResult> result = proc.handleToken((Element)node, data, docInfo, data.getSamlAlgorithmSuite()); byte[] secret = (byte[])result.get(0).get( WSSecurityEngineResult.TAG_SECRET ); return new SAMLKeyInfo(secret); } else if (el.equals(BINARY_SECRET) || el.equals(BINARY_SECRET_05_12)) { Text txt = (Text)node.getFirstChild(); return new SAMLKeyInfo(Base64.decode(txt.getData())); } else if (SecurityTokenReference.STR_QNAME.equals(el)) { STRParser strParser = new SignatureSTRParser(); strParser.parseSecurityTokenReference( (Element)node, data, docInfo, new HashMap<String, Object>() ); SAMLKeyInfo samlKeyInfo = new SAMLKeyInfo(strParser.getCertificates()); //null samlKeyInfo.setPublicKey(strParser.getPublicKey()); samlKeyInfo.setSecret(strParser.getSecretKey()); Principal principal = strParser.getPrincipal(); // Check for compliance against the defined AlgorithmSuite AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite(); if (algorithmSuite != null && principal instanceof WSDerivedKeyTokenPrincipal) { AlgorithmSuiteValidator algorithmSuiteValidator = new AlgorithmSuiteValidator(algorithmSuite); algorithmSuiteValidator.checkDerivedKeyAlgorithm( ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm() ); algorithmSuiteValidator.checkSignatureDerivedKeyLength( ((WSDerivedKeyTokenPrincipal)principal).getLength() ); } return samlKeyInfo; } } node = node.getNextSibling(); } // // Next marshal the KeyInfo DOM element into a javax KeyInfo object and get the // (public key) credential // X509Certificate[] certs = null; KeyInfoFactory keyInfoFactory = null; try { keyInfoFactory = KeyInfoFactory.getInstance("DOM", "ApacheXMLDSig"); } catch (NoSuchProviderException ex) { keyInfoFactory = KeyInfoFactory.getInstance("DOM"); } XMLStructure keyInfoStructure = new DOMStructure(keyInfoElement); try { javax.xml.crypto.dsig.keyinfo.KeyInfo keyInfo = keyInfoFactory.unmarshalKeyInfo(keyInfoStructure); List<?> list = keyInfo.getContent(); for (int i = 0; i < list.size(); i++) { XMLStructure xmlStructure = (XMLStructure) list.get(i); if (xmlStructure instanceof KeyValue) { PublicKey publicKey = ((KeyValue)xmlStructure).getPublicKey(); return new SAMLKeyInfo(publicKey); } else if (xmlStructure instanceof X509Data) { List<?> x509Data = ((X509Data)xmlStructure).getContent(); for (int j = 0; j < x509Data.size(); j++) { Object x509obj = x509Data.get(j); if (x509obj instanceof X509Certificate) { certs = new X509Certificate[1]; certs[0] = (X509Certificate)x509obj; return new SAMLKeyInfo(certs); //certs are null which causes the error you are seeing since you are new to wss4j why not use the predefined tests here are 2 you can use right away grep -S -l "certs =" *cert*.* wss4j/src/test/java/org/apache/ws/security/components/crypto/CertificateStoreTest.java wss4j/src/test/java/org/apache/ws/security/message/SignatureCertTest.java HTH Martin ______________________________________________ _____ _ _____ _ _____ ___ _ _____ _ _ _ |_ _| |_ ___ | _ |___ ___ ___| |_ ___ | __|___| _| |_ _ _ _ ___ ___ ___ | __|___ _ _ ___ _| |___| |_|_|___ ___ | | | | -_| | | . | .'| _| | -_| |__ | . | _| _| | | | .'| _| -_| | __| . | | | | . | .'| _| | . | | |_| |_|_|___| |__|__| _|__,|___|_|_|___| |_____|___|_| |_| |_____|__,|_| |___| |__| |___|___|_|_|___|__,|_| |_|___|_|_| |_| ________________________________ From: Lapin Blanc <[email protected]> Sent: Sunday, February 18, 2018 9:18 AM To: [email protected] Subject: Set WSS basic authentication on org.apache.axis.client.Stub Hi, I've created a SOAP client stub using Eclipse WST on a wsdl file from a service provider I have to use. To access this service I need to authenticate, with a really basic clear text username/password. The stub I'm trying to use inherit from org.apache.axis.client.Stub. I first tried the "regular" way, by setting username and password properties on the stub before my action is invoked. Nevertheless, the system refused my credential, complaining about the absence of any token : {}description:L'authentification a échoué : aucune information de sécurité reçue (WSS X509 ou WSS UsernameToken) {}description:Authentication failed : no proven X509 certificate or username token found Then I analyzed what SoapUI generated like XML request and saw that it actually adds WSS headers to the request : <con:wssContainer> <con:outgoing> <con:name>etnic</con:name> <con:entry type="Username" password="changeMe" username="[email protected]<mailto:[email protected]>"> <con:configuration> <addCreated>false</addCreated> <addNonce>false</addNonce> <passwordType>PasswordText</passwordType> </con:configuration> </con:entry> </con:outgoing> </con:wssContainer> This way, no problem, I got the correct answer. But I can't really figure out how to do this programmatically into my project without having to dig deep into the XML headers etc. I tried to understand the doc at several places (especially https://ws.apache.org/wss4 ), but it's overwhelming, I'm wondering if there is a simple approach... Any help is very, very welcome... :-)
