You are on page 1of 7

Automating Security with Policies in Web

Services
(Page 1 of 4 )

Last week's exercise taught you how to install a sample X.509 certificate and configure your
applications to take advantage of their improved security. This week's exercise gets into policies,
which allow for greater automation of certain aspects of security. It is the third in a series of
exercises that are part of a lab titled "Web Services Enhancements 2.0: Security and Policy,"
written by MSDN Virtual Labs.
Exercise 3 Automating Security with Policies
Scenario
In the last two exercises you were able to secure the SecureInvoiceService application by
requiring UsernameToken authentication, message signatures, encryption, and implementing
authorization checks in your WebMethod code. You also used X.509 certificates for signing and
encrypting messages, which provided stronger security in the areas of integrity and privacy.
Implementing these security features was a manual process, meaning you had to write code to
introduce the functionality. This can be tedious and error-prone. A better approach would allow
developers to declaratively enable security features, without having to write any code, while
relying on the infrastructure take care of the details.
WS-Policy is a Web services specification that allows Web services to describe policies. A
policy describes the requirements, preferences, and capabilities of a service. A policy statement
consists of one or more policy assertions (see WS-PolicyAssertions and WS-SecurityPolicy).
Developers can read policy statements to learn how to deal with the service appropriately.
Infrastructure can programmatically inspect policy statements in order to automate the code you
wrote in the previous exercises. WSE 2.0 provides support for all of these specifications as you'll
see below. In this exercise, you're going to secure SecureInvoiceService with minimal code.
You'll be working in the Exercises\C\before directory.
Tasks Detailed steps

Getting Started.
You can write policies for receiving messages as well as for sending messages. In this exercise
you're going to write a policy that describes messages received by the Web service.
1. Return to Visual Studio .NET 2003.

2. Click File | Open | Project.


3. Navigate to C:\Microsoft Hands-on-Lab\DEV-
HOL34\VB\Exercises\C\before.
4. Select PolicyInvoice.sln and click Open. This solution consists of two projects:
PolicyInvoiceClient and PolicyInvoiceService.
5. The code in PolicyInvoiceClient is nearly identical to the SecureInvoiceClient
project you started with before adding security features. The only difference is
that WSE 2.0 has already been enabled.
6. The code for PolicyInvoiceService is identical to the SecureInvoiceService
project you started with before adding security features. The only difference is
that WSE 2.0 has already been enabled.

Note: it doesn't currently require any security features, such as security tokens,
signatures, or encryption.

7. Build the solution. Run the client and verify that security is not currently in place.

Note: now your goal is to provide the same security features you implemented in
the previous exercises without writing a single line of code. You'll accomplish this
with a policy.

Automating Security with Policies in Web


Services - Requiring Security Features with a
Policy
(Page 2 of 4 )

You can write a policy that requires certain security features. In this step, you're going to write a
policy that requires security tokens, signatures, and encryption without having to write any code
(like you did before). You're going to create the policy using the WSE Security Settings Tool.
1. Right click on the PolicyInvoiceService project in Solution Explorer and select
WSE Settings 2.0. This will open the WSE 2.0 settings tool.
2. On the General tab, verify that both check boxes are checked to enable WSE 2.0.
3. Go to the Policy tab and click Enable Policy.
4. In the Edit Application Policy section, click Add.
5. In the Add or Modify Endpoint URI dialog box, enter the following URL:
http://localhost/PolicyInvoiceService/
ViewInvoices.asmx.

Note: this specifies the endpoint that you're going to describe with the policy
you're creating. Make sure you get the case right as the current implementation is
case sensitive.
6. Press OK to close the dialog. This should launch the WSE Security Settings
Tool:

7. Press Next and select Secure a service application.


8. Press Next and ensure that Requires signatures and Requires encryption are
checked for both the request and response messages.
9. Press Next and select Username for the client token type.
10. Press Next and in the Allowed User or Role section, press Add Role. In the Add
Role Name dialog, enter CLIENT1\User. Press OK to close the dialog.
11. Press Next and in the Choose X.509 Certificate section, press Select Certificate.
In the Select Certificate dialog, select the WSE2QuickStartServer certificate.
12. Press OK to close the Select Certificate dialog, press Next, and Finish the
wizard.

Note: the wizard creates a policy that requires the following: a UsernameToken,
a signature based on a DerivedKeyToken (based on the UsernameToken), and an
encrypted body (where the encryption should be performed using the
WSE2QuickStartServer certificate). It also specifies that the authenticated
UsernameToken must belong to the
MACHINE_NAME\User role in order to authorize access.
13. Repeat these steps to create a policy for each of the .asmx endpoints in the
PolicyInvoiceService project (SubmitInvoice.asmx, ApproveInvoice.asmx, and
PayInvoice.asmx). You should choose the same settings described above. The
only difference will be the URL you enter after pressing Add to launch the
wizard.
14. Go to the Security tab and click to select Allow test roots, click Yes to confirm
test roots, and verify that the Store location box contains Local Machine.
15. Press OK to close to the WSE Settings Tool.

Note: the tool made various changes to the project's web.config file and added a
new file named policyCache.config.

16. In Solution Explorer, verify that policyCache.config is now found in the


PolicyInvoiceService project. This file was added by the WSE Settings Tool. It
contains the policy statements you defined by running the wizard.
17. Open policyCache.config and take a look at the XML representation of the policy
statements.
18. Open Web.config in the PolicyInvoiceService project. Notice the new entries in
the microsoft.web.services2 section:

...
<microsoft.web.services2>
...
<security>
<x509 allowTestRoot="true" verifyTrust="true"
storeLocation= "LocalMachine" />
</security>
<policy>
<cache name"C:\HOLDEVL34\ = "policyCache.config" />
</policy>
</microsoft.web.services2>
...

Note: the x509 element tells the WSE 2.0 infrastructure which certificate store to
use and that test certificate authorities are OK. The policy element specifies which
policy file to use for this application.
19. Build the solution.
20. Run PolicyInvoiceClient and test invoking an operation. At this point, you
should get an error indicating: The message does not conform to the policy it
was mapped to. This is because the service now requires various security
features that the client isn't currently sending in the messages. Now the client
needs a policy to figure out what to send.
21. Click OK.
22. Close the Invoice Manager application.

Automating Security with Policies in Web


Services - Adding Security Features with a
Policy on the Client
(Page 3 of 4 )

You can write a policy that adds security features to messages before they're sent. In this step,
you're going to write a policy that adds security tokens, signatures, and encryption to messages
without having to write any code (like you did before). You're going to create the policy using
the WSE Security Settings Tool.
1. Right click on the PolicyInvoiceClient project in Solution Explorer and select
WSE Settings 2.0. This will open the WSE Settings Tool.
2. On the General tab, verify that WSE 2.0 is enabled.
3. Go to the Policy tab and click Enable Policy.
4. In the Edit Application Policy section, click Add.
5. In the Add or Rename Endpoint URI dialog box, leave <DefaultEndpoint>.

Note: this specifies that the policy you're about to create applies to all endpoints
used by this application.
6. Press OK to close the dialog. This should launch the WSE Security Settings
Tool.
7. Press Next and select Secure a client application.
8. Press Next and ensure that Requires signatures and Requires encryption are
checked for both the request and response messages.
9. Press Next and select Username for the client token type.
10. Press Next again (you don't need to specify a role here).
11. Press Next and in the Trusted Certificates section, press Add. In the Select
Certificate dialog, select the WSE2QuickStartServer certificate.
12. Press OK to close the Select Certificate dialog, press Next, and Finish the
wizard.

Note: the wizard creates a policy that tells the client application to: send a
UsernameToken, sign the message with a DerivedKeyToken (based on the
UsernameToken), and encrypt the body with the WSE2QuickStartServer
certificate.
13. Go to the Security tab and click to select Allow test roots, and click Yes to
confirm.
14. In the Store location box, select Current User.
15. Press OK to close to the WSE Settings Tool.

Note:the tool made various changes to the project's app.config file and added a
new file named policyCache.config.
16. In Solution Explorer, verify that policyCache.config is now found in the
PolicyInvoiceClient project. This file was added by the WSE Settings Tool. It
contains the policy statement you defined by running the wizard.
17. Open InvoiceManagerForm.vb and import the following namespace:

...
Imports Microsoft.Web.Services2. Security.Policy
...
18. When you run the client application with the policy in place, WSE will look for a
UsernameToken that it can use in the message. You must supply WSE with this
token ahead of time by adding it to a global token cache. Open
InvoiceManagerForm.vb and update ConfigureProxy to look like this:

...
Private Sub ConfigureProxy(ByVal proxy As _
WebServicesClientProtocol) PolicyEnforcementSecurity
TokenCache.GlobalCache. Clear()
PolicyEnforcementSecurity TokenCache.GlobalCache.Add
(
login.Token)
End Sub 'ConfigureProxy
...
19. Build the solution.
20. Run PolicyInvoiceClient and test invoking an operation. Verify that everything
works.
21. Close the application.
22. Open OutputTrace.webinfo in the PolicyInvoiceClient output directory (bin).
Notice that WSE automatically adds the UsernameToken, signs the message
with a DerivedKeyToken, and encrypts the body of the SOAP message with the
WSE2QuickStartServer certificate. The messages now conform to the
requirements of the service (as specified by the server-side policy).

When you inspect the traced message, you'll notice that the UsernameToken
contains a plain text password that is not encrypted on the way out.
Automating Security with Policies in Web
Services - Adjusting Policy Details
(Encrypting a usernameToken)
(Page 4 of 4 )

In this step, you're going to adjust both policy statements to enforce/require encrypting the
UsernameToken that contains the plain text password.
1. Open policyCache.config in the PolicyInvoiceClient project.
2. Locate the first <Confidentiality> element and update the
<MessageParts> child element to contain the wse:UsernameToken()
message part as illustrated here:

...
<wssp:Confidentiality wsp:Usage="wsp:Required">
<wssp:KeyInfo>
<wssp:SecurityToken>
...
</wssp:SecurityToken>
</wssp:KeyInfo>
<wssp:MessageParts Dialect=
"wsp:Body">http://schemas.xmlsoap.org/
2002/12/wsse#part">wsp:
Body()
wse:UsernameToken()</wssp:MessageParts>
</wssp:Confidentiality>
...
3. Save policyCache.config.
4. Run PolicyInvoiceClient and test invoking an operation. Verify that
everything works.
5. Open OutputTrace.webinfo in the PolicyInvoiceClient output directory
(bin) and verify that the UsernameToken element is now encrypted.
6. Click File | Close Solution.

Note: by using policies, you've been able to implement the same security
features from the first two exercises without having to write any code.
Please check back next week for the continuation of this article.

You might also like