How to: Secure SOAP Messages Routed Through the WSE SOAP Router
The Web Services Enhancements for Microsoft .NET Framework (WSE) enables developers to specify and enforce security requirements for SOAP messages exchanged between a client and a SOAP router and SOAP messages exchanged between a SOAP router and a Web service.
Security for SOAP messages exchanged between the client and the router and between the router and the Web service must specify an actor attribute other than the empty string (""). To specify the actor attribute for SOAP messages sent from the client to the router, apply a policy to that SOAP message exchange and set the serviceActor attribute on the turnkey security assertion. Likewise, to specify the actor attribute for SOAP messages sent from the router to the Web service, use the serviceActor attribute on the turnkey security assertion.
Note
Establishing a secure conversation is only supported between a client and the Web service when a SOAP router is not used. That is, a policy cannot include a policy assertion with the serviceActor attribute set to a value other then the empty string ("") and the establishSecurityContext attribute set to true.
Security for SOAP responses exchanged between the Web service and the router must specify an actor attribute other than the empty string (""). To set the actor attribute for SOAP responses sent to the router, set the clientActor attribute on the turnkey security assertion. When security isn't needed between the Web service and the router, the actor attribute can remain as the default empty string ("").
To secure SOAP messages sent to and from a SOAP router
In Microsoft® Visual Studio 2005, create an empty web site.
- Start Visual Studio 2005.
- On the File menu, click New Web Site.
- In the New Web Site dialog box, select Empty Web Site.
- In the Location box, enter the name of the Web server for the SOAP router.
The following procedure uses the location https://localhost/RouterService. - Click OK.
Add an App_Code folder to the project.
- In Solution Explorer, right-click Add ASP.NET Folder, and then click App_Code.
Add a class that represents the SOAP router to the solution.
- In Solution Explorer, right-click App_Code, and then click Add New Item ...
- In the Add New Item dialog box, select Class.
- In the Name box, enter the name of the class that represents the SOAP router.
The following procedure names the classRouterWithPolicy
. - Click OK.
Add references to the Microsoft.Web.Services3 and System.Web.Services assemblies.
- In Solution Explorer, right-click the project, and then select Add Reference.
- Click the .NET tab, select Microsoft.Web.Services3 and System.Web.Services and then click OK.
Add Imports or using directives for WSE-related namespaces.
Open the RouterWithPolicy.cs file.
At the top of the file, add the directives as shown in the following code example.
Imports System Imports System.Data Imports System.Configuration Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Imports Microsoft.Web.Services3 Imports Microsoft.Web.Services3.Messaging Imports Microsoft.Web.Services3.Design Imports System.Security.Cryptography.X509Certificates
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using Microsoft.Web.Services3; using Microsoft.Web.Services3.Messaging; using Microsoft.Web.Services3.Design; using System.Security.Cryptography.X509Certificates;
Edit the
RoutingWithPolicy
class to derive from the SoapHttpRouter class**.**Public Class RouterWithPolicy Inherits SoapHttpRouter
public class RouterWithPolicy : SoapHttpRouter {
Define the policy for SOAP messages exchanged between the client and the SOAP router.
Optionally, create a class that defines the policy for SOAP messages exchanged between the client and the SOAP router.
The policy can be defined in a policy file instead of in a class.
The following code example defines a policy that uses the custom policy assertion defined in the previous step.Public Class RouterPolicy Inherits Policy Public Sub New() Dim assertion As New MutualCertificate11Assertion() assertion.ClientActor = "http://microsoft.web.services3.samples.securerouting/client" assertion.ServiceActor = "https://schemas.xmlsoap.org/soap/actor/next" assertion.ClientX509TokenProvider = New X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "CN=WSE2QuickStartClient") assertion.ServiceX509TokenProvider = New X509TokenProvider(StoreLocation.LocalMachine, StoreName.My, "CN=WSE2QuickStartServer") Me.Assertions.Add(assertion) End Sub 'New End Class 'RouterPolicy
public class RouterPolicy : Policy { public RouterPolicy() : base() { MutualCertificate11Assertion assertion = new MutualCertificate11Assertion(); assertion.ClientActor = "http://microsoft.web.services3.samples.securerouting/client"; assertion.ServiceActor = "https://schemas.xmlsoap.org/soap/actor/next"; assertion.ClientX509TokenProvider = new X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "CN=WSE2QuickStartClient"); assertion.ServiceX509TokenProvider = new X509TokenProvider(StoreLocation.LocalMachine, StoreName.My, "CN=WSE2QuickStartServer"); this.Assertions.Add(assertion); } }
Override the GetRequestPolicy method and specify for the policy for SOAP messages exchanged between the client and the SOAP router.
The following code example overrides the GetRequestPolicy method and specifies the policy defined previously.Protected Overrides Function GetRequestPolicy() As Policy Return New RouterPolicy() End Function 'GetRequestPolicy
protected override Policy GetRequestPolicy() { return new RouterPolicy(); }
Define the policy for SOAP messages exchanged between the SOAP router and the Web service.
Optionally, create a class that defines the policy for SOAP messages exchanged between the SOAP router and the Web service.
The policy can be defined in a policy file instead of in a class.Override the GetForwardRequestPolicy method and specify for the policy for SOAP messages exchanged between the client and the SOAP router.
The following code example overrides the GetRequestPolicy method and specifies that the policy is namedForwardRequestPolicy
and that it is defined in the SOAP router's policy file.Protected Overrides Function GetForwardRequestPolicy() As Policy Return Policies.Default("ForwardRequestPolicy") End Function
protected override Policy GetForwardRequestPolicy() { return Policies.Default["ForwardRequestPolicy"]; }
Specify that the SOAP router runs for this Web application.
In Solution Explorer, double-click Web.config.
Include an <add> element for the <httpHandlers> section to specify the routing class.
The following code example configures the WSE router to run for all SOAP requests received for files with an .asmx extension in this Web application.<configuration> <system.web> <httpHandlers> <add verb="*" path="*.asmx" type="RouterWithPolicy" /> </httpHandlers> </system.web> </configuration>
Note
The type attribute of the <add> Element for <httpHandlers> section must be on one line, even though this example code contains line breaks for readability.
Example
The following code example secures SOAP messages sent between the client and the SOAP router by using a policy that is defined in code. SOAP messages that are sent from the SOAP router to the Web service are secured using a policy that is defined in a policy file.
Note
Typically, you would not define the policy partially in code and partially in a policy file. It is done in this example to demonstrate how to use both methods.
Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports Microsoft.Web.Services3
Imports Microsoft.Web.Services3.Messaging
Imports Microsoft.Web.Services3.Design
Imports System.Security.Cryptography.X509Certificates
Public Class RouterWithPolicy
Inherits SoapHttpRouter
Protected Overrides Function GetRequestPolicy() As Policy
Return New RouterPolicy()
End Function 'GetRequestPolicy
Protected Overrides Function GetForwardRequestPolicy() As Policy
Return Policies.Default("ForwardRequestPolicy")
End Function
End Class 'RouterWithPolicy
Public Class RouterPolicy
Inherits Policy
Public Sub New()
Dim assertion As New MutualCertificate11Assertion()
assertion.ClientActor = "http://microsoft.web.services3.samples.securerouting/client"
assertion.ServiceActor = "https://schemas.xmlsoap.org/soap/actor/next"
assertion.ClientX509TokenProvider = New X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "CN=WSE2QuickStartClient")
assertion.ServiceX509TokenProvider = New X509TokenProvider(StoreLocation.LocalMachine, StoreName.My, "CN=WSE2QuickStartServer")
Me.Assertions.Add(assertion)
End Sub 'New
End Class 'RouterPolicy
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Messaging;
using Microsoft.Web.Services3.Design;
using System.Security.Cryptography.X509Certificates;
public class RouterWithPolicy : SoapHttpRouter
{
protected override Policy GetRequestPolicy()
{
return new RouterPolicy();
}
protected override Policy GetForwardRequestPolicy()
{
return Policies.Default["ForwardRequestPolicy"];
}
}
public class RouterPolicy : Policy
{
public RouterPolicy()
: base()
{
MutualCertificate11Assertion assertion = new MutualCertificate11Assertion();
assertion.ClientActor = "http://microsoft.web.services3.samples.securerouting/client";
assertion.ServiceActor = "https://schemas.xmlsoap.org/soap/actor/next";
assertion.ClientX509TokenProvider = new X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "CN=WSE2QuickStartClient");
assertion.ServiceX509TokenProvider = new X509TokenProvider(StoreLocation.LocalMachine, StoreName.My, "CN=WSE2QuickStartServer");
this.Assertions.Add(assertion);
}
}
See Also
Tasks
How to: Create a Custom Policy Assertion that Secures SOAP Messages