Whilst it can be simple in concept many people find configuring security for web services to be something that is very daunting. Unfortunately, and particularly for JAX-WS, there is not yet a nice simple tutorial available that explains all the steps. This isn't that tutorial yet; but I hope to be able to walk through the process providing as much information as possible so as to become a starting point. (Also refer to this weblogic document on the web logic site)
As I work developing tools for weblogic I tend to have a new install every two or three days. For this reason this blog will be from the angle of configuring web logic security from a developers point of view. I will try to annotated the process where you would likely diverge in a production environment. Any commands run in this blog are run in the context of setDomainEnv command that you can find in your domain's "bin" directory. For JDeveloper users who want to configure the integrated domain you will find this in your ~/.jdeveloper/systemXXXXXX/ DefaultDomain/bin directory.
So for the purposes of this blog we are going to consider a simple stock trading application. We are going to pick one of the predefined weblogic policies to make our life easier. My code looks something like this:
@WebService @Policy(uri = "policy:Wssp1.2-2007-Wss1.1-UsernameToken-Plain-X509-Basic256.xml") public class BrokerService { ... }
This policy has a bit of everything, user name tokens, encryption of said tokens and then signing of the whole kit and caboodle. A better match for this service in the real world would probably be to encrypt the entire message; but it wouldn't be such a good example so I am going to stick with this policy.
It is worth taking a look at the policy name as the naming convention used by web logic can tell you a lot about what is actually in the file. (For the content of the file take a look at my previous missive) "Wssp1.2-2007" tells you that the policy file contains assertions from the WS-SecurityPolicy 1.2 specification using the revised 2007 name space. "UsernameToken-Plain" tell you that the unecrypted text of the password token if passed in rather than a digest. "x509" for most cases we are talking RSA Public/Private key. Finally "Basic256" tell you which combinations of algorithm suite is being used. The last point takes us to the Wssp1.2 specification section 6.1 which has a table which explains what encryption and what key lengths are required for each suite.
One thing to look at in this document the asynchronous minimum key length, AKL, is 1024 bits this means that you cannot unfortunately make use of the DemoIdentity key store for a simple configuration; but instead need to create some new keys fortunately weblogic has some commands that make this much easier.
Before we get to this we need to take a quick diversion into the topic of trust. For this all to work the server has to be able to trust that the key combination used by the client to sign the message is a valid one. You have two choices for this, either add the client certificate to the server trust store directly or sign the client certificate with a certificate authority that is trusted by the server. The latter is more useful for distributed application as you don't have to worry about out of band key passing so we are going to use it in this example.
Luckily your weblogic instances comes with a demo CA, you can find the certificate and key for this in .../wlserver_10.3 /server/lib/CertGenCA.der and CertGenCAKey.der. This key doesn't appear to change between weblogic installations and is trusted by the default DemoTrust store. For this reason it is very very important you never have the DemoTrust store enabled in a production environment. Otherwise anybody can become trusted fairly easily; but the purposes of setting up a development environment it is really useful.
We are going to use the weblogic CertGen command that will generate keys of the correct key length and more importantly sign it with the demo CA we just mentioned. So we need a client cert/key pair to sign the outgoing message and the server certificate to encrypt the important parts. You are probably bored of me exposing now so lets actually run some commands:
java utils.CertGen -certfile ClientCert -keyfile ClientKey -keyfilepass ClientKey java utils.CertGen -certfile ServerCert -keyfile ServerKey -keyfilepass ServerKey
The server cert doesn't really need to be signed by the CA; but it is easier to use the same command to save time. Note if you were doing this for a production system you probably want to us something more industrial like openssl to generate your keys as the weblogic documentation recommends. From this you end up with a bunch of .der and .pem files which we need to import into key stores, actually it will create new one for you if they don't exist, to make them easier to use from java, again using the weblogic helper command:
java utils.ImportPrivateKey -certfile ClientCert.der -keyfile ClientKey.der -keyfilepass ClientKey -keystore ClientIdentity.jks -storepass ClientKey -alias identity -keypass ClientKey java utils.ImportPrivateKey -certfile ServerCert.der -keyfile ServerKey.der -keyfilepass ServerKey -keystore ServerIdentity.jks -storepass ServerKey -alias identity -keypass ServerKey
So now we get into the nitty gritty of configuring the server side of the equation. As mentioned before we are going to rely on the DemoTrust store so we only need to configure the server certificate and private key. Now the easiest way to do this is to make us of a script that comes with the standalone web logic install, for some reason it doesn't get installed with JDeveloper, and you can find the script in ../wlserver_10.3/samples/server/examples/src/ examples/webservices/ wss1.1/configWss.py or from the edocs site. So to configure the server we simply need to run the following command making sure you replace /.../ with the absolute path to the file in each case.
wlst /.../configWss.py weblogic weblogic localhost 7001 /.../ServerIdentity.jks ServerKey identity ServerKey
You can verify that this command has run properly by looking at the "Web Service Security" tab on your domain from the weblogic logic console. Note that the default_ww configuration is used for all web services unless you intimate otherwise. That part of the configuration is for a future blog.
So after restarting your server you can now create a client to invoke this service. The code needs to provide the client key and certificates for signing; the servers certificate so we can encrypt the message and finally something to provide the user name password tokens. For completeness here is the code I used to test this configuration:
import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.xml.ws.BindingProvider; import javax.xml.ws.WebServiceRef; import weblogic.security.SSL.TrustManager; import weblogic.wsee.security.bst.ClientBSTCredentialProvider; import weblogic.wsee.security.unt.ClientUNTCredentialProvider; import weblogic.wsee.security.util.CertUtils; import weblogic.xml.crypto.wss.WSSecurityContext; import weblogic.xml.crypto.wss.provider.CredentialProvider; // brokerServiceService = new BrokerServiceService(); BrokerService brokerService = brokerServiceService.getBrokerServicePort(); // Security stuff // // String constants to for server certificate, and client identity store String serverCertFile = ".../ServerCert.der"; String clientKeyStore = ".../ClientIdentity.jks"; String clientKeyStorePass = "ClientKey"; String clientKeyAlias = "identity"; String clientKeyPass = "ClientKey"; // Create list of credential providers List credProviders = new ArrayList(); // Create user name token provider ClientUNTCredentialProvider unt = new ClientUNTCredentialProvider("weblogic", "weblogic"); credProviders.add(unt); // Create a credential provider with the client indentity and the server side // certificate final X509Certificate serverCert = (X509Certificate)CertUtils.getCertificate(serverCertFile); serverCert.checkValidity(); CredentialProvider cp = new ClientBSTCredentialProvider(clientKeyStore, clientKeyStorePass, clientKeyAlias, clientKeyPass, "JKS", serverCert); credProviders.add(cp); // Finally add the credential providers to the request context MaprequestContext = ((BindingProvider)brokerService).getRequestContext(); requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders); // Setup the TrustManager to verify the signature on the returned message requestContext.put(WSSecurityContext.TRUST_MANAGER, new TrustManager() { public boolean certificateCallback(X509Certificate[] chain, int validateErr) { // Check that the server cert matches boolean result = chain[0].equals( serverCert); return result; } }); // Invoke the service BigDecimal bigDecimal = brokerService.getStockQuote("ORCL"); System.out.println(bigDecimal);
Now of course you need to copy the client keystore and the server certificate to the machine you are running the client from. This is okay as the client keystore with the private key is a secret only the client needs to know and the server certificate is public information.
So here is the general overview of the steps that the weblogic client will go through to send this message:
- Generate a new aes256 symmetric key, encrypt using the servers certificate. (Think RSA public key) and included in the message
- Encrypt the WS-Security UNT headers using the aes256 key and replace in message
- Include the client certificate, which the server trust as has been signed by the demo CA
- Create signature block with digest for each part of the message and the client private key. (The server can then verify this using the client certificate)
Although this is probably a bit too much detail lets look at an example message that the client could send to the server. I have tried to annotate the message so we can relate it to the configuration we have done do far.
> <?xml version = '1.0' encoding = 'UTF-8'?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis -200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1"> <ns1:EncryptedKey xmlns:ns1="http://www.w3.org/2001/04/xmlenc#" Id="u2KgDzrQ0fxzn776"> <ns1:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"> <ns2:DigestMethod xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> </ns1:EncryptionMethod> <ns3:KeyInfo xmlns:ns3="http://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="str_c8qqMexjG7qPtxHf"> <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1"> +JvAr7erivisYq6D+P8HGAj0678=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ns3:KeyInfo> <ns1:CipherData> <ns1:CipherValue>rFSQYWTxid4uY6noIglQTy3uPqzhO7/DeVT6apdp2afD5hzw7pgn2HGO eYyd06gnveW772BEoS0qQqea/kayEmik6ZO0Lme9BjsEiGMOirM8cxp1 GH8ITQEOWX7ZyrruzJq3nbJtECSUGtxsdLh1+YdybfhgXVZ50zE4mGwT jQc=</ns1:CipherValue> </ns1:CipherData> <ns1:ReferenceList> <ns1:DataReference URI="#M107teyC8vM4NGla"/> </ns1:ReferenceList> </ns1:EncryptedKey> <wsse:BinarySecurityToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0 #Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="bst_OICTd53HaizQ97WY"> MIICLTCCAdcCEIaJVGuuAUqDWjfqd+LqWc8wDQYJKoZIhvcNAQEEBQAweTELMAkGA1UEBhMCVVM xEDAOBgNVBAgTB015U3RhdGUxDzANBgNVBAcTBk15VG93bjEXMBUGA1UEChMOTXlPcmdhbml6YX Rpb24xGTAXBgNVBAsTEEZPUiBURVNUSU5HIE9OTFkxEzARBgNVBAMTCkNlcnRHZW5DQUIwHhcNM DkwMTE5MTM0NjU5WhcNMjQwMTIwMTM0NjU5WjB3MQswCQYDVQQGEwJVUzEQMA4GA1UECBYHTXlT dGF0ZTEPMA0GA1UEBxYGTXlUb3duMRcwFQYDVQQKFg5NeU9yZ2FuaXphdGlvbjEZMBcGA1UECxY QRk9SIFRFU1RJTkcgT05MWTERMA8GA1UEAxYIdWtwNzkyNjYwgZ8wDQYJKoZIhvcNAQEBBQADgY 0AMIGJAoGBAKSbrv5XD1sjEZxg8LApKmot1T5EqYTEo1J60hwev+3rXZAgjwXaoRx7Z5A2Ln35x W6CJbhymiV/INfsm93VoJWKoN8g1/cEidoXnNfO+H/6WQPcrTtRuq1X9FrmKYWOAsmkNjX7ohdw dKtWo+3twNgm+GhPrXi1U830e5PgBVX9AgMBAAEwDQYJKoZIhvcNAQEEBQADQQA/1ucLAAwUE5C efd7PRk2dPvNX+idsDL+wntiRk2tH5WIxKVKytT64G6wtwLM4q+X2XDBfBHtPkJB1JYFZMyTo </wsse:BinarySecurityToken> <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <dsig:SignedInfo> <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <dsig:Reference URI="#Timestamp_2aUNpfbuj63zIItu"> <dsig:Transforms> <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <dsig:DigestValue>FBrjakBhUyh83bJ+qXPavE0HyS4=</dsig:DigestValue> </dsig:Reference> <dsig:Reference URI="#Body_1XLlJAczORkplAwo"> <dsig:Transforms> <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <dsig:DigestValue>FXY8sR0rX7j5AoF/emb89cPI+94=</dsig:DigestValue> </dsig:Reference> <dsig:Reference URI="#unt_jGt3DAGS0A5sKDXi"> <dsig:Transforms> <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <dsig:DigestValue>ZvEVCrm9DiSQCEA2lL6TsCGCUZA=</dsig:DigestValue> </dsig:Reference> Client certificate signature <dsig:Reference URI="#bst_OICTd53HaizQ97WY"> <dsig:Transforms> <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <dsig:DigestValue>s8yt4r8aHbAJ9+MVEd1MkwDy5Dc=</dsig:DigestValue> </dsig:Reference> </dsig:SignedInfo> <dsig:KeyInfo> <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile- 1.0#X509v3" wsu:Id="str_gm2kU2SAnassqTl7"> <wsse:Reference URI="#bst_OICTd53HaizQ97WY" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile- 1.0#X509v3"/> </wsse:SecurityTokenReference> </dsig:KeyInfo> </dsig:Signature> <ns1:EncryptedData xmlns:ns1="http://www.w3.org/2001/04/xmlenc#" Encoding="UTF-8" Id="M107teyC8vM4NGla" MimeType="text/xml" Type="http://www.w3.org/2001/04/xmlenc#Element"> <ns1:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/> <ns1:CipherData> <ns1:CipherValue> oUoMOMf12IAMEgZ01UuaHY+xYlKkYeaAIrZyuN5CEafQRco1HecGmaGcjtB5q cNrRTNmrE9S18Z9K1oE6kwHKp3ZeYMp7KF/TbiqOwvKsy/+YpTQMS8gaqgbDN XlRi0gG5/CZO6yqParDs//h3xvC9L1uazotzTGJofDWXaF/O8RC0qamD6yuoH olV38na2mq28X0j44Eki4zJIkQg9q2ORj1juEE8RBt/zNuFKggThJrsmsixUj AVRHXYA0exbwqUgWGoEEvw/AK4ZQooXfBXfIOsvPn4O4e515QpXhtM6cuqUEM soGSIO/N+HT8oi4tOurXOAVCMZw6RonqBRvUPvLl2MQm3RIg4kBNFN7VIkqw4c 3jj+BbjGksKrmT3XX9jgypDDKJbW0OcOCTGYMhawQ2/wJMH/JazR55zwRLEzn8 8EIrLQ4SuGU7TN3pRNXdL3GdRxMZXF05mPT+6FLiSZ73kQLXxjlfQ9Bx4U3k2W m+Pa0nMk0vb8Vj2DV5ZOB830f9C15jCIn7cvFZmYIdXSLOl1zrBJ1zGpdmVov e1eKETKOyADGhWfE4Rt7mxPhLsUrhOlLIg4YMp+q3MIFEknoB8aBS0JPs9TSPvkQ2tk= </ns1:CipherValue> </ns1:CipherData> </ns1:EncryptedData> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp_2aUNpfbuj63zIItu"> <wsu:Created>2009-01-20T14:35:09Z</wsu:Created> <wsu:Expires>2009-01-20T14:36:09Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </S:Header> <S:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Body_1XLlJAczORkplAwo"> <ns2:getStockQuote xmlns:ns2="http://webservice.stockbroker.com/"> <ticker>ORCL</ticker> </ns2:getStockQuote> </S:Body> </S:Envelope>
I will leave the analysis of the response message from the server as an exercise for the reader at this point; but I think you get the general idea of how the different parts of the configuration to hang together to create a message.
It is worth trying, as a sanity check, using a client key that is not trusted by the server. You can easily create such a key using the keytool command
keytool -genkey -keyalg RSA -keystore UnsignedClient.jks -storepass ClientKey -alias identity -keypass ClientKey -dname "CN=Client, OU=WEB_AGE, C=UK" -keysize 1024 -validity 1460
In this case when the client is run with the new keystore the server will response with an indignant response that the certificate could be verified. The stack trace you might see will look something like this the following, this could be fixed by adding the new client certificate to the server key store we configured earlier.
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Security token failed to validate. weblogic.xml.crypto.wss.SecurityTokenValidateResult@137c90d[status: false] [msg [ [ Version: V3 Subject: CN=Client, OU=WEB_AGE, C=UK Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 Key: Sun RSA public key, 1024 bits modulus: 10367272402852596114462785541689739976823783564655877706471495047404251812... public exponent: 65537 Validity: [From: Tue Jan 20 16:18:56 GMT 2009, To: Sat Jan 19 16:18:56 GMT 2013] Issuer: CN=Client, OU=WEB_AGE, C=UK SerialNumber: [ 4975f970] ] Algorithm: [SHA1withRSA] Signature: 0000: 65 F7 E6 13 7F 47 50 20 F5 DA 01 BE 44 39 B1 5E e....GP ....D9.^ 0010: 0E A3 23 CD 39 95 BB 3E D2 CD 1E B8 A2 3E FC 74 ..#.9..>.....>.t 0020: F3 06 78 3C 2D 43 D8 26 E9 A3 2F 24 3F C2 A2 FF ..x<-C.&../$?... 0030: 10 2D E1 ED 09 34 7F E8 B8 48 04 38 DE 4E B3 D9 .-...4...H.8.N.. 0040: 37 27 F1 42 74 C1 A9 0C 61 E7 23 7F 09 A1 2F F1 7'.Bt...a.#.../. 0050: EC 0B 10 40 F8 DD C1 39 62 92 0A 62 96 D2 F8 5F ...@...9b..b..._ 0060: EF AF E3 93 C4 3E 62 D7 2F 5A 78 65 54 BD 28 4B .....>b./ZxeT.(K 0070: DF 34 55 7D 8C 10 05 5A DB 91 D8 A0 46 65 C3 16 .4U....Z....Fe.. ]] at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:190) at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:122) at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119) at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89) at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118) at $Proxy30.getStockQuote(Unknown Source) at com.stockbroker.webservice.BrokerServicePortClient.main(BrokerServicePortClient.java:107) Process exited with exit code 1.
So this blog should have shown you have to understand policy names, attach policy to a class, configure a server with the correct key stores, create a client and some understanding on how the bit relate to the structures you will find in the resultant soap message. As I say before this is not a definitive tutorial; but perhaps at least a starting point for a further investigation.
Update 11 February: If you have been using this example to try to perform two way encryption you you will find that the client will fail to decrypt the message. This is because of a mistake in my original code, it has a trust manager that only trusts the server certificate:
// Setup the TrustManager to verify the signature on the returned message requestContext.put(WSSecurityContext.TRUST_MANAGER, new TrustManager() { public boolean certificateCallback(X509Certificate[] chain, int validateErr) { // Check that the server cert matches boolean result = chain[0].equals( serverCert); return result; } });
The failure message from weblogic wasn't particularly useful so I spend a lot of time making sure that the keys in the messages lined up.
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: weblogic.xml.dom.marshal.MarshalException: weblogic.xml.crypto.wss.WSSecurityException: weblogic.xml.crypto.encrypt.api.XMLEncryptionException: Unable to resolve encryption key for weblogic.xml.crypto.encrypt.api.EncryptedType{keyInfo=null, cipherData=CipherValue: 0i8YETKYNv6PKD9nZqikDDIYpBrqrfDORnLK+nyJiY9HBaE462+v/PCG0NCbO4kqyotFGPqMExSCZ4hYOGtR4nWseqoAWD7Z64SPKfNYv0ugRhTcGIsJ8kya1eJFOzNfwRFPSaalRzLDQ8j+Rl7yiw==, id='null', mimeType='null', encoding='null', encryptionMethod=EncryptionMethod: algorithm = http://www.w3.org/2001/04/xmlenc#aes256-cbc;}
The fix for this was to replace the trust manager with one that either trusts everything, and returns true, or checks the client certificate. It is better to got for the latter.
List certificate = CertUtils.getCertificate(clientKeyStore, clientKeyStorePass, clientKeyAlias, "JKS"); final X509Certificate clientCert = (X509Certificate)certificate.get(0); ... // Setup the TrustManager to verify the signature on the returned message requestContext.put(WSSecurityContext.TRUST_MANAGER, new TrustManager() { public boolean certificateCallback(X509Certificate[] chain, int validateErr) { // Check that the server cert matches boolean result = chain[0].equals( serverCert) || chain[0].equals(clientCert); return result; } });
I did think about fixing the code in the blog and saying no more about it, but I feel that you can learn more from people's mistakes as well as they successes. Thanks for Chris Muir for working through this one with me.
19 comments:
Gerard, FYI at least in my resolution / browser, the text gets cutoff for long lines, presumably by CSS or something. I'm using FF3. It looks fine in Google Reader. That's for the post, this is helpful stuff!
Right,
Second person today to tell me about that. Chris Muir has suggested a solution, will try it later on today.
Gerard
Here is a comment for newbies. I could not run wlst as written above so instead I ran it like this after first sourcing the environment with setWLSEnv.cmd:
java weblogic.WLST configWss.py weblogic weblogic localhost 7001 ServerIdentity.jks ServerKey identity ServerKey
Gerard,
Even after applying the fix that you have suggested, I am still getting the following error.
Client log:
javax.xml.ws.soap.SOAPFaultException: weblogic.xml.crypto.encrypt.api.XMLEncryptionException: Unable to resolve encryption key for weblogic.xml.crypto.encrypt.api.EncryptedType{keyInfo=null, cipherData=CipherValue: Sz49CKJSCJDoF8Wv7LN/KhSoB3uFli/lbQm13BXAsxjbpwKNf3LLE3FW3KUpGUVx9R4T3YWnLON8T8EjPfVgcc255qt1PdADGHTls+ZFuPiewlCeJDKelqwhlXyyjq02EZmlWVIzxgdGsGSzGvIVe/j16ENtuvTr9byxjsrsJ+nVLk/5E/yXjtQMn5fLvgkb5CRutShGbHBONdUaT6O1ML/oFSqIIxevM3wdlc62Nh/jlSrEykbuxC+0eHbPN85t7Gm2N9qrqUeQWRX6DYoakdnO9t8QqePMAVycRacRdGM2gcmvMBgGHPQuMnLOn23ezwbR2OujAuWhFo0kS11bxuE8Y7xgV0GeZ9py1XvE2mW4a45I5RKbGd2evJBAUs7jLSFeB72+7k+/AZlbeZ9Y/2owcdHuLzfsyvFN/I519KwJaKyvIugDkcA9bbtCDjYaLKjg3wTlbseTntHA32dwwUBlCxG0csSp6mmw8BcY1gaB8+fOkaiKqe7II5HdI7I0n5j5GQeTbRWdoVO25o+CuXRBBYhfb6f6LEYhrllDaI4eNPSvsHt7xc4+krpgU2Na5zgqi5er3T2kSsCX6yQV3txGF0wAws7HeTDnxAxBnGM=, id='D2IlSwyBTSOV2NGY', mimeType='text/xml', encoding='UTF-8', encryptionMethod=EncryptionMethod: algorithm = http://www.w3.org/2001/04/xmlenc#aes256-cbc;}
Server Log:
Error BEA-000000 CertPathBuilder does not support building cert path from class weblogic.security.pk.X509ThumbprintSelector
java.security.InvalidAlgorithmParameterException: [Security:090596]The WebLogicCertPathProvider was passed an unsupported CertPathSelector.
at weblogic.security.providers.pk.WebLogicCertPathProviderRuntimeImpl$JDKCertPathBuilder.engineBuild(WebLogicCertPathProviderRuntimeImpl.java:682)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at com.bea.common.security.internal.legacy.service.CertPathBuilderImpl$CertPathBuilderProviderImpl.build(CertPathBuilderImpl.java:67)
at com.bea.common.security.internal.service.CertPathBuilderServiceImpl.build(CertPathBuilderServiceImpl.java:86)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Truncated. see log file for complete stacktrace
>
What could be wrong?
Sudha.
Not sure,
It might be you picked up the wrong version of configWss.py. Could you paste a link to the version you are using?
Gerard
Gerard,
I followed your blog, however once I set the system to Sign the request I get the following:
java.rmi.RemoteException: SOAPFaultException - FaultCode [{http://schemas.xmlsoap.or
g/soap/envelope/}Server] FaultString [weblogic.xml.crypto.wss.WSSecurityContext] FaultActor [null] Detail ...xmlns:bea_fau
lt="http://www.bea.com/servers/wls70/webservice/fault/1.0.0"...java.lang.ClassCastException: weblogic.xml.crypto.wss.WSSecurityContext
at weblogic.wsee.security.wssp.handlers.WssHandler.getSecurityContext(WssHandler.java:220)
at weblogic.wsee.security.wssp.handlers.WssHandler.setupSecurityContext(WssHandler.java:189)
at weblogic.wsee.security.wssp.handlers.WssHandler.getSecurityPolicyDriver(WssHandler.java:168)
at weblogic.wsee.security.wssp.handlers.WssClientHandler.processRequest(WssClientHandler.java:65)
at weblogic.wsee.security.wssp.handlers.WssHandler.handleRequest(WssHandler.java:87)
at weblogic.wsee.handler.HandlerIterator.handleRequest(HandlerIterator.java:123)
at weblogic.wsee.handler.HandlerIterator.handleRequest(HandlerIterator.java:99)
at weblogic.wsee.ws.dispatch.client.ClientDispatcher.dispatch(ClientDispatcher.java:101)
at weblogic.wsee.ws.WsStub.invoke(WsStub.java:89)
at weblogic.wsee.jaxrpc.StubImpl._invoke(StubImpl.java:331)
at com.intrado.echo.client.EchoPortType_Stub.echo(EchoPortType_Stub.java:32)
at com.intrado.echoclient.EchoClient.main(EchoClient.java:52)
.../detail>]; nested exception is:
javax.xml.rpc.soap.SOAPFaultException: weblogic.xml.crypto.wss.WSSecurityContext
I'm not sure where I'm going wrong. Does the stack trace tell you anything?
Thanks,
Kevin
Hmm,
Not sure about your exception I am afraid. Not tried it with RPC, from the stack this appear to be what you are using. Or have I gotten the wrong end of the stick.
Gerard
Hi:
I´m new to jdeveloper and weblogic, i was running your example, when i execute the client i always get the following error:
javax.xml.ws.soap.SOAPFaultException: weblogic.xml.crypto.wss.WSSecurityException: Failed to derive subject from token.javax.security.auth.login.FailedLoginException: [Security:090304]Authentication Failed: User Hernan javax.security.auth.login.LoginException: [Security:090300]Identity Assertion Failed: User Hernan does not exist
But when i create user 'Hernan' in weblogic console, execution of code is correct. do you know why it does happen?
Thanks in advance
Hi,
It is most likely because Herman is the CN you used in your client certificate.
By default weblogic maps this to a username as it is assumed the accepted cert is evidence of identity. I think you configure this under the security realm; but I don't have a wls handy to check at the moment.
Gerard
Some insight for Sudha
Hi Gerard,
i like this blog and i was able to understand the idea. But i've an issue with the user, or the certificate owner? When i test my client, i got also the [Security:090304]Authentication Failed: User HOST-NAME. This means, my "stub" connect with Servername credentials instead of given user? When i create a user in the security reams named as my hostname, it works.... strange ?
regards
Joerg
Jeorg,
This is due to a change in how the script works in later versions of JDeveloper if you look under you security realm you will see there is a x509 name mapper which takes the CN name of the certificate and enforces this as the user name.
You can either disable this manually, or create the certificate with the correct CName.
Sorry for the late reply,
Gerard
when i tried executing ur example i get the below error :
#### <[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <> <1267877868718>
After upgraded to new jdeveloper (11.1.1.3.0) the following error is reported.
With previous jdeveloper version everything worked.
Any clue?
javax.xml.ws.soap.SOAPFaultException: Message Expires time has passed
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:197)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:130)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:125)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:95)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:135)
at $Proxy33.fileUpload(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at weblogic.wsee.jaxws.spi.ClientInstance$ClientInstanceInvocationHandler.invoke(ClientInstance.java:363)
at $Proxy34.fileUpload(Unknown Source)
at aws.client.FTClient.main(FTClient.java:58)
Caused by: javax.xml.ws.soap.SOAPFaultException: Message Expires time has passed
at weblogic.wsee.jaxws.framework.jaxrpc.TubeFactory$JAXRPCTube.processRequest(TubeFactory.java:203)
at weblogic.wsee.jaxws.tubeline.FlowControlTube.processRequest(FlowControlTube.java:99)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:604)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:563)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:548)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:445)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:275)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:454)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:250)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:140)
at weblogic.wsee.jaxws.HttpServletAdapter$AuthorizedInvoke.run(HttpServletAdapter.java:319)
at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:232)
at weblogic.wsee.jaxws.JAXWSServlet.doPost(JAXWSServlet.java:310)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at weblogic.wsee.jaxws.JAXWSServlet.service(JAXWSServlet.java:87)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3594)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2202)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2108)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1432)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
gre000ga,
The only think that comes to mind is whether the clock on the client and server is not synchronized properly.
Gerard
Can I implement the policy below with Jdev 10.1.3 or Jdev 11
http://schemas.xmlsoap.org/ws/2005/07/securitypolicy
Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy
X509 witn basic128RSA15
Mahesh
service@mayoo.com
Hi, do you have an idea on how to create a ws client like yours to call the web service in weblogic from jboss/seam?
Sorry czetsuya, I only know weblogic at the moment.
Great article! Helped me a lot when securing my web services. Just one question, can you use similar approach to use weblogic configuration when it comes to web service client deployed on weblogic?
My question is can you keep configuration for ClientBSTCredentialProvider on weblogic and not in the code same as you do with ServerBSTCredentialProvider for web service provider. And if you can, how do you achieve that? Weblogic doesn't allow me to have two x509 tokens in one default config...
Post a Comment