Creating and Using Policies
This topic describes how to use WS-Policy support in InterSystems IRIS. WS-Policy enables you to specify the WS-Security headers to use or to expect. It also enables you to specify use of WS-Addressing headers and MTOM (which are described in Creating Web Services and Web Clients). You create policies in separate classes rather than editing the web service or web client directly. In most cases, no low-level programming is required.
Overview
In InterSystems IRIS, the policy (or collection of policies) for a web service or client is contained in a separate configuration class, a subclass of %SOAP.ConfigurationOpens in a new tab. The policies are in effect when the class is compiled.
No coding is generally required. However, in some cases, you can specify a detail programmatically, rather than having that element hardcoded into the policy.
Effect of the Configuration Class
When you compile a configuration class, the future operation of the web service or client is affected as follows:
-
The web service or client includes additional header elements in outbound messages, according to the details of the policy.
-
The web service or client validates inbound SOAP messages based on the policy. This includes decrypting inbound messages if appropriate.
-
The web service or client optionally encrypts outbound messages, if appropriate.
-
For a web service, the WSDL is automatically affected. Specifically, <wsp:Policy> elements are added, and the namespace declarations include the following:
xmlns:wsp="http://www.w3.org/ns/ws-policy"
If the configuration class is mapped to multiple namespaces, you must compile it in each of those namespaces.
Relationship to WS-Security, WS-Addressing, and MTOM Support
InterSystems IRIS support for WS-Policy is built on InterSystems IRIS support for WS-Security, WS-Addressing, and MTOM. Note the following points:
-
If a policy does not include a security policy, InterSystems IRIS uses the SecurityOut property of the web service or web client. (To add security header elements manually to a web service or client, you add them to SecurityOut property, as described elsewhere.)
-
If a policy does include a security policy, InterSystems IRIS ignores the SecurityOut property of the web service or web client except for any elements that relate to that policy.
For example, when you use the Mutual X.509 Certificates Security policy, you can specify an InterSystems IRIS credential set to use directly within the policy, or you can create an instance of %SYS.X509CredentialsOpens in a new tab and add that, contained in a binary security token, to the SecurityOut property. If you do not specify the credential set directly in the policy, InterSystems IRIS retrieves the binary security token from the SecurityOut property and uses it. InterSystems IRIS ignores other elements in SecurityOut property, however, because they do not apply to this scenario.
-
If a policy requires WS-Addressing, InterSystems IRIS ignores the WSADDRESSING class parameter.
If the AddressingOut property is set, however, InterSystems IRIS uses the WS-Addressing headers that it specifies. Otherwise, it uses the default set of WS-Addressing headers.
-
If a policy requires MTOM, InterSystems IRIS ignores the MTOMREQUIRED class parameter and the MTOMRequired property.
Relationship of Web Service and Web Client
When you attach a policy to a web service, all clients must be able to obey that policy. If the web service policy does not include any policy alternatives, then the clients must have the same policy as the web service, substituting a client-side certificate for the server-side certificate, if needed.
Similarly, if you attach a policy to a web client, the service must be able to obey that policy.
In practice, if both the service and the client are created in InterSystems IRIS, the following procedure is the simplest:
-
Create the web service class.
-
Create the web service configuration class, with the service policy.
-
Generate the client classes, including the client configuration class.
After you do so, examine the generated client classes and make changes if needed.
You usually also create a wrapper class for it.
For information on these tasks, see Creating Web Services and Web Clients.
-
Examine the generated configuration classes and make changes if needed. See Editing the Generated Policy.
For details on the configuration class, see WS-Policy Configuration Class Details.
Creating and Attaching Policies
To create a policy and attach it to a web service or client, you create and compile a configuration class. There are several ways to create this class:
-
Use the GeneratePolicyFromWSDL() method to generate just the configuration class from the WSDL. This option applies if the web service or client class already exists, and you do not want to regenerate that.
-
Create a configuration class manually for an existing web service or client. For information, see the next topic.
If you generate the policy class from a WSDL, you may need to edit it as described in the next section.
Generating the Policy from the WSDL
In some cases, you might already have client classes, but not the corresponding configuration classes. This could occur, for example, if you generate the client classes from the WSDL and later the WSDL is modified to include WS-Policy information. In such cases, you can generate the configuration class alone by using a utility method in %SOAP.WSDL.ReaderOpens in a new tab, as follows:
-
Create an instance of %SOAP.WSDL.ReaderOpens in a new tab.
-
Set properties of that instance as applicable. See the class documentation for %SOAP.WSDL.ReaderOpens in a new tab.
Do not use the Process() method.
-
Invoke the GeneratePolicyFromWSDL() method of your instance.
This method has the following signature:
method GeneratePolicyFromWSDL(wsdlURL As %String, clientWebServiceClass As %String, policyConfigClass As %String) as %Status
Where:
-
wsdlURL is URL of the WSDL which contains the policy. It is assumed that the WSDL specifies only one port.
-
clientWebServiceClass is the name of the web client class. It is your responsibility to ensure that this web client matches the given WSDL.
-
policyConfigClass is the name of the configuration class to be created.
-
This creates (or overwrites) a configuration class for a web service client which contains the policy specified by the WSDL of the web service. If there is no policy in the WSDL, an empty configuration class is created. The configuration class will be compiled if the CompileClasses property of the instance equals 1.
Editing the Generated Policy
If you generate a configuration class from a WSDL and if the WSDL is external to this instance of InterSystems IRIS, you must edit the configuration class to include information about the certificates and SSL/TLS configurations to use. Or you could specify this information at runtime.
The following table gives the details:
If the Generated Policy Includes ... | Do the following ... |
---|---|
<sp:HttpsToken> | For a policy attached to client, do one of the following:
|
<sp:InitiatorToken> | For a policy attached to client, do one of the following:
For a policy attached to a service, no change is needed. |
<sp:RecipientToken> | Do one of the following:
|
<sp:SecureConversationToken> | Optionally add the cfg:Lifetime attribute as described in Adding InterSystems Extension Attributes. The default lifetime is 5 minutes. |
Adding a Certificate at Runtime
If your web service or client must select and include a certificate programmatically, use the following procedure:
-
Retrieve an instance of %SYS.X509CredentialsOpens in a new tab, as described in Retrieving Credential Sets Programmatically.
For example:
set credset=##class(%SYS.X509Credentials).GetByAlias(alias,password)
Or:
set credset=..SecurityIn.Signature.X509Credentials
-
Create an instance of %SOAP.Security.BinarySecurityTokenOpens in a new tab that contains the certificate from that credential set. For example:
set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)
Where credentials is the credential set you retrieved in the previous step.
This returns an object that represents the <BinarySecurityToken> element, which carries the certificate in serialized, base-64–encoded form.
-
Call the AddSecurityElement() method of the SecurityOut property of your web client or web service. For the method argument, use the binary security token you created previously. For example:
do ..SecurityOut.AddSecurityElement(bst)
In some cases, two binary security tokens are needed: one for encryption and one for signing. Be sure to add these in the appropriate order. If the policy encrypts the message and then signs it, be sure to add the binary security token used for encryption before you add the one used for signing. Conversely, if the policy signs and then encrypts, the first binary security token must be the one used for signing.
The following shows an example within a web method in a web service:
//get credentials
set x509alias = "something"
set pwd = "password"
set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias,pwd)
//get certificate and add it as binary security token
set cert = ##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)
do ..SecurityOut.AddSecurityElement(cert)
The code would be slightly different for a web client, because you do not typically edit the proxy client:
set client=##class(proxyclient.classname).%New()
//get credentials
set x509alias = "something"
set pwd = "password"
set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias,pwd)
//get certificate and add it as binary security token
set cert = ##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)
do client.SecurityOut.AddSecurityElement(cert)
//invoke web method of client
Specifying a Policy at Runtime
For an InterSystems IRIS web client, you can specify the policy to use at runtime; this overrides any policy configuration class. To specify the policy at runtime, set the PolicyConfiguration property of the web client instance. The value must have the following form:
Configuration class name:Configuration name
Where Configuration class name is the full package and class name of a policy configuration class, as described earlier in this topic, and Configuration name is the value of the name attribute of the <configuration> element for the policy in that class
Suppressing Compilation Errors for Unsupported Policies
By default, when you compile a configuration class, InterSystems IRIS issues an error if the configuration includes any policy expressions that are not supported in InterSystems IRIS. To suppress such errors, include the following in the configuration class:
Parameter REPORTANYERROR=0;
When you generate a web client or web service from a WSDL, if InterSystems IRIS also generates a configuration class, it includes this parameter setting in that class.
Unsupported alternatives can be ignored as long as there is one supported policy alternative.