Configuring Security
The following sections describe how to configure security for WebLogic Web Services:
- Overview of Web Services Security
- What Type of Security Should You Configure?
- Configuring Message-Level Security (Digital Signatures and Encryption)
- Configuring Transport-Level Security (SSL): Main Steps
- Configuring SSL for a Client Application
- Configuring Access Control Security: Main Steps
- Testing a Secure WebLogic Web Service From Its Home Page
Overview of Web Services Security
To secure your WebLogic Web Service, you configure one or more of three conceptually different types of security:
- Message-level security, in which data in a SOAP message is digitally signed or encrypted.
See Configuring Message-Level Security (Digital Signatures and Encryption).
- Transport-level security, in which SSL is used to secure the connection between a client application and the Web Service.
- Access control security, which specifies which users, groups, and roles are allowed to access Web Services.
What Type of Security Should You Configure?
Access control security answers the question "who can do what?" First you specify the list of users, groups, or roles that are allowed to access a Web Service (or the component that implement the Web Service). Then, when a client application attempts to invoke a Web Service operation, the client authenticates itself to WebLogic Server, using HTTP, and if the client has the authorization, it is allowed to continue with the invocation. Access control security secures only WebLogic Server resources. This means that if you configure only access control security, the connection between the client application and WebLogic Server is not secure and the SOAP message is in plain text.
With transport-level security, you secure the connection between the client application and WebLogic Server with Secure Sockets Layer (SSL). SSL provides secure connections by allowing two applications connecting over a network to authenticate the other's identity and by encrypting the data exchanged between the applications. Authentication allows a server, and optionally a client, to verify the identity of the application on the other end of a network connection. Encryption makes data transmitted over the network intelligible only to the intended recipient.
Transport-level security, however, secures only the connection itself. This means that if there is an intermediary between the client and WebLogic Server, such as a router or message queue, the intermediary gets the SOAP message in plain text. When the intermediary sends the message to a second receiver, the second receiver does not know who the original sender was. Additionally, the encryption used by SSL is "all or nothing": either the entire SOAP message is encrypted or it is not encrypted at all. There is no way to specify that only selected parts of the SOAP message be encrypted.
Message-level security includes all the security benefits of SSL, but with additional flexibility and features. Message-level security is end-to-end, which means that a SOAP message is secure even when the transmission involves one or more intermediaries. The SOAP message itself is digitally signed and encrypted, rather than just the connection. And finally, you can specify that only parts of the message be signed or encrypted.
Configuring Message-Level Security (Digital Signatures and Encryption)
Message-level security specifies whether the SOAP messages between a client application and the Web Service it is invoking should be digitally signed or encrypted.
WebLogic Web Services implements the Web Services Security Core specification (WS-Security). This specification provides three main mechanisms: security token propagation, message integrity, and message confidentiality. These mechanisms can be used independently (such as passing a username security token for user authentication) or together (such as digitally signing and encrypting a SOAP message.)
Warning: BEA's implementation of the Web Services Security Core Specification is based on Working Draft Version 1.0, dated April 5, 2002. Because this specification is not yet an OASIS Standard, BEA's current implementation is subject to change in future versions of WebLogic Server. Customers using the message-level security features described in this section should do so with the understanding that this implementation may not be compatible with Web Services Security implementations based on other versions of the Core Specification.
The following sections provide information about message-level security:
- Main Use Cases
- Unimplemented Features of the Web Services Security Core Specification
- Terminology
- Architectural Overview of Message-Level Security
- Configuring Message-Level Security: Main Steps
Main Use Cases
BEA's implemenation of the Web Services Security Core specification is designed to fully support the following use cases:
- Use an X.509 certificate to encrypt and sign a SOAP message, starting from the client application that invokes the message-secured Web Service, to the WebLogic Server instance that is hosting the Web Service and back to the client application. The SOAP message itself contains all the security information, so intermediaries between the client application and Web Service can also play a part without compromising any security of the message.
- Provide flexibility over what parts of the SOAP message are signed and encrypted. By default, when you enable WebLogic Web Service message-level security, the entire SOAP message body is encrypted and signed. You can, however, specify that all occurrences of a specific element in the SOAP message be signed, encrypted, or both.
- Include an encrypted and signed username and password in the SOAP message (rather than in the HTTP header, as is true for SSL and access control security) for further downstream processing.
Unimplemented Features of the Web Services Security Core Specification
WebLogic Web Services do not implement all features of the Web Services Security Core specification as follows:
- The specification allows for any type of security token to be passed in the SOAP message. WebLogic Web Services, however, supports only two types of tokens:
- UsernameToken
- BinarySecurityToken
Additionally, the only supported value for the ValueType attribute of the BinarySecurityToken element is wsse:X509v3.
WebLogic Web Services do not support (among others) custom, SAML, Kerberos, and XrML tokens.
- WebLogic Web Services do not support PKI certificate chains.
- WebLogic Web Services validate certificates through the default Identity Asserter via mapping to a user. If you require addtional validation, implement your own Identity Asserter.
- WebLogic Web Services do not support the XML Decryption Transformation algorithm when signing a SOAP message. WebLogic Web Services support only the Exclusive XML Canonicalization algorithm.
- A message-secured WebLogic Web Service first signs and then encrypts the out-going SOAP response. You cannot change this order.
When a WebLogic Web Service receives a SOAP request, it signs and encrypts the message in the reverse order that the message was originally signed and encrypted.
- WebLogic Web Services do not support secret key encryption; they support only public key encryption.
Terminology
Note the following terms:
- key pair: pair of public and private keys.
- digital certificate: binding of key pairs to an identity, such as a username.
- keystore: file that stores key pairs and digital certificates securely.
Architectural Overview of Message-Level Security
The <security> element of the web-services.xml deployment descriptor file specifies whether a WebLogic Web Service has been configured for message-level security. In particular, the <security> element describes:
- For a particular message-secured operation, what parts of the SOAP request and response should be encrypted or digitally signed.
- The encryption and signature key pairs that WebLogic Server uses from its identity keystore to sign, verify, encrypt, and decrypt the SOAP messages.
- Which operations have been configured for message-level security.
When the Web Service is deployed, the security information specified in the web-services.xml file is published in the WSDL so that client applications that invoke the Web Service know whether they need to digitally sign or encrypt the SOAP messages.
Note: Because WSDL 1.1 does not include a standard for specifying security information, the way that WebLogic Server publishes its message-level security information is proprietary.
The following diagram and paragraphs describe what happens when a message-secured WebLogic Web Service is deployed and a client application invokes it. The paragraphs are broken up according to the actor that performs the action.
Figure 13-1 Message-Secured WebLogic Web Service Architecture
A. WebLogic Server
- Loads the key pairs and certificates from WebLogic Server's identity keystore.
- Deploys the message-secured Web Service, using information from the web-services.xml deployment descriptor, such as which operations require what type of message-level security.
- Updates the WSDL of the Web service with security information so that client applications that invoke the Web Service know what security processing needs to occur on the SOAP request. This security information includes the certificate for WebLogic Server's encryption key pair, used by the client application to encrypt the SOAP request. WebLogic Server uses the information in the <security> element of the web-services.xml deployment descriptor file to determine how it should update the WSDL.
B. Client Application
The client application loads the signature key pair and certificate from its client keystore and uses the weblogic.webservice.context.WebServiceContext API to add the public key and certificate as attributes to the Web Service session. Note that the client application uses the key pair and certificate loaded from its client keystore to digitally sign the SOAP request. WebLogic Server later uses the key pair and certificate to encrypt the SOAP response.
C. WebLogic Web Services Client Runtime Environment
When the client application is executed, the Web Services client runtime environment, packaged in the client runtime JAR files, performs the following tasks: Note that the client runtime performs all encryption and signature tasks directly before it sends the request to WebLogic Server and after all client handlers have executed.
- Reads the WSDL of the Web Service being invoked to determine what parts of the SOAP request should be digitally signed or encrypted. The client runtime also gets the certificate for the server encryption key from the WSDL.
- Generates the unsecured SOAP message request.
- Creates a <Security> element in the header of the SOAP request that will contain the security information.
- If required by the WSDL, inserts a username token with the client's username and password into the <Security> header of the SOAP request.
- If the WSDL requires that the SOAP request be digitally signed, the Web Services client runtime environment:
- Generates a digital signature, according to the WSDL requirements, using the private key from the client's WebServiceContext.
- Adds the digital signature to the <Security> header of the SOAP request.
- Adds the certificate from the client's WebServiceContext to the <Security> header of the SOAP request. WebLogic Server later uses this certificate to verify the signature.
- If the WSDL requires that the SOAP request be encrypted, the Web Services client runtime environment:
- Gets WebLogic Server's public encryption key from the certificate published in the WSDL.
- Encrypts the SOAP request according to the requirements in the WSDL using WebLogic Server's public encryption key. The WSDL specifies what part of the SOAP message should be encrypted.
- Adds a description of the encryption to the <Security> header of the SOAP request. WebLogic Server later uses this description to decrypt the SOAP request.
- The Web Services client runtime sends the encrypted and signed SOAP request to WebLogic Server.
D. WebLogic Server
- Receives the SOAP request and extracts the <Security> header.
- If the SOAP request has been encrypted, WebLogic Server:
- Reads the description of the encryption and decrypts the SOAP request using WebLogic Server's private encryption key from its identity keystore.
- Removes the encryption description from the <Security> header.
- If the SOAP request has been digitally signed, WebLogic Server performs the following tasks to verify the signature:
- Extracts the client's certificate from the <Security> header of the SOAP request.
- Extracts the digital signature from the <Security> header.
- Verifies the signature using the client's public key, obtained from the client's certificate.
- Asserts the identity of the client certificate to ensure that it maps to a valid WebLogic Server user.
- Removes the signature from the <Security> header.
- Extracts, if present, the username token from the <Security> header.
- Asserts the identity of the user and verifies their password. The rest of the invocation of the Web Service operation is run as this user.
- Removes the <Security> header from the SOAP request.
- Saves the client certificate that was included in the SOAP request for encrypting the SOAP response, if required.
- Verifies that the specifications in the <Security> header matched the requirements in the WSDL.
- Sends the post-processed SOAP request to the Web Services runtime for standard invocation.
Similar steps happen in reverse if WebLogic Server is required to digitally sign or encrypt the SOAP response, with the following differences:
- WebLogic Server uses the public key from the saved client certificate to encrypt the SOAP response. The client application in turn uses the private key from its WebServiceContext (originally loaded from the client keystore) to decrypt the response.
- WebLogic Server uses the signature key pair and certificate from its identity keystore to digitally sign the SOAP response. WebLogic Server includes this certificate in the response so that the client application can verify the signature.
- WebLogic Server includes a username token in the SOAP response only if explicitly specified in the web-services.xml deployment descriptor file. Typically this is not needed because the client application does not need to assert the identity.
Configuring Message-Level Security: Main Steps
Configuring message-level security for a WebLogic Web Service involves some standard security tasks, such as obtaining digital certificates, creating keystores, and users, as well as Web Service-specific tasks, such as updating the web-services.xml file with security information.
To configure message-level security for a WebLogic Web Service and a client that invokes the service, follow these steps. Later sections describe some steps in more detail. Note that the following procedure assumes that you have already implemented and assembled a WebLogic Web Service and you want to update it to use digital signatures and encryption.
- Obtain two sets of key pair and digital certificates to be used by WebLogic Web Services. Although not required, BEA recommends that you obtain key pairs and certificates that will be used only by WebLogic Web Services.
Warning: BEA requires that the key length be 1024 bits or larger.
For clarity, it is assumed that the key pair/certificate used for digital signatures has a name digSigKey and password digSigKeyPassword and the one used for encryption has a name encryptKey and password encryptKeyPassword.
You can use the Cert Gen utility or Sun Microsystem's keytool utility to perform this step. For development purposes, the keytool utility is the easiest way to get started.
For details, see Obtaining Private Keys and Digital Signatures.
- Create, if one does not currently exist, a custom identity keystore for WebLogic Server and load the key pairs and digital certificates you obtained in the preceding step into the identity keystore.
If you have already configured WebLogic Server for SSL, then you have already created a identity keystore which you can also use for WebLogic Web Services data security purposes.
You can use WebLogic's ImportPrivateKey utility and Sun Microsystem's keytool utility to perform this step. For development purposes, the keytool utility is the easiest way to get started.
For details, see Creating a Keystore and Loading Key Pairs Into the Keystore
- Using the Administration Console, configure WebLogic Server to locate the keystore you created in the preceding step. If you are using a keystore that has already been configured for WebLogic Server, you do not need to perform this step.
For details, see Configuring Keystores.
- Create a keystore used by the client application. BEA recommends that you create one client keystore per application user.
You can use the Cert Gen utility or Sun Microsystem's keytool utility to perform this step. For development purposes, the keytool utility is the easiest way to get started.
Later sections of this document assume you created a client keystore called client_keystore with password client_keystore_password.
For details, see Obtaining Private Keys and Digital Signatures.
- Create a key pair and a digital certificate, and load them into the client keystore. The same key pair will be used to digitally sign the SOAP request and encrypt the SOAP responses. The digital certificate will be mapped to a user of WebLogic Server, created in a later step.
Warning: BEA requires that the key length be 1024 bits or larger.
You can use Sun Microsystem's keytool utility to perform this step.
Later sections of this document assume you created a key pair called client_key with password client_key_password.
- Using the Administration Console, configure an Identity Asserter provider for your WebLogic Server security realm.
WebLogic Server provides a default security realm, called myrealm, which is configured with a default Identity Asserter provider. Use this default security realm if you do not want to configure your own Identity Asserter provider. You must, however, perform additional configuration tasks to ensure that the default Identity Asserter Provider works correctly with message-secured WebLogic Web Services.
For details, see Configuring The Identity Asserter Provider for the myrealm Security Realm.
- Using the Administration Console, create users for authentication in your security realm.
For details, see Creating Users.
Later sections of this guide assume you created a user auth_user with password auth_user_password.
- Update the build.xml file that contains the call to the servicegen Ant task by adding the <security> child element to the <service> element that builds your Web Service. Specify information such as the encryption key pair, the digital signature key pair, and their corresponding passwords. Note that the servicegen Ant task offers only course-grained control of the encryption and digital signature configuration for a Web Service. For more fine-grained control of the data in the SOAP message that is encrypted or digitally signed, update the web-services.xml file manually. For details, see Updating Security Information in the web-services.xml File.
For details about using servicegen, see Updating the servicegen build.xml File.
- Re-run the servicegen Ant task to re-assemble your Web Service and regenerate the web-services.xml deployment descriptor.
- Optionally encrypt the various passwords in the web-services.xml file of the EAR for your domain before deploying the EAR file to WebLogic Server. Typically you perform this step only when you deploy your Web Service in production mode.
For details, see Encrypting Passwords in the web-services.xml File.
- Update your client application to invoke the message-secured Web Service.
For details, see Updating a Java Client to Invoke a Data-Secured Web Service.
Configuring The Identity Asserter Provider for the myrealm Security Realm
You can use the default Identity Asserter provider, configured for the default myrealm security realm, with message-secured WebLogic Web Services. You must, however, perform some additional configuration tasks:
- In the left pane of the Administration Console, expand the Security
- > Realms- > myrealm- > Providers- > Authentication folder.- Click DefaultIdentityAsserter under the Authentication folder. The page to configure the default Identity Asserter appears in the right pane, open to the General tab.
- In the right pane, scroll down to the Types box.
- Move X.509 from the Available box to the Chosen box.
- Click Apply.
- Select the Details tab.
- Ensure that Use Default User Name Mapper is checked.
- Select the Default User Name Mapper Attribute Type used when mapping the X.509 digital certificate to a user name.
- Select the Default User Name Mapper Attribute Delimiter.
- Click Apply.
For additional information about configuring the Identity Asserter, see:
Updating the servicegen build.xml File
Update the build.xml file that contains the call to the servicegen Ant task by adding a <security> child element to the <service> element that builds your Web Service, as shown in the following example. By default, servicegen specifies that the entire SOAP body will be digitally signed or encrypted, rather than specific elements. Later sections describe how to digitally sign or encrypt specific elements.
Note: For clarity, the following excerpt of servicegen's build.xml file contains passwords in clear text. However, for security reasons, BEA recommends that you update your build.xml file to prompt for the passwords, using the <input> Ant task, rather than actually store the passwords in the file. For details on using the <input> Ant task, see Apache Ant User Manual.
<servicegen destEar="ears/myWebService.ear" warName="myWAR.war" contextURI="web_services" > <service ejbJar="jars/myEJB.jar" targetNamespace="http://www.bea.com/examples/Trader" serviceName="TraderService" serviceURI="/TraderService" generateTypes="True" expandMethods="True" > <security signKeyName="digSigKey"
signKeyPass="digSigKeyPassword" encryptKeyName="encryptKey" encryptKeyPass="encryptKeyPassword" />
</service> </servicegen>The preceding build.xml file specifies that servicegen assemble a Web Service that includes the following message-level security information in the web-services.xml deployment descriptor file:
- The signKeyName and signKeyPass attributes specify that the body of the SOAP request and response must be digitally signed. WebLogic Server uses the key pair and certificate, accessed using the name digSigKey and password digSigKeyPassword, from its keystore to digitally sign the SOAP response. The key pair and certificate are those that you added in step 1 of Configuring Message-Level Security: Main Steps.
- The encryptKeyName and encryptKeyPass attributes specify that the body of the SOAP request and response must be encrypted. WebLogic Server uses the key pair and certificate, accessed using the name encryptKey and password encryptKeyPassword, from its keystore to encrypt and decrypt the SOAP request. The key pair and certificate are those that you added in step 1 of Configuring Message-Level Security: Main Steps.
Note: Always encrypt the passwords in the web-services.xml file with the weblogic.webservice.encryptpass utility, described in Encrypting Passwords in the web-services.xml File.
If you use the <security> element of the servicegen Ant task to add security to your Web Service, the entire SOAP body is encrypted and digitally signed for all operations of the Web Service. The encryption and digital signatures occur for both the request and response SOAP messages.
If you want more fine-grained control, such as specifying particular elements of the SOAP message to be digitally signed or encrypted, a subset of operations that have message-level security, and so on, update the web-services.xml file of your WebLogic Web Service manually. For details, see Updating Security Information in the web-services.xml File.
Updating Security Information in the web-services.xml File
The servicegen Ant task adds minimal default message-level security information to the generated web-services.xml deployment descriptor file. In particular, the default information specifies that, for all operations of the Web Service, the entire body of the SOAP messages be digitally signed or encrypted, rather than specific elements. This default behavior is adequate in many cases; however, you might sometimes want to specify just a subset of the elements to be digitally signed or encrypted, as well as specify different security specifications for different operations. In this case, update the web-services.xml file manually.
If you use the build.xml file in Updating the servicegen build.xml File to run servicegen, the following example shows the resulting <security> element in the generated web-services.xml file; the sections in bold are described after the example:
<web-service>
... <security><signatureKey> <name>digSigKey</name> <password>digSigKeyPassword</password>
</signatureKey><encryptionKey> <name>encryptKey</name> <password>encryptKeyPassword</password>
</encryptionKey><spec:SecuritySpec xmlns:spec="http://www.openuri.org/2002/11/wsse/spec" Namespace="http://schemas.xmlsoap.org/ws/2002/07/secext" Id="default-spec"><spec:BinarySecurityTokenSpec xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext" EncodingType="wsse:Base64Binary" ValueType="wsse:X509v3"> </spec:BinarySecurityTokenSpec><spec:SignatureSpec SignatureMethod="http://www.w3.org/2000/09/xmldsig#rsa-sha1" SignBody="true"
CanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"> </spec:SignatureSpec><spec:EncryptionSpec EncryptBody="true"
EncryptionMethod="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"> </spec:EncryptionSpec></spec:SecuritySpec></security>...<operations> <operation name="myOperation" method="myMethod" component="ejbComp" in-security-spec="default-spec" out-security-spec="default-spec"> ... </operation> </operations>...</web-service>Note that the spec prefix in the preceding example is a namespace prefix that is required for the security information in the web-services.xml deployment descriptor file. For more information about XML namespaces, see Namespaces in XML.
The <signatureKey> and <encryptKey> elements in the preceding web-services.xml excerpt specify the username and passwords used to retrieve the keys for digital signatures and encryption, respectively, from the server's keystore.
The Id="default-spec" attribute of the <spec:SecuritySpec> element specifies that it is the default security specification. By default, the SOAP requests and responses for invokes of all operations of the Web Service must follow the security information described by this security specification; this is specified with the in-security-spec="default-spec" and out-security-spec="default-spec" attributes of each <operation> element.
The SignBody="true" and EncryptBody="true" attributes of the <spec:SignatureSpec> and <spec:EncryptionSpec> elements specify that the entire body of the SOAP messages for all operations must be digitally signed and encrypted.
The following sections describe how to update the web-services.xml file to specify more fine-grained message-level security:
- Digitally Signing or Encrypting a Particular Element in the SOAP Message
- Associating an Operation with a Particular Security Specification
- Using Timestamps
Digitally Signing or Encrypting a Particular Element in the SOAP Message
To specify particular elements to be digitally signed or encrypted, add one or more <spec:ElementIdentifier> child elements to the <spec:SignatureSpec> or <spec:EncryptionSpec> element, respectively, in the web-services.xml file.
For example, assume that, in addition to the entire SOAP body, you want to digitally sign an element in the SOAP header whose local name is Timestamp. To specify this configuration, add a <spec:ElementIdentifier> child element to the <spec:SignatureSpec> element as shown:
<spec:SignatureSpec SignatureMethod="http://www.w3.org/2000/09/xmldsig#rsa-sha1" SignBody="true" CanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"><spec:ElementIdentifier LocalPart="Timestamp" Namespace="http://www.bea.com/examples/security" />
</spec:SignatureSpec>The example shows how to identify that the Timestamp element of the SOAP message be digitally signed by using the LocalPart and Namespace attributes of the <spec:ElementIdentifier> element. Set the LocalPart attribute equal to the name of the element in the SOAP message you want to encrypt and the Namespace attribute to its namespace. To get the exact name and namespace of the element, you can:
- Look at the WSDL of the Web Service. To get the WSDL of a WebLogic Web Service, use the wsdlgen Ant task on the existing non-secure Web Service. For details, see wsdlgen.
- View the actual SOAP messages generated from an invoke of the operation when deployed as a non-secure Web Service. For details, see Using the Web Service Home Page to Test Your Web Service.
Specifying a particular element to be encrypted is very similar. For example, to encrypt just the element CreditCardNumber, wherever it appears in the SOAP message (rather than the entire SOAP body), update the <spec:EncryptionSpec> element as shown:
<spec:EncryptionSpec EncryptionMethod="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" ><spec:ElementIdentifier LocalPart="CreditCardNumber" Namespace="http://www.bea.com/examples/security" />
</spec:EncryptionSpec>For details about the <security> element, and all its child elements discussed in this section, see WebLogic Web Service Deployment Descriptor Elements.
Associating an Operation with a Particular Security Specification
The <security> element of the web-services.xml deployment descriptor file can contain zero or more <spec:SecuritySpec> elements. These elements specify the security requirements for a particular SOAP message: what should be signed, what should be encrypted, what tokens should be included, and so on.
Each <spec:SecuritySpec> element typically has an Id attribute that uniquely identifies it. In the <operations> section of the web-services.xml file, each <operation> element can reference a specific security specification by setting the operation's in-security-spec or out-security-spec attribute to the relevant Id value. The security specification referenced by the in-security-spec attribute is applied to SOAP requests; the security specification referenced by the out-security-spec attribute is applied to SOAP responses.
If a <spec:SecuritySpec> element contains no Id attribute, or it is assigned the value default-spec, the security specification is treated as the default specification and is applied to all operations that do not explicitly reference a specification. Only one default specification can be defined: if more than one is defined in the web-services.xml file, the Web Service will not deploy.
The servicegen Ant task always generates a default security specification in the generated web-services.xml file (with an Id="default-spec" attribute) and this security specification is applied to all SOAP messages for all operations. The individual <operation> elements do not contain any direct reference to this security specification, since none is needed.
For example, assume you have defined the following two security specifications for a Web Service:
<web-service>
... <security> ... <spec:SecuritySpec xmlns:spec="http://www.openuri.org/2002/11/wsse/spec" Namespace="http://schemas.xmlsoap.org/ws/2002/07/secext" Id="encrypt-only"> <spec:EncryptionSpec ... </spec:EncryptionSpec> </spec:SecuritySpec><spec:SecuritySpec xmlns:spec="http://www.openuri.org/2002/11/wsse/spec" Namespace="http://schemas.xmlsoap.org/ws/2002/07/secext" Id="sign-only"> <spec:SignatureSpec ... </spec:SignatureSpec> </security> ...
</web-service>In the example, the encrypt-only security specification requires only encryption and the sign-only security specification requires only digital signatures. You can mix and match these security specifications for particular operations by using the in-security-spec and out-security-spec attributes of the relevant <operation> element, as shown in the following example:
<operations> <operation name="operationOne" method="methodOne" component="ejbComp" in-security-spec="encrypt-only" out-security-spec="encrypt-only"> ... </operation> <operation name="operationTwo" method="methodTwo" component="ejbComp" in-security-spec="sign-only"> ... </operation>
</operations>The preceding excerpt shows that both the SOAP request and response of the operationOne operation must be encrypted, but not digitally signed. The SOAP request for operationTwo must be digitally signed (although not encrypted), but the SOAP response requires no security at all.
For details about the <security> and <operation> elements, see WebLogic Web Service Deployment Descriptor Elements.
Using Timestamps
When a client application invokes a WebLogic Web Service that has been configured for message-level security, WebLogic Server may also require and add timestamp information in the SOAP request and response. By default, WebLogic Server:
- Requires that digitally signed SOAP requests include a timestamp and rejects any that do not. The timestamp itself must be digitally signed.
- Assumes that its clock and the client application's clock are not synchronized. This means that if the SOAP request from a client application includes a timestamp with an expiration, WebLogic Server rejects the message. This is because WebLogic Server is unable to ensure that the message has not already expired.
- Adds a timestamp to the SOAP response. The timestamp contains only the creation date of the SOAP response; it does not contain an expiration date.
You can change the default timestamp behavior of your WebLogic Web Service by adding a <timestamp> child element to the <security> element in the web-services.xml deployment descriptor.
The following web-services.xml excerpt shows an example of configuring timestamp behavior:
<web-service>
... <security> <timestamp> <clocks-synchronized>true</clocks-synchronized> <clock-precision>30000</clock-precision> <require-signature-timestamp>false</require-signature-timestamp> <generate-signature-timestamp>true</generate-signature-timestamp> <inbound-expiry>120000</inbound-expiry> <outbound-expiry>30000</outbound-expiry> </timestamp>
... </security> ...
</web-service>The preceding <timestamp> element specifies the following timestamp behavior when the relevant Web Service operation is invoked:
- WebLogic Server's and the client application's clocks are synchronized, and are accurate within 30000 milliseconds (30 seconds) of each other. This implies that if WebLogic Server receives a digitally signed SOAP request whose expiration period is less than 30 seconds, WebLogic Server automatically rejects the request because it cannot accurately determine if the message has expired.
- WebLogic Server does not require that digitally signed SOAP requests include a timestamp, although it always includes a timestamp in its digitally signed SOAP responses.
- WebLogic Server has its own expiration period for digitally signed SOAP requests of 120000 milliseconds (2 minutes). This means that, independent of any client-specified expiration, WebLogic Server rejects the request if it receives it more than 2 minutes after it was created (adjusting for clock precision.)
- WebLogic Server includes an expiration of 30000 milliseconds (30 seconds) in the SOAP response.
The value specified for the <clock-precision> element is a reflection of how accurately the clocks are synchronized between WebLogic Server and the client applications that invoke the Web Service operation. WebLogic Server uses the value to round all timestamps in a consistent manner. For example, assume that the clock precision is 30000 milliseconds, or 30 seconds. This means that all timestamps are rounded to the closest 30 second increment. This means that, in this example, WebLogic Server rounds the times 12:00:10 and 11:59:50 to the same time (12:00:00) and thus treats the two timestamps equally.
Each of the timestamp elements of the web-services.xml deployment descriptor has a client-side equivalent system property that you can set in your client application. For details, see Using Web Services System Properties.
For detailed descriptions of the <timestamp> element and all its child elements, see WebLogic Web Service Deployment Descriptor Elements.
Encrypting Passwords in the web-services.xml File
Encrypt the key pair passwords (used for encryption and digital signatures) in the web-services.xml file with the weblogic.webservice.encryptpass utility.
The weblogic.webservice.encryptpass utility updates the specified EAR file (or exploded directory) by editing the <security> element of the web-services.xml file, replacing any plain text passwords with their encrypted equivalents.
Only the WebLogic Server domain you specify to the utility is able to decrypt the passwords. This means that if, for example, you want to deploy the EAR file on a WebLogic Server domain different from the one you specified in the encryptpass utility, rerun the utility against the EAR file that contains plain text passwords, specifying the new domain.
To encrypt the passwords:
- Set your environment.
On Windows NT, execute the setEnv.cmd command, located in your domain directory. The default location of WebLogic Server domains is BEA_HOME\user_projects\domains\domainName, where BEA_HOME is the top-level installation directory of the BEA products and domainName is the name of your domain.
On UNIX, execute the setEnv.sh command, located in your domain directory. The default location of WebLogic Server domains is BEA_HOME/user_projects/domains/domainName, where BEA_HOME is the top-level installation directory of the BEA products and domainName is the name of your domain.
- Change to the domain directory of the WebLogic Server domain which will be deploying your EAR file. The domain directory contains the config.xml file for the WebLogic Server.
Warning: Only this WebLogic Server domain will be able to decrypt the encrypted passwords in the web-services.xml file.
- Run the utility:
java weblogic.webservice.encryptpass options ear_or_dirwhere
- options refers to one or more of the options described in Table 13-1.
- ear_or_dir refers to the full path name of the EAR file (or exploded directory) for which you want to encrypt the passwords in the web-services.xml file.
The following example shows how to encrypt the passwords for the Hello Web Service packaged in the ears/myService.ear file:
java weblogic.webservice.encryptpass -serviceName Hello -verbose ears/myService.ear
Option
Description
-help Prints the usage message for the utility. -version Prints the version information for the utility. -verbose Enables verbose output. -warName name Specifies the name of the Web application WAR file, packaged inside the EAR file, that contains the web-services.xml file.Default value is web-services.war. -serviceName name Specifies the name of the Web Service for which you want to encrypt passwords. The name corresponds to the name attribute of the Web Service's <web-service> element in the web-services.xml file.Default value is the first Web Service in the web-services.xml file. -domain directory Specifies the domain directory of the WebLogic Server to which you want to deploy your Web Service.Default value is the current directory from which you are running the utility.
Updating a Java Client to Invoke a Data-Secured Web Service
To update a Java client application to invoke either a WebLogic or a non-WebLogic Web Service that uses digital signatures or encryption:
- Update your client application's CLASSPATH to include WL_HOME/server/lib/wsse.jar, where WL_HOME refers to the top-level directory of WebLogic Platform. This client JAR file contains BEA's implementation of the Web Services Security (WS-Security) specification.
- Update your Java code to load a key pair and digital certificate from the client's keystore and pass this information, along with a username and password for user authentication, to the secure WebLogic Web Service being invoked.
For details, see Writing the Java Code to Invoke a Secure WebLogic Web Service.
For an example of invoking a secure non-WebLogic Web Service, see Writing the Java Code to Invoke a Secure Non-WebLogic Web Service
- Run the client application.
For details about system properties you can set to get more information about the digital signatures and encryption, see Running the Client Application.
Writing the Java Code to Invoke a Secure WebLogic Web Service
The following example shows a Java client application that invokes a message-secured WebLogic Web Service, with the security-specific code in bold (and described after the example):
import examples.security.basicclient.Basic;
import examples.security.basicclient.BasicPort;
import examples.security.basicclient.Basic_Impl;import weblogic.webservice.context.WebServiceContext;
import weblogic.webservice.context.WebServiceSession;
import weblogic.webservice.core.handler.WSSEClientHandler;
import weblogic.webservice.WLMessageContext;import weblogic.xml.security.SecurityAssertion;
import weblogic.xml.security.UserInfo;import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.HandlerRegistry;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;public class AutoClient {private static final String CLIENT_KEYSTORE = "client_keystore"; private static final String KEYSTORE_PASS = "client_keystore_password";private static final String CLIENT__KEYNAME = "client_key"; private static final String CLIENT_KEYPASS = "client_key_password"; private static final String AUTHENTICATION_USER = "auth_user"; private static final String AUTHENTICATION_USER_PASS = "auth_user_password";public static void main(String[] args) throws IOException, ServiceException, Exception { {final KeyStore keystore = loadKeystore(CLIENT_KEYSTORE, KEYSTORE_PASS);Basic service = new Basic_Impl("http://localhost:7001/secservice/basic?WSDL"); WebServiceContext context = service.context();System.out.println("passing context info to the client");X509Certificate clientcert; clientcert = getCertificate(CLIENT_KEYNAME, keystore);PrivateKey clientprivate; clientprivate = getPrivateKey(CLIENT_KEYNAME, CLIENT_KEYPASS, keystore);WebServiceSession session = context.getSession();session.setAttribute(WSSEClientHandler.CERT_ATTRIBUTE, clientcert); session.setAttribute(WSSEClientHandler.KEY_ATTRIBUTE, clientprivate);UserInfo ui = new UserInfo(AUTHENTICATION_USER, AUTHENTICATION_USER_PASS); session.setAttribute(WSSEClientHandler.REQUEST_USERINFO, ui);BasicPort port = service.getbasicPort(); String result = null;result = port.helloback();System.out.println(result);SecurityAssertion[] assertions = (SecurityAssertion[]) session.getAttribute(WLMessageContext.RESPONSE_SECURITY_ASSERTIONS_PROP); for (int i = 0; i < assertions.length; i++) {SecurityAssertion assertion = assertions[i]; System.out.println(assertion); } } }private static KeyStore loadKeystore(String filename, String password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {final KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(filename), password.toCharArray()); return ks; }private static PrivateKey getPrivateKey(String alias, String password, KeyStore keystore) throws Exception { PrivateKey result = (PrivateKey) keystore.getKey(alias, password.toCharArray()); return result; }private static X509Certificate getCertificate(String alias, KeyStore keystore) throws Exception { X509Certificate result = (X509Certificate) keystore.getCertificate(alias); return result; }}The main points to note about the preceding code are:
- Once you create the JAX-RPC Service object, get the WebLogic Web Service context:
WebServiceContext context = service.context();The weblogic.webservice.context.WebServiceContext class is a proprietary WebLogic Web Service client API.
- Load the needed key pairs and X.509 digital certificates from a client keystore:
X509Certificate clientcert; clientcert = getCertificate(CLIENT_KEYNAME, keystore);PrivateKey clientprivate; clientprivate = getPrivateKey(CLIENT_KEYNAME, CLIENT_KEYPASS, keystore);- From the WebLogic Web Service context, get the session information:
Note that the weblogic.webservice.context.WebServiceSession class is a WebLogic Web Service client API.WebServiceSession session = context.getSession();- Use WebServiceSession attributes to pass the private key and digital certificates to the WebLogic Web Service being invoked:
session.setAttribute(WSSEClientHandler.CERT_ATTRIBUTE, clientcert); session.setAttribute(WSSEClientHandler.KEY_ATTRIBUTE, clientprivate);- Create a UserInfo object that contains the authentication username and password, and use an attribute of the WebServiceSession to pass the information to the WebLogic Web Service being invoked:
Note that the weblogic.xml.security.UserInfo class is a WebLogic Web Service client API.UserInfo ui = new UserInfo(AUTHENTICATION_USER, AUTHENTICATION_USER_PASS); session.setAttribute(WSSEClientHandler.REQUEST_USERINFO, ui);- The local methods getPrivateKey(), getCertificate(), and loadKeystore() are simple examples of how to get information from the client's local keystore. Depending on how you have set up your client keystore, you will use different ways of getting this information.
For more information about the WebLogic Web Services APIs discussed in this section, see the Javadoc.
Writing the Java Code to Invoke a Secure Non-WebLogic Web Service
The following example is similar to the one in the previous section, except that it shows how to write a Java client application that invokes a non-WebLogic Web Service, such as .NET.
The example uses the weblogic.xml.security.wsse and weblogic.xml.security.specs APIs to create user Tokens, X.509 Tokens, EncryptionSpecs, and SignatureSpecs which the WebLogic client API uses to create the appropriate <wsse:Security> element in the SOAP message request that invokes the non-WebLogic Web Service. The user Token objects contain username and passwords and X.509 Token objects contain a certificate and an optional private key.
Note: Because there is currently no standard way of specifying security information in the WSDL of a Web Service, consult with the Web Service provider to find out what needs to be signed and encrypted when invoking a non-WebLogic Web Service.
The relevant sections of the example are in bold (and described after the example):
import java.io.IOException;
import java.io.FileInputStream;import java.util.List;
import java.util.ArrayList;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;import javax.xml.rpc.ServiceException;import javax.xml.namespace.QName;import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.HandlerRegistry;import weblogic.webservice.context.WebServiceContext;
import weblogic.webservice.core.handler.WSSEClientHandler;
import weblogic.xml.security.wsse.Security;
import weblogic.xml.security.wsse.Token;
import weblogic.xml.security.wsse.SecurityElementFactory;
import weblogic.xml.security.specs.EncryptionSpec;
import weblogic.xml.security.specs.SignatureSpec;
import weblogic.xml.security.SecurityAssertion;
import examples.security.basicclient.BasicPort;
import examples.security.basicclient.Basic_Impl;
import examples.security.basicclient.Basic;public class Client {private static final String CLIENT_KEYSTORE = "client.keystore"; private static final String KEYSTORE_PASS = "gumby1234";private static final String KEY_ALIAS = "joe"; private static final String KEY_PASSWORD = "myKeyPass";private static final String SERVER_KEY_ALIAS = "myServer";private static final String USERNAME = "pete"; private static final String USER_PASSWORD = "myPassword";public static void main(String[] args) throws IOException, ServiceException, Exception {{ final KeyStore keystore = loadKeystore(CLIENT_KEYSTORE, KEYSTORE_PASS);Basic service = new Basic_Impl(); WebServiceContext context = service.context();// add WSSE Client Handler to the handler chain for the service. HandlerRegistry registry = service.getHandlerRegistry();List list = new ArrayList();list.add(new HandlerInfo(WSSEClientHandler.class, null, null));registry.setHandlerChain(new QName("basicPort"), list);// load the client credential X509Certificate clientcert; clientcert = getCertificate(KEY_ALIAS, keystore);PrivateKey clientprivate; clientprivate = getPrivateKey(KEY_ALIAS, KEY_PASSWORD, keystore);// load the server's certificate... X509Certificate serverCert = getCertificate(SERVER_KEY_ALIAS, keystore);// configure the Security element for the service. SecurityElementFactory factory = SecurityElementFactory.getDefaultFactory();Token x509token = factory.createToken(clientcert, clientprivate); Token userToken = factory.createToken(USERNAME, USER_PASSWORD);EncryptionSpec encSpec = EncryptionSpec.getDefaultSpec(); SignatureSpec sigSpec = SignatureSpec.getDefaultSpec();Token serverToken = null;// create a token for the server's cert... no PrivateKey... serverToken = factory.createToken(serverCert, null);Security security = factory.createSecurity(/* role */ null);//add the username/password to the header as a UsernameToken security.addToken(userToken);security.addSignature(x509token, sigSpec);//add client cert for signature verification and response encryption // should be added after the signature.... security.addToken(x509token);security.addEncryption(serverToken, encSpec);BasicPort port = service.getbasicPort();// add the security element to the request... context.getSession().setAttribute("weblogic.webservice.security.request", security);String result = null; result = port.helloback();System.out.println(result);// view the assertions from processing the server's response... SecurityAssertion[] assertions = (SecurityAssertion[]) context.getSession().getAttribute("weblogic.webservice.security.assertions.response"); for (int i = 0; i < assertions.length; i++) {SecurityAssertion assertion = assertions[i]; System.out.println(assertion); } } }private static KeyStore loadKeystore(String filename, String password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { final KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(filename), password.toCharArray()); return ks; }private static PrivateKey getPrivateKey(String alias, String password, KeyStore keystore) throws Exception { PrivateKey result = (PrivateKey) keystore.getKey(alias, password.toCharArray());return result; }private static X509Certificate getCertificate(String alias, KeyStore keystore) throws Exception { X509Certificate result = (X509Certificate) keystore.getCertificate(alias); return result; }
}The main points to note about the preceding code are:
- Add the WSSE client handler to the client's handler chain:
HandlerRegistry registry = service.getHandlerRegistry();
List list = new ArrayList();
list.add(new HandlerInfo(WSSEClientHandler.class, null, null));
registry.setHandlerChain(new QName("basicPort"), list);- Use the weblogic.xml.security.wsse.SecurityElementFactory to create an object that represents the <wsse:Security> element of the SOAP message. Also use this factory to create the user and X.509 tokens, as shown in the following code excerpts:
SecurityElementFactory factory = SecurityElementFactory.getDefaultFactory();Token x509token = factory.createToken(clientcert, clientprivate);
Token userToken = factory.createToken(USERNAME, USER_PASSWORD);Token serverToken = null;Security security = factory.createSecurity(/* role */ null);- Once you have the security object and tokens, create optional EncryptionSpec and SignatureSpec objects that specify the elements of the SOAP message that you want to encrypt or digitally sign, respectively.
EncryptionSpec encSpec = EncryptionSpec.getDefaultSpec();
SignatureSpec sigSpec = SignatureSpec.getDefaultSpec();- Use the addToken(), addSignature(), and addEncryption() methods to add the tokens to the security element and to specify whether you want the SOAP message to be encrypted or digitally signed. If you created the optional EncryptionSpec or SignatureSpec objects, specify them as parameters to the respective methods. If you do not specify these specs, the entire SOAP message body is encrypted or digitally signed.
security.addToken(userToken);
security.addSignature(x509token, sigSpec);
security.addToken(x509token);
security.addEncryption(serverToken, encSpec);- Add the security element to the SOAP request by setting it as an attribute to the session using the weblogic.webservice.security.request attribute:
context.getSession().setAttribute("weblogic.webservice.security.request", security);Keep the following points in mind when using the WebLogic Web Services Security APIs to invoke a secure non-WebLogic Web Service:
- When you use the addXXX() methods to add tokens and encryption and signature information to the <wsse:Security> element of the SOAP message, they are applied to the message in the order you specify. They appear, however, in reverse order in the resulting SOAP message.
- If you specify that you want the SOAP message to be digitally signed, in your Java code add the X.509 token used for the signature after you have added the signature using the appropriate addXXX() method. This is because the X.509 token, which specifies the actual certificate and optional private key, should be read by the recipient of the message before it processes the signature.
- You cannot encrypt or sign the contents of the <wsse:Security> element itself.
Running the Client Application
When you run the client application that uses digital signatures and encryption to invoke a Web Service, you can set the following system properties to view more runtime security information:
- weblogic.xml.encryption.verbose=true
- weblogic.xml.signature.verbose=true
Configuring Transport-Level Security (SSL): Main Steps
Transport-level security refers to securing the connection between a client application and a Web Service with Secure Sockets Layer (SSL). The following procedure describes the high-level steps; later sections in the chapter describe the steps in more detail.
- Configure SSL for WebLogic Server.
You can configure one-way SSL (the default) where WebLogic Server is required to present a certificate to the client application, or two-way SSL where both the client applications and WebLogic server present certificates to each other.
For details about SSL, the difference between one-way and two-way, and procedures to configure both, see Configuring SSL.
- Optionally update the web-services.xml file to specify that the Web Service can be accessed only by HTTPS.
- Configure SSL for the client application.
Warning: If you use two-way SSL to secure the connection when invoking a WebLogic Web Service, WebLogic Server always asserts the identity of the certificate to ensure that it maps to a valid WebLogic Server user, even if the Web Service or the stateless EJB back-end component does not require any special privileges.
Warning: WebLogic Server does not assert the identity of the certification in one-way SSL, however, because in that case the client application does not send its certificate.
Configuring SSL for a Client Application
Configure SSL for your client application by using either:
- The WebLogic Server-provided SSL implementation. See Using the WebLogic Server-Provided SSL Implementation.
- A third-party SSL implementation. See Using a Third-Party SSL Implementation.
If you are using two-way SSL, your client application must also present its certificate to WebLogic Server. For details, see Configuring Two-Way SSL For a Client Application.
For additional detailed information about the APIs discussed in this section see the Web Service security Javadocs.
Using the WebLogic Server-Provided SSL Implementation
If you are using a stand-alone client application, WebLogic Server provides an implementation of SSL in the webserviceclient+ssl.jar client runtime JAR file. In addition to the SSL implementation, this client JAR file contains the standard client JAX-RPC runtime classes contained in webservicesclient.jar.
Note: For information about BEA's current licensing of client functionality, see the BEA eLicense Web Site.
To configure basic SSL support for your client application, follow these steps:
- Set the filename of the file containing trusted Certificate Authority (CA) certificates. Do this by either:
- Setting the System property trustedfile to the name of the file that contains a collection of PEM-encoded certificates.
- Executing the BaseWLSSLAdapter.setTrustedCertificatesFile(String ca_filename) method in your client application.
- Run your Java client application, either as a standalone client or on WebLogic Server.
If you are creating a standalone client application:
- Add the WL_HOME/server/lib/webserviceclient+ssl.jar runtime Java client JAR file to you CLASSPATH, where WL_HOME refers to the top-level directory of WebLogic Platform. This client JAR file contains the client runtime implementation of JAX-RPC as well as the implementation of SSL.
If your client application is running on WebLogic Server, you do not need this runtime client JAR file.
- Set the following System properties on the command line:
- bea.home=license_file_directory
- java.protocol.handler.pkgs=com.certicom.net.ssl
where license_file_directory refers to the directory that contains the BEA license file license.bea, as shown in the following example:
java -Dbea.home=/bea_home \ -Djava.protocol.handler.pkgs=com.certicom.net.ssl my_appNote: If your client application is running on a computer different from the computer hosting WebLogic Server (which is typically the case), copy the BEA license file from the server computer to a directory on the client computer, and then point the bea.home System property to this client-side directory.
- If you are not using a certificate issued by a CA in your trusted CA file, then disable strict certificate validation by either setting the weblogic.webservice.client.ssl.strictcertchecking System property to false at the command line when you run the standalone application, or programmatically use the BaseWLSSLAdapter.setStrictCheckingDefault() method. Use the second way if your client application is running on WebLogic Server.
By default, client applications that use the WebLogic SSL implementation do not share sockets. If you want to change this behavior, see Using SSL Socket Sharing When Using the WebLogic SSL Implementation.
For detailed information, see the Web Service security Javadocs.
Configuring the WebLogic SSL Implementation Programatically
You can also configure the WebLogic Server-provided SSL implementation programatically by using the weblogic.webservice.client.WLSSLAdapter adapter class. This adapter class hold configuration information specific to WebLogic Server's SSL implementation and allows the configuration to be queried and modified.
The following excerpt shows an example of configuring the WLSSLAdapter class for a specific WebLogic Web Service; the lines in bold are discussed after the example:
// instantiate an adapter... WLSSLAdapter adapter = new WLSSLAdapter(); adapter.setTrustedCertifcatesFile("mytrustedcerts.pem");// optionally set the Adapter factory to use this // instance always... SSLAdapterFactory.getDefaultFactory().setDefaultAdapter(adapter); SSLAdapterFactory.getDefaultFactory().setUseDefaultAdapter(true);//create service factory ServiceFactory factory = ServiceFactory.newInstance();//create service Service service = factory.createService( serviceName );//create call Call call = service.createCall();call.setProperty("weblogic.webservice.client.ssladapter", adapter);try {//invoke the remote web service String result = (String) call.invoke( new Object[]{ "BEAS" } ); System.out.println( "Result: " +result); } catch (JAXRPCException jre) { ... }The example first shows how to instantiate an instance of the WebLogic Server-provided WLSSLAdapter class, which supports the SSL implementation contained in the webserviceclient+ssl.jar file. It then configures the adapter instance by setting the name of the file that contains the Certificate Authority certificates using the setTrustedCertificatesFile(String) method; in this case the file is called mytrustedcerts.pem.
The example then shows how to set WLSSLAdapter as the default adapter of the adapter factory and configures the factory to always return this default.
Note: This step is optional; it allows all Web Services to share the same adapter class along with its associated configuration.
You can also set the adapter for a particular Web Service port or call. The preceding example shows how to do this when using the Call class to invoke a Web Service dynamically:
call.setProperty("weblogic.webservice.client.ssladapter", adapter);Set the property to an object that implements the weblogic.webservice.client.SSLAdapter interface (which in this case is the WebLogic Server-provided WLSSLAdapter class.)
The following excerpt shows how to set the adapter when using the Stub interface to statically invoke a Web Service:
((javax.xml.rpc.Stub)stubClass)._setProperty("weblogic.webservice.client.ssladapter", adapterInstance);You can get the adapter for a specific instance of a Web Service call or port by using the following method for dynamic invocations:
call.getProperty("weblogic.webservice.client.ssladapter");Use the following method for static invocations:
((javax.xml.rpc.Stub)stubClass)._getProperty("weblogic.webservice.client.ssladapter");For detailed information, see the Web Service security Javadocs.
Using SSL Socket Sharing When Using the WebLogic SSL Implementation
By default, socket sharing is disabled for SSL client applications that connect to a WebLogic Web Service using the WebLogic Server-provided SSL implemenation.
However, to improve the performance of your client application, you can enable socket sharing for multiple serial invokes of a Web Service. This socket sharing mechanism provides the improved performance of SSL connection reuse, while giving you the ability to enforce any necessary security.
Implications of Enabling SSL Socket Sharing
If your application is actually a server in which multiple clients use SSL authentication to invoke a Web Service, it is your responsibility to prevent access by one client to another client's JAX-RPC stub implementation object (weblogic.webservice.core.rpc.StubImpl).
Additionally, be aware of the following thread safety issues. The BEA generated JAX-RPC client stubs are thread-safe. However, as soon as you enable SSL socket sharing, the client stubs are no longer thread-safe. To minimize the chances of your Web Service client applications running into threading problems, BEA recommends you do either of the following:
- Implement your Web Service client as an EJB, either stateless session of message-driven. Then, if you want to use a single weblogic.webservice.core.rpc.StubImpl object for all operation invocations, the EJB container will prevent more that one WebLogic execute thread from running at a time. To do this, create an instance variable in the EJB to store the object that extends StubImpl, as shown in the following code snippet:
private TraderServicePort trader_;The TraderServicePort object in the preceding line extends weblogic.webservice.core.rpc.StubImpl.
- Create a new instance of the weblogic.webservice.core.rpc.StubImpl object for each thread. This has some major performance (and coding) implications, so it should only be used as a last resort.
If your client application is not an EJB, you could also use synchronization to handle threading issues. You cannot use synchronization if your client is an EJB, because this would violate the EJB specifiation.
Because of the security and thread safety issues, the socket sharing mechanism is not enabled by default.
Enabling SSL Socket Sharing
To enable socket sharing in your SSL client application, set the Java system property https.sharedsocket to true on the command you use to invoke your client application, as shown in the following example:
java -Dbea.home=/bea_home \ -Djava.protocol.handler.pkgs=com.certicom.net.ssl \ -Dhttps.sharedsocket=true my_appThe default value of the https.sharedsocket system property is false.
You can also specify the timeout value for shared sockets by using the https.sharedsocket.timeout system property to set the number of seconds that shared sockets live, as shown in the following example:
java -Dbea.home=/bea_home \ -Djava.protocol.handler.pkgs=com.certicom.net.ssl \ -Dhttps.sharedsocket=true -Dhttps.sharedsocket.timeout=30 my_appThe default value of https.sharedsocket.timeout is 15 seconds.
Note: This timeout value does nothing to the actual transport layer controlling the socket. The value is used to determine if the SSL socket has not been referenced in the given timeframe and if not, then on this reference, if the time has expired, then the socket is closed and the protocol handshake is restarted.
Using a Third-Party SSL Implementation
If you want to use a third-party SSL implementation, first implement your own adapter class. The following example shows a simple class that provides support for JSSE; the main steps to implementing your own class are discussed after the example:
import java.net.URL;
import java.net.Socket;
import java.net.URLConnection;
import java.io.IOException;public class JSSEAdapter implements weblogic.webservice.client.SSLAdapter {javax.net.SocketFactory factory = javax.net.ssl.SSLSocketFactory.getDefault();// implements weblogic.webservice.client.SSLAdapter interface...public Socket createSocket(String host, int port) throws IOException { return factory.createSocket(host, port); }public URLConnection openConnection(URL url) throws IOException { // assumes you have java.protocol.handler.pkgs properly set.. return url.openConnection(); }// the configuration interface...public void setSocketFactory(javax.net.ssl.SSLSocketFactory factory) { this.factory = factory; }public javax.net.ssl.SSLSocketFactory getSocketFactory() { return (javax.net.ssl.SSLSocketFactory) factory; }
}To create your own adapter class:
- Create a class that implements the following interface:
weblogic.webservice.client.SSLAdapter- Implement the createSocket method, whose signature is:
public Socket createSocket(String host, int port) throws IOExceptionThis method returns an object that extends java.net.Socket. The object is connected to the designated hostname and port when a Web Service is invoked.
- Implement the openConnection method, whose signature is:
public URLConnection openConnection(URL url) throws IOExceptionThis method returns an object that extends the java.net.URLConnection class. The object is configured to connect to the designated URL. These connections are used for infrequent network operations, such as downloading the Web Service WSDL.
- When you run your client application, set the following System property to the fully qualified name of your adapter class:
weblogic.webservice.client.ssl.adapterclassThe default SSLAdapterFactory class loads your adapter class and creates an instance of the class using the default no-argument constructor.
- Configure your custom adapter class as shown in Configuring the WebLogic SSL Implementation Programatically, substituting your class for WLSSLAdapter and using the configuration methods defined for your adapter.
For detailed information, see the Web Service security Javadocs.
Extending the SSLAdapterFactory Class
You can create your own custom SSL adapter factory class by extending the SSLAdapterFactory class, which is used to create instances of adapters. One reason for extending the factory class is to allow custom configuration of each adapter when it is created, prior to use.
To create a custom SSL adapter factory class:
- Create a class that extends the following class:
weblogic.webservice.client.SSLAdapterFactory- Override the following method of the SSLAdapterFactory class:
public weblogic.webservice.client.SSLAdapter createSSLAdapter();This method is called whenever a new SSLAdapter, or an adapter that implements this interface, is created by the adapter factory. By overriding this method, you can perform custom configuration of each new adapter before it is actually used.
- In your client application, create an instance of your factory and set it as the default factory by executing the following method:
SSLAdapterFactory.setDefaultFactory(factoryInstance);For detailed information, see the Web Service security Javadocs.
Configuring Two-Way SSL For a Client Application
If you configured two-way SSL for WebLogic Server, the client application must present a certificate to WebLogic Server, in addition to WebLogic Server presenting a certificate to the client application as required by one-way SSL. The following sample Java code shows one way of doing this where the client application receives the client certificate file as an argument (relevant code in bold):
...SSLAdapterFactory factory = SSLAdapterFactory.getDefaultFactory();
WLSSLAdapter adapter = (WLSSLAdapter) factory.getSSLAdapter();if (argv.length > 1 ) { System.out.println("loading client certs from "+argv[1]);FileInputStream clientCredentialFile = new FileInputStream (argv[1]);
String pwd = "clientkey";adapter.loadLocalIdentity(clientCredentialFile, pwd.toCharArray());javax.security.cert.X509Certificate[] certChain = adapter.getIdentity("RSA",0);factory.setDefaultAdapter(adapter);factory.setUseDefaultAdapter(true);...
Using a Proxy Server
If your client application is running inside a firewall, for example, and needs to use a proxy server, set the host name and the port of the proxy server using the following two System properties:
- weblogic.webservice.transport.https.proxy.host
- weblogic.webservice.transport.https.proxy.port
For more information on these System properties, see Using Web Services System Properties.
Configuring Access Control Security: Main Steps
Access control security refers to configuring the Web Service to control the users who are allowed to access it, and then coding your client application to authenticate itself, using HTTP, to the Web Service when the client invokes one of its operations.
The following procedure describes the high-level steps; later sections in the chapter describe the steps in more detail.
- Control access to either the entire Web Service or some of its components by creating roles, mapping the roles to principals in your realm, then specifying which components are secured and accessible only by the principals in the role.
- Optionally update the web-services.xml file to specify that the Web Service can be accessed only by HTTPS.
- Code your client to authenticate itself using HTTP when invoking a WebLogic Web Service.
See Coding a Client Application to Authenticate Itself to a Web Service.
Controlling Access to WebLogic Web Services
WebLogic Web Services are packaged as standard J2EE Enterprise applications. Consequently, to secure access to the Web Service, you secure access to some or all of the following components that make up the Web Service:
- The entire Web Service
- A subset of the operations of the Web Service
- The Web Service URL
- The stateless session EJB that implements the Web Service
- A subset of the methods of the stateless session EJB
- The WSDL and Home Page of the Web Service
You can use basic HTTP authentication or SSL to authenticate a client that is attempting to access a WebLogic Web Service. Because many of the preceding components are standard J2EE components, you secure them by using standard J2EE security procedures. The following sections describe how to secure each of these components.
Note: If the back-end component that implements your Web Service is a Java class or a JMS listener, the only way to secure the Web Service is by adding security constraints to the entire Web Service or to the URL that invokes the Web Service. In other words, you cannot secure just the back-end component that implements the Web Service.
For additional and detailed information about configuring, programming, and managing WebLogic security, see the security documentation.
Securing the Entire Web Service and Its Operations
You secure an entire Web Service by creating a security policy through the Administration Console and assigning it to a WebLogic Web Service. You can also use the Administration Console to secure a subset of the Web Service operations. Security policies answer the question "who has access" to a WebLogic resource, in this case a Web Service or a subset of its operations. A security policy is created when you define an association between a WebLogic resource and a user, group, or role. A WebLogic resource has no protection until you assign it a security policy.
You assign security policies to an individual resource or to attributes or operations of a resource. If you assign a security policy to a type of resource, all new instances of that resource inherit that security policy. Security policies assigned to individual resources or attributes override security policies assigned to a type of resource.
To use a user or group to create a security policy, the user or group must be defined in the Authentication provider configured in the default security realm. To use a role to create a security policy, the role must be defined in the Role Mapping provider configured in the default security realm. By default, the WebLogic Authentication and Role Mapping providers are configured.
For more information and procedures about setting protections for a WebLogic Web Service or a subset of its operations using the Administration Console, see Securing WebLogic Resources.
Securing the Web Service URL
Client applications use a URL to access a Web Service, as described in WebLogic Web Services Home Page and WSDL URLs. An example of such a URL is:
http://ariel:7001/web_services/TraderServiceYou can restrict access to the entire Web Service by restricting access to its URL. To do this, update the web.xml and weblogic.xml deployment descriptor files (in the Web application that contains the web-services.xml file) with security information.
For detailed information about restricting access to URLs, see Securing WebLogic Resources.
Securing the Stateless Session EJB and Its Methods
If you secure the stateless session EJB that implements a Web Service, client applications that invoke the service have access to the Web application, the WSDL, and the Web Service Home Page, but might not be able to invoke the actual method that implements an operation. This type of security is useful if you want to closely monitor who has access to the business logic of the EJB but do not want to block access to the entire Web Service.
You can also use this type of security to decide at the method-level who has access to the various operations of the Web Service. For example, you can specify that any user can invoke a method that views information, but only a certain subset of users are allowed to update the information.
For more information and procedures about securing EJBs and individual methods of an EJB using the Administration Console, see Securing WebLogic Resources.
Securing the WSDL and Home Page of the Web Service
You can restrict access to either the WSDL or Home Page of a WebLogic Web Service by updating the web-services.xml deployment descriptor that describes the service, as described in the following procedure:
- Open the web-services.xml file in your favorite editor.
The web-services.xml file is located in the WEB-INF directory of the Web application of the Web Services EAR file. See The Web Service EAR File Package for more information on locating the file.
- To restrict access to the WSDL, add the exposeWSDL="False" attribute to the <web-service> element that describes your Web Service. To restrict access to the Home page, add the exposeHomePage="False" attribute. The following excerpt shows an example:
<web-service name="stockquotes" uri="/myStockQuoteService" exposeWSDL="False" exposeHomePage="False" > ... </web-service>The default value of the exposeWSDL and exposeHomePage attributes is True.
- Re-deploy your Web Service for the change to take affect. The WSDL and Home Page of the Web Service will be inaccessible to all users.
Specifying the HTTPS Protocol
You make a Web Service accessible only through HTTPS by updating the protocol attribute of the <web-service> element in the web-services.xml file that describes the Web Service, as shown in the following excerpt:
<web-services> <web-service name="stockquotes" targetNamespace="http://example.com" uri="/myStockQuoteService" protocol="https" > ... </web-service>
</web-services>Note: If you configure SSL for WebLogic Server and you do not specify the HTTPS protocol in the web-services.xml file, client applications can access the Web Service using both HTTP and HTTPS. However, if you specify HTTPS access in the web-services.xml file, client applications cannot use HTTP to access the Web Service.
If you use the servicegen Ant task to assemble the Web Service, use the protocol attribute of the <service> element to specify the HTTPS protocol, as shown in the following sample build.xml file:
<project name="buildWebservice" default="ear"> <target name="ear"> <servicegen destEar="ws_basic_statelessSession.ear" contextURI="WebServices" <service ejbJar="HelloWorldEJB.jar" targetNamespace="http://www.bea.com/webservices/basic/statelesSession" serviceName="HelloWorldEJB" serviceURI="/HelloWorldEJB" protocol="https"
generateTypes="True" expandMethods="True"> </service> </servicegen> </target>
</project>
Coding a Client Application to Authenticate Itself to a Web Service
When you write a JAX-RPC client application that invokes a Web Service, you use the following two properties to send a user name and password to the service so that the client can authenticate itself:
- javax.xml.rpc.security.auth.username
- javax.xml.rpc.security.auth.password
The following example, taken from the JAX-RPC specification, shows how to use these properties when using the javax.xml.rpc.Stub interfaces to invoke a secure Web Service:
StockQuoteProviderStub sqp = // ... get the Stub;
sqp._setProperty ("javax.xml.rpc.security.auth.username", "juliet");
sqp._setProperty ("javax.xml.rpc.security.auth.password", "mypassword");
float quote sqp.getLastTradePrice("BEAS");If you use the WebLogic-generated client JAR file to invoke a Web Service, the Stub classes are already created for you, and you can pass the user name and password to the Service-specific implementation of the getServicePort() method, as shown in the following example taken from the JAX-RPC specification:
StockQuoteService sqs = // ... Get access to the service;
StockQuoteProvider sqp = sqs.getStockQuoteProviderPort ("juliet", "mypassword");
float quote = sqp.getLastTradePrice ("BEAS");In this example, the implementation of the getStockQuoteProvidePort() method sets the two authentication properties.
For additional information on writing a client application using JAX-RPC to invoke a secure Web Service, see http://java.sun.com/xml/jaxrpc/index.html.
Testing a Secure WebLogic Web Service From Its Home Page
The section Deploying and Testing WebLogic Web Services describes how to invoke and test a non-secure WebLogic Web Service from its Home page. To test a secure WebLogic Web Service from its Home Page, however, perform the following additional tasks first:
- If not already configured, configure SSL for WebLogic Server.
For more information, see Configuring the SSL Protocol.
- Add the following flags to the script that starts up this instance of WebLogic Server:
-Dweblogic.webservice.client.BaseWLSSLAdapter.strictCertChecking=false
-Dweblogic.security.SSL.ignoreHostnameVerification=true
- Create a certificate, key, and trusted CA and configure WebLogic Server to use them.
For more information, see Configuring the SSL Protocol.
- Restart WebLogic Server for the startup flags to take effect.
- Invoke the secure WebLogic Web Service's Home Page in your browser. The browser will return a message saying the certificate is not trusted.
- Load the trusted certificate in your browser. You may need to restart your browser for it to take effect.
- Invoke the secure WebLogic Web Service's Home Page again in your browser. You should now be able to test your secure Web Service as described in Deploying and Testing WebLogic Web Services.