This chapter covers
In the previous chapter, which marked the beginning of part III, we began exploring how we can create an enterprise-class SOA security solution using the lessons from part II. As a first step, we looked at how to implement a shared security service that reduces the security enforcement burden on endpoints. That solution addresses only some of the challenges in enterprise security. We will address the remaining ones in this chapter and the next. In this chapter, we will focus on three challenges that can be addressed by adopting a declarative approach to security:
This chapter introduces the concept of declarative security in SOA and shows how you can address these three challenges using security policies in web services. By the end of this chapter, you will understand how to codify and share security policies using standards such as WS-Policy, WS-SecurityPolicy, WS-PolicyAttachment, and WS-MetadataExchange. As some of these standards are not easy to understand, we use examples as the primary mechanism to describe the ideas behind them. You will also learn the shortcomings of these standards and be able to plan for necessary extensions in your use.
We will start off by explaining the declarative approach and why it makes sense for SOA security solutions.
Complexity in programming has been growing over the years. Gone are the days when people armed with the knowledge of a language and a few libraries develop complete applications. These days, developers have to be familiar with several different technologies, standards, and best practices to be effective at their jobs. To complicate matters further, most of the developmental activities that programmers do these days require intricate domain knowledge. Typically, developers do not have this knowledge and need to work with domain experts to develop the solution. Domain expertise is needed in more than the application field. Security, corporate governance, and graphic design are also examples of domains that require specialized expertise.
To help developers and domain experts collaborate without having to fully understand each other’s work, most development platforms these days try to separate out concerns. Declarative programming is one mechanism that’s often used to separate a concern from the rest of the solution.
Declarative programming takes many shapes. In web application development, a graphic artist can declare the look and feel of various elements in the application using Cascading Style Sheets (CSS). The web application developer simply refers to CSS files produced by the graphic artist to get the right look and feel for each of the elements in the application.
A more complex example would be if we let domain experts declare the rules of the system. Taxation domain expert may codify taxation rules by supplying statements such as “long-term gains on energy stocks are tax-exempt for the year 2006.” The declarations are not written in such clear English, but nevertheless, they are separate from the program and available for a domain expert to view, validate, modify, and maintain.
SOA too has several different experts collaborating to develop a solution. In particular, in SOA security, security policies can be developed by people who understand security issues well. If we are to secure services by writing code the way we did in the examples in part II, developers and security experts will have to work very closely with each other. This is clearly not a scalable approach.
Does the idea of security as a service, introduced in the previous chapter, solve this problem? No. Even with a shared security service, developers of each service still need to write the code for interacting with the security service and using its findings appropriately. Instead, if the SOA platforms on which services are hosted allow security experts to declaratively specify the security policies that should be enforced, developers need not work closely with the security experts. Developers can develop services and security experts can set up security policies that should be enforced—the work of both communities will come together seamlessly.
Most web services platforms already support separation of concerns between security experts and service developers. In fact, the latest versions of all leading web services platforms take a policy-driven approach to security, making declarative security not only possible but also the easiest and the most natural way to secure services. If you are developing a service today, you can configure it to be secured by a security policy that was created independently. The security policy may be created by security experts in your enterprises, or you may pick one of the prepackaged security policies provided by your platform vendor. In either case, you are taking a declarative approach to security.
Declarative security can be adapted to varying degrees. The benefits and the complexity involved will differ accordingly. Here are three different degrees to which you can employ declarative security:
Let us look deeper into each of these use cases, in that order.
Declarative security can be employed internally within an enterprise to ensure that security policies are applied consistently by all security solutions used by the enterprise. An analogy will help you understand this better. If you programmed in the C language, you will remember how you can group the definitions of related constants as a header file and include them in multiple applications using the #include mechanism. This mechanism makes it easy to consolidate and manage constants that should have consistent values across multiple applications. It has no bearing on the execution of the code; its use is mainly for maintenance.
Similarly, declarative security can be used to codify and consolidate the security policies in use within an enterprise. Even if we don’t use the policies at runtime, this step of codifying and consolidating all the security policies is still useful. In OO modeling, describing the model in a suitable language can help developers understand a problem and make it tractable. Similarly, codified and consolidated security policies are primarily of help in planning and development.
A full description of the process for policy codification and consolidation is beyond the scope of this book. To describe this process briefly, it starts with a cataloguing of the existing services. After that, the security policy of each service needs to be described. The security policies of each service may subsequently have to be evaluated for compliance with government regulations and corporate governance policies. Eventually, the policies for all services are codified and consolidated in a repository. The codification can take place in several different ways, depending on the tools used.
As shown in figure 9.1, security policies are often scattered in compiled forms in different solutions. Converting security policies into declarative statements (that is, codifying security policies) and consolidating them in a repository will help with consistent application of policies across all solutions in an enterprise. As mentioned earlier, creating and managing a policy repository can be the responsibility of a security expert or experts group. It is the responsibility of the developers to make sure that the applications implement these policies.
The developers, without any special tools or frameworks, can read the codified policies for the services and turn them into working code. This is very much like developing code from use cases. If the security policy of an enterprise states that all uses of HTTPS should be with 1024-bit encryption the developer makes sure that his application follows that rule.
This approach clearly is error-prone and tedious. While it still achieves consistency of security checks, it is not easy to develop; in addition, it does not ensure interoperability. If the tools and frameworks support the development process to use codified policies automatically, as shown in figure 9.1, it can make development a lot easier.
To fully realize the potential of declarative security, we need a few standards.
The benefits of these standards are ease of use and interoperability. Let’s see how to derive these benefits in the next two subsections.
Declarative security can be used at design/deployment time to ensure interoperability between the enterprise’s security solutions and those of partners/customers. The developer of a service consumer can fetch the security policies of the service provider and his own enterprise, reconcile the differences, and develop the consumer to comply with both policies. Better yet, he can do this using a design-time tool. Recall that we did something similar in chapter 2. We generated a service consumer stub from a description of the service in WSDL. Similarly, a tool can assist the developer in complying with the security policies of all parties involved.
For example, as shown in figure 9.2, when the developer is using his application designer, it may present a choice of authentication mechanisms that are supported by the policies of both parties. The developer may opt for one possibility. Based on that choice, the tool can generate the code required for authentication.
The idea of using security policy declarations at design time to ensure interoperability is simple and therefore attractive. It is not always practical. The security policies of the service provider and/or the service consumer are liable to change over time. In such cases, the solutions on both sides may have to be rebuilt when the policy changes on one side. A runtime mechanism to ensure interoperability will not suffer from this problem. Let’s look at that possibility next.
So far, we’ve looked at two different ways to use declarative security: consolidate existing policies and validate them, or use at design time to generate code and configuration. We will look at a more advanced way of using declarative security—namely, using it at runtime.
Consider how your browser interacts with SSL-enabled web servers. Each web server may support several different encryption algorithms with different key strengths. Your browser is also capable of communicating at different encryption strengths. Somehow they negotiate the best possible security mechanism to communicate between themselves. Similarly, a service and a service consumer can exchange security policies at runtime and figure out how to interoperate.
The level of sophistication required in this scenario is clearly much higher. It requires security frameworks that can fetch and reconcile the security policies of parties involved in a message exchange, and customize themselves at runtime. Figure 9.3 shows the requirement.
As figure 9.3 shows, the policies of parties involved in the message exchange can be fetched and reconciled at runtime to ensure interoperability. While the sophistication required for this in practice is quite high, the benefits of interoperability are attractive enough to justify the effort.
Let’s summarize what you have learned in this section so far. Current-generation SOA platforms allow you to declaratively specify the security requirements of a service. This approach is preferable over coding-in the security requirements into each service because:
These three benefits can be realized in practice to varying degrees. The first benefit is the easiest to realize. Almost every leading SOA platform already supports declarative security, helping us hide the complexity of SOA security technologies from service developers and administrators.
The second benefit is a little tougher to realize. Consolidation of security policies using a central repository is easy if there is a standard language for codifying security policies. But all is not lost if there is no standard policy language. Consolidation is still possible, as tools can be created to transform policies expressed in one language into another.
The third benefit is the toughest to realize. A standard policy language is a must if we are to use policies to ensure interoperability. This is possibly why WS-Policy and WS-SecurityPolicy, which, together, define a standard policy language for use in security solutions, seem to limit themselves to addressing the needs of interoperability.
Vendors currently define their own custom extensions to WS-Policy and WS-SecurityPolicy in order to allow you to declaratively specify security for your services. As we cannot possibly describe the extensions created by all leading vendors here, we will restrict the discussion in the rest of this chapter to what the standards cater to now: interoperability.
Before we look into WS-Policy and WS-SecurityPolicy, it helps to first understand the kind of interoperability problems that we seek to solve by codifying security policies. We will dedicate the next section to discussing the interoperability challenges in SOA security.
One of the most compelling arguments in favor of SOA is that it lets enterprises reuse software without being inhibited by differences in platforms. Given this promise, designers of enterprise SOA security just cannot wish for a homogeneous environment. Any enterprise-class SOA security solution will have to interoperate with multiple other implementations of SOA security.
To understand the challenge of interoperability in SOA security, let’s look at the sources of incompatibility between two implementations of SOA security standards. This analysis will help us understand what kind of policy declarations are required to enhance interoperability. We will use this understanding in later sections when we talk about WS-SecurityPolicy.
Here are the main reasons why two different applications implementing the same SOA security standards may be incompatible:
Table 9.1 goes deeper into the sources of incompatibilities. It may not be an exhaustive list, but it is representative of the incompatibility problems that can arise.
Description |
|
---|---|
Choice between transport-layer security and message-level security | Most home-grown web services toolkits still rely on transport-layer security (HTTPS in most cases). Such implementations will clearly not be able to interoperate with endpoints that rely on message-level security enabled by WS-Security. |
Third party to trust: WS-Trust STS, certificate authority, Kerberos KDC, SAML authority | There will never be an agreement on a central security authority. Given this, two implementations that rely on different security authorities will find it difficult to interoperate without prior agreement on some common security authority that each party trusts directly or indirectly. |
Versions of SOAP, WS-Security, security token profiles, WS-Trust, SSL/TLS, and other applicable standards | As web services standards evolve, implementations will vary in support for different versions of standards. Two implementations compliant with different versions of the same standard will run into interoperability problems unless the higher version implementation is backward-compatible. |
Types of supported security tokens | If a service consumer cannot provide a token required by the service provider, interoperability will clearly suffer. Most home-grown service consumers still use username and password for authentication. If a service provider starts requiring the use of digital certificates for authentication, that provider’s services can no longer be accessed by service consumers who do not have the ability to use digital certificates. |
Inclusion/referral of security tokens and in the case of referral, mechanisms used | WS-Security leaves the choice of token transport to implementers in almost all cases. Security tokens can be embedded or referred to using one or more mechanisms. An X.509 certificate can be referred to by its issuer and serial number or by its X.509 SubjectKeyIdentifier. These choices will cause interoperability problems between implementations that do not support all possible referencing mechanisms. |
Choice of algorithms, key strengths, transformations, and encoding | Multiple algorithms exist for almost every cryptography related activity we use in SOA security. This choice will lead to interoperability problems, as not all implementations will support every possible algorithm with every possible variation (such as key strength). |
Encryption/Signing of only selected parts in a message | Most implementations still only support encryption/signatures on the entirety of message body/message. When working with such endpoints, the other endpoint cannot choose to do selective encryption and signing. |
Mechanisms used to refer to protected message elements | The absence of a single mechanism to identify elements in a message has already caused much damage, as we learned in previous chapters. A mix of ID/IDREF with wsu:Id, Id, and xml:id will cause a lot of interoperability problems. |
Order of encryption and signing | As we discussed in the chapter on signatures, we have the option to encrypt and then sign or sign and then encrypt. There are positives and negatives with both orders. Good implementations should be able to deal with both, but poor implementations that assume one order will break if the other party uses another. |
Order of entries in a WS-Security header | It is a little difficult to develop efficient implementations that can access the entries in the security header in random order, as and when required. Implementations may have specific requirements on the order of elements in the WS-Security header. |
Use and location of timestamp in a WS-Security header | Timestamps are needed for detecting replay attacks. There are two practical issues in using timestamps. First, clocks need to be synchronized closely. Second, implementations should understand time zone information. Daylight saving time (DST) is not easy to deal with, especially if different countries keep changing the dates on which DST kicks in/out. |
Attachment mechanism | We describe the evolution of attachment standards in appendix C. As different implementations are likely to use different standards in the near future, interoperability problems are bound to occur. |
As you can see, interoperability problems can stem from different sources:
There are two different ways to solve these interoperability issues. As we mentioned, we can determine the subset of standards to use based on the security policies of involved parties at runtime, which is not easy to implement and unsuitable for some situations.
A simpler solution is to restrict the choices to a small subset (profile), so that implementers have a better chance of supporting that subset. It is clear that this simpler solution cannot solve the interoperability problem completely, will still have to be left to the implementors. Still, this solution is worthwhile in practice. The WS-I Basic Security Profile specification, introduced next, is a standard that attempts this incomplete but simpler solution to interoperability problems in SOA security.
The Web Services-Interoperability (WS-I) Organization is an industry consortium that seeks to enhance interoperability among web services implementations. WS-I publishes implementation guidelines known as profiles for popular web services specifications with the goal of enhancing interoperability. WS-I Basic Profile 1.0 (later split into Simple SOAP Binding Profile 1.0 and Basic Profile 1.1) provides guidelines for implementing SOAP, WSDL, and UDDI. WS-I has also published multiple working drafts of a Basic Security Profile that similarly clarifies WS-Security and associated security token profiles.
Readers of this book will find drafts of WS-I Basic Security Profile very easy to understand. We will not repeating here the long list of rules laid down by this specification. But to help you better understand the basic ideas behind WS-I Basic Security Profile, we will list the kinds of rules you will see in the profile.
As you can see, WS-I Basic Security Profile not only enhances interoperability but also makes it easier to develop a security solution by eliminating unnecessary choices and providing clarifications needed to eliminate the gray areas in WS-Security. WS-I Basic Security Profile, however, cannot guarantee interoperability between conforming implementations. This is because not all choice can be eliminated by WS-I Basic Security Profile. WS-I Basic Security Profile, however, cannot eliminate the choice between PKI and Kerberos. Of course, such a choice is required by implementations. This is where WS-Policy and WS-SecurityPolicy come into play. These specifications attempt to provide a comprehensive framework for ensuring interoperability among web services security implementations. We will introduce you to both of these standards in the next two sections.
As you know by now, a declarative approach to SOA security can bring three main benefits to an enterprise. It can:
Of these three, standards are a key enabler for the last; the other two can benefit from standards too, but are not impossible to accomplish without standards. Currently (at the time of writing this book), standards for declarative security almost exclusively focus on enabling interoperability.
Interoperability of security solutions happens to be a special case of a larger problem. Just like WS-Security, other web services standards that extend SOAP such as WS-ReliableMessaging also leave a lot of choice to implementers in order to ensure applicability in a wide variety of situations. Unless there are mechanisms for ensuring interoperability, it is quite likely that web services implementations that use any of these extensions will not be compatible.
It makes sense to standardize a generic framework for ensuring interoperability. In this section, we will discuss such a framework proposed in WS-Policy and related standards. In particular, we will:
In section 9.4, we’ll look at applying this framework specifically to create security policies. Let’s start with a discussion of the formal concepts of policy and policy intersection.
The word policy suggests process-related rules and guidelines. The definition of a policy is more formal in the context of web services. In this context, a policy is a machine-readable expression of what is required in a message exchange from a WS-Standards perspective. To understand the motivation behind this formalism, let’s look at an example.
Figure 9.4 shows the use of policies for ensuring interoperability in a two-party scenario. In this scenario, party 1 needs to make a web services call to party 2. It does not know the requirements, capabilities, and constraints of party 2. In step 1 of figure 9.4, party 1 fetches the policy of party 2. Party 2’s policy tells party 1 how to customize its implementation in order to interoperate with party 2. Party 2 may have the requirement that all parties invoking its services should:
In addition, it may also have limitations on the algorithms and key strengths it can use for decryption and verifying signatures. Party 2 may only support AES with 128/192-bit keys for decryption.
Party 1 can understand these requirements and constraints by fetching the security policy of party 2. Naturally, it may also have its own requirements and limitations. Party 1’s security solution may have its own list of supported algorithms and key strengths that can be used in encryption and signatures. In our example, let’s assume that party 1 can encrypt using AES and 192/256-bit keys.
At this point, it is obvious to us that party 1 can only use AES with 192-bit keys for encryption when communicating with party 2. The question is: Can machines make this analysis as well and ensure interoperability?
In the simple scenario illustrated in figure 9.5, party 1 needs to compare its own list of supported algorithms and key strengths with the list provided in party 2’s policy and see if the two lists have any common elements. If they do, the two policies are said to intersect or be compatible. Party 1 can customize its call to party 2 using the effective policy determined by computing the intersection between the two policies.
Steps 2 and 3 of figure 9.4 illustrate this process. Party 1 fetches its local policy, compares it with the policy of party 2, and determines an effective policy by computing the intersection between the two policies.
Once an effective policy is computed, party 1 makes the web service call to party 2 using the guidelines in the effective policy. This is shown as step 4 in figure 9.4.
The same mechanism can be used in the opposite direction as well. Party 2 can fetch party 1’s policy when receiving responses, compute the intersection between its own capabilities and party 1’s requirements/constraints, and customize the way it responds to party 1’s request.
Comparing two policies, computing their intersection, and customizing a web service on the fly to ensure interoperability is a complex task. Most web services toolkits are not capable of doing this yet. For now, polices need to be used offline to evaluate interoperability between service providers and consumers and to customize producers and consumers at development or deployment time.
Now that you understand the formal definitions of policy and policy intersections, we can introduce you to WS-Policy. We do that next with the help of an example.
The WS-Policy specification provides the basic syntax for expressing policies. Listing 9.1 is an example policy that lays down the text encoding and languages supported by the subject of the policy.
As you can see from this example, a policy consists of one or more policy assertions that can be grouped together as policy alternatives. In this example, there are two policy alternatives. The first requires the use of a language named Telugu (indicated by the language identifier te) with UTF-8 as the encoding. The second requires the use of English with ISO-8859-1 encoding.
Putting it all together, here’s what this policy is saying: The service/service consumer that is the subject of this policy can understand UTF-8–encoded Telugu messages or ISO-8859-1–encoded English messages.
WS-Policy limits itself to providing the syntax for writing up policies as collections of policy alternatives, each alternative being a collection of policy assertions. It rightly does not go on to enumerate all possible assertions that can be used in a policy. Instead, WS-Policy leaves it up to other specifications to come up with the list of policy assertions that make sense in each domain. The wsp: Language and wsp:TextEncoding assertions shown in listing 9.1, along with a few other very basic assertions useful for all web services, are standardized by a specification named WS-PolicyAssertions and not WS-Policy. In the security domain, WS-SecurityPolicy specifies the list of assertions that can be used for making security policy assertions.
WS-Policy also specifies an algorithm to compare two policies without understanding the semantics of assertions used in either policy and compute their intersection to a first approximation. We will not discuss the algorithm here. You do not need the details of this algorithm unless:
If you fall into either of these categories, you should refer to the WS-Policy specification itself, which provides you with complete details of the policy specification.
In summary, here’s what WS-Policy provides:
Did you notice that there is one missing piece in the standards-based solution we have discussed so far for the interoperability puzzle? Let’s say you are a service consumer. If you can access the service provider’s policy and your own policy, you can use the policy intersection algorithm specified by WS-Policy to compute the effective policy. But how do you access the service provider’s policy? This is the topic of the next section.
The generic policy framework we are describing in this chapter seeks to standardize the approach for solving the interoperability puzzle in web services. As we just pointed out, one of the important questions that the framework should help answer is: How does one fetch the policies of a party one wants to communicate with? Figure 9.6 shows three possible answers to this question.
The first of these possibilities is standardized by WS-MetadataExchange. The second and third possibilities are described by WS-PolicyAttachment. Let us look at both of these standards next, starting with WS-MetadataExchange.
WS-MetadataExchange defines a very simple protocol for querying metadata such as XSD, WSDL, and WS-Policy. Figure 9.7 depicts how a policy document can be fetched using WS-MetadataExchange.
As the figure shows, any entity seeking to fetch metadata can use the GetMetaData request defined by WS-MetadataExchange. The Dialect element in the request can be used to indicate what type of metadata is being requested. Listing 9.2 shows an example request in which the Dialect element is set to a URI that identifies the metadata being requested as a WS-Policy document.
In this example, the client is requesting for the policy from the server. The server may respond with the response shown in listing 9.3.
WS-MetadataExchange is that simple to use. Observe that WS-MetadataExchange does not assume a policy repository (or registry) that is shared by the service provider and service consumer. Policies can be exchanged by any two parties using this protocol.
Service consumers often have access to a service registry in which service descriptions (WSDL documents) are stored. In such cases, it is possible to eliminate the need for a metadata service by attaching policies to service descriptions. The WS-PolicyAttachment standard specifies how this can be done. We will describe WS-PolicyAttachment next.
WS-PolicyAttachment defines how policies can be attached to WSDL definitions and UDDI entities. We will restrict the discussion here to attaching policies to WSDL, since we have not discussed UDDI in detail in this book.
WS-PolicyAttachment identifies four levels at which policies can be defined for a web service. These are Service, Endpoint, Operation, and Message. Formally, these are referred to as policy subjects, as they are the subjects of policy assertions. For example:
1. At the service level, a policy might indicate that all message exchanges need to be logged for auditing purposes.
2. At the endpoint level, a policy might indicate that a particular set of algorithms and key strengths are supported for encryption and signatures.
3. At the operation level, a policy might indicate that a SAML assertion is needed to indicate the privileges and/or preferences of the caller.
4. At the message level, a policy might identify parts of the message that need to be protected with encryption and/or signatures.
The policy to use in a message exchange is a combination of those associated with each of these four levels or subjects. Syntactically, the policy is split into these four portions in WSDL. WS-PolicyAttachment identifies multiple points in WSDL where a policy can be attached for each of these subjects. The endpoint is the subject for policies attached to wsdl:Port, wsdl:Binding, and wsdl:PortType elements in WSDL. The possible points of attachment for each subject are listed in figure 9.8.
WS-PolicyAttachment provides two mechanisms for attaching policy assertions to any element with a WSDL document.
The first of these mechanisms is not always legal, since WSDL does not allow extension elements under all WSDL elements. WS-PolicyAttachment provides the second mechanism as well.
In both cases, URIs are used to refer to policy assertions defined elsewhere. For policy definitions that are available as part of the same WSDL document, the URIs take the form of #Id where Id refers to the policy’s identifier as given by its wsu:Id attribute. Listing 9.4 shows an example.
Naturally, the client needs to combine all the subject-specific policies into one policy to understand the requirements of the service.
So far, we have described a generic policy framework for ensuring interoperability in web services. In particular, we
Now, it is time to look at how this generic framework can be used to ensure interoperability between security solutions. There is only one extension that we need to make the generic policy framework work; we need to standardize the security-related policy assertions we are going to use as part of policy alternatives in a WS-Policy document. WS-SecurityPolicy does exactly this. Let’s study it in the next section.
WS-SecurityPolicy provides security-related assertions that can be used in WS-Policy documents to express the requirements, capabilities, and constraints of a web services security implementation. In particular, WS-SecurityPolicy standardizes assertions related to usage of WS-Security, WS-Trust, and WS-SecureConversation.
The assertions defined by WS-SecurityPolicy can be classified into four groups based on the policy subjects they can be associated with.
Observe that WS-SecurityPolicy does not describe any assertions whose subject is a service. Figure 9.9 further classifies the assertions for endpoints, operations, and messages.
To help you understand the policy assertions, we will show you different kinds of policy examples. We will start with examples of policies defined at the endpoint level.
Before we start to learn the assertions defined by WS-SecurityPolicy for endpoints, it is helpful to understand how the designers of WS-SecurityPolicy approached this problem.
Previously, when discussing the challenges of interoperability between security solutions, we listed (in table 9.1) a large number of potential variations between security implementations that can break interoperability. The task that the designers of WS-SecurityPolicy had on their hands was to come up with policy assertions that unambiguously describe the position a security implementation should take on each possible variation. As there are too many possible variations, the trivial approach of simply defining one assertion per variation will result in a combinatorial explosion.
The designers of WS-SecurityPolicy attacked this problem by recognizing that only a few combinations of these variations are commonly seen in the real world. In fact, most real-world security implementations can be seen as following one of the three security usage patterns shown in figure 9.10.
In words, these three possibilities can be described as:
For each of these security usage patterns, WS-SecurityPolicy defines assertions for:
In addition to assertions related to the security usage pattern, WS-SecurityPolicy defines two other kinds of assertions with regards to an endpoint’s security policies.
We will look at examples of all these assertions in this section. We will start with examples of the assertions that can be used to specify one of the three security usage patterns described in figure 9.10.
The security policy of an endpoint that is secured using transport-layer security is described using a TransportBinding assertion. As part of the TransportBinding assertion, the endpoint can specify the kind of transport-layer security it is willing to accept. It can state that it requires an HTTPS protocol with a specific key strength. Listing 9.5 shows how to put this information in a WS-Policy document.
This example is quite simple—it says that we are using HTTPS for the transport. Let’s next look at an example of the assertions defined for the second security usage pattern described in figure 9.10.
Recall that endpoints that use the same tokens for message protection in both directions (request and reply) are said to be using symmetric binding. An example of a token that can be used that way is a Kerberos ticket. Figure 9.11 shows a sample interaction that is secured in both directions using a Kerberos ticket. The source endpoint in this interaction obtains a Kerberos ticket from a WS-Trust STS (described in section 8.5.1).
Listing 9.6 shows how the service provider shown in figure 9.11 can assert that service consumers must use a Kerberos ticket issued by a specific WS-Trust STS to encrypt/sign messages to and from the service provider endpoint.
In listing 9.6 we are asserting that the initiator should use a token issued by a specific STS . The IncludeToken attribute on the IssuedToken element needs further explanation. This attribute can take four different values to indicate the different possibilities described in table 9.2.
URI[1] |
Description |
---|---|
.../Never | The security token must never be sent along with the message. It must always be referred to using an external reference. Refer to an X509 certificate by issuer and serial number (or other external reference mechanisms for certificates) instead of embedding the certificate. |
.../Once | Only include the token in the first message from the initiator to the recipient. For all subsequent messages in either direction, refer to the token using an external reference. |
.../AlwaysToRecipient | Always include the token in messages from initiator to recipient. Never include the token in messages from recipient to initiator. |
.../Always | Include the token in all messages in either direction. |
1 To keep the text in the table readable, we have only shown the last component of the URIs. Replace “...” in the URIs with http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken
Figure 9.11 is an example of the assertions defined for the third security usage pattern described in figure 9.11.
Recall that asymmetric binding, as opposed to symmetric binding, is where the endpoints use different tokens for message protection depending on the direction of message exchange. Figure 9.12 shows a sample interaction that fits into this pattern.
Listing 9.7 shows how you can use the AsymmetricBinding assertion defined by WS-SecurityPolicy to require the use of two different X.509 certificates—one belonging to the source endpoint and another belonging to the destination endpoint—for protecting request and response messages.
In all three security usage patterns, we need to deal with interoperability issues that can arise out of mismatches in algorithms and key strengths between different endpoints. The next assertion we discuss is designed to deal with this problem.
Instead of defining one assertion per algorithm and key strength combination, WS-SecurityPolicy groups commonly used combinations of algorithms and key strengths into algorithm suites. An endpoint can assert its support for one or more suites using the AlgorithmSuite assertion. We can specify the following snippet under the Policy element to state that the endpoint supports the Basic algorithm suite with 256 bits of key strength.
<sp:AlgorithmSuite> <wsp:Policy><sp:Basic256/></wsp:Policy> </sp:AlgorithmSuite>
The AlgorithmSuite assertion can be nested in any of the three security usage pattern assertions we have defined previously: TransportBinding, SymmetricBinding, and AsymmetricBinding.
We will next discuss the Layout assertion, which can also be nested in any of the three security usage pattern assertions we have defined previously. It is only useful when a WS-Security header entry is used to provide message-level security.[1]
1 Note that a message secured using a point-to-point secure channel such as HTTPS can also have a WS-Security header entry in it.
In chapters 3-8, you have learned a lot about security tokens that can be included as part of a Security header entry in a SOAP message. In these chapters, we have also talked about the ordering of tokens in the Security header entry. In chapter 6, when introducing the security tokens used for encryption, we told you that the ReferenceList of elements that have been encrypted must be prepended to the Security header entry to make the decryption process easy for receivers of the message. But standards cannot always mandate a specific order of elements in the Security header. At the same time, implementations may be limited in their ability to handle elements in arbitrary order; for the sake of simplicity and/or efficiency, implementations may assume particular layouts of elements within the Security header.
So, if we want to ensure interoperability between arbitrary security implementations, we need a standard way to declare the capabilities and constraints of either endpoint in handling different layouts of elements in the Security header entry. WS-SecurityPolicy makes this possible by defining a Layout assertion. This assertion can be used to specify four different kinds of layouts, as described in table 9.3.
Layout name |
Description |
---|---|
Strict | This layout is probably the easiest to handle for WS-Security implementations. Tokens are declared before they are used, signed elements within the WS-Security header appear before their signature, and ReferenceList occurs before any of the EncrypedData elements within the WS-Security header are referred in the list. |
Lax | Elements can occur in any order as long as the WS-Security spec is not violated. |
LaxTimestampFirst | Same as Lax except that the first entry in the WS-Security header must be a wsu:Timestamp element defined by WS-Security |
LaxTimestampLast | Same as Lax except that the last entry in the WS-Security header must be a wsu:Timestamp element defined by WS-Security |
If we want to specify the layout to be strict, here is how we can do it.
<sp:Layout> <wsp:Policy><sp:Strict/></wsp:Policy> </sp:Layout>
One of the elements in the WS-Security header we discussed in table 9.2 is wsu:Timestamp. Let’s next look at assertions related to that.
WS-Security defines but does not mandate the inclusion of a Timestamp element. It is almost always desirable to include it. Implementations that want to make the Timestamp element mandatory can do so using an assertion defined by WS-SecurityPolicy. Using this assertion is quite simple: Just nest an <sp:IncludeTimestamp/> element in the TransportBinding, SymmetricBinding, or AsymmetricBinding assertions, whichever is declared in the endpoint’s policy document.
So far, we have seen assertions related to the three security usage patterns described in figure 9.10. As we described previously, there are two other kinds of endpoint-related assertions that WS-SecurityPolicy defines.
Let’s next look at the assertions related to conformance with WS-Security and WS-Trust.
WS-SecurityPolicy defines assertions that an endpoint can use to declare the conformance it requires with WS-Security 1.0/1.1 and WS-Trust 1.0. As we said before, these assertions become necessary because several options defined by these specifications and implementations may or may not support all options.
WS-Security provides options for referring to a security token. A security token can be embedded within a request or simply referred to using some token identification mechanism. Let’s say an endpoint prefers to refer to X.509 certificates by issuer name and serial number as shown in the following:
<wsse:SecurityTokenReference> <ds:X509IssuerSerial> <ds:X509IssuerName> CN=Prasad Chodavarapu,OU=Authors,O=Manning,... </ds:X509IssuerName> <ds:X509SerialNumber> 1120945714 </ds:X509SerialNumber> </ds:X509IssuerSerial> </wsse:SecurityTokenReference>
How does such an endpoint declare that a client endpoint will need the capability to resolve references to certificates based on issuer and serial numbers? The solution is straightforward: The endpoint should declare in its policy that any party seeking to interact with it must support security token references based on issuer and serial number, as defined in WS-Security 1.0. The following assertion does this:
<sp:Wss10> <wsp:Policy> <sp:MustSupportRefIssuerSerial/> </wsp:Policy> </sp:Wss10>
This example should have given you a good idea of how WS-SecurityPolicy seeks to solve the interoperability problems that arise out of options defined by WS-Security and WS-Trust. Table 9.4 shows the complete list of assertions defined by WS-SecurityPolicy for declaring conformance with various optional aspects of WS-Security 1.0/1.1 and WS-Trust 1.0.
Specification name and version |
Top-level assertion element defined by WS-SecurityPolicy |
Assertions that can be nested |
---|---|---|
WS-Security 1.0 | Wss10 |
MustSupportRefKeyIdentifier MustSupportRefIssuerSerial MustSupportRefExternalUri MustSupportRefEmbeddedToken |
WS-Security 1.1 | Wss11 |
MustSupportRefKeyIdentifier MustSupportRefIssuerSerial MustSupportRefExternalUri MustSupportRefEmbeddedToken MustSupportRefThumbprint RequireSignatureConfirmation |
WS-Trust 1.0 | Trust10 |
MustSupportClientChallenge MustSupportServerChallenge RequireClientEntropy RequireServerEntropy MustSupportIssuedTokens |
Most of the assertions listed in table 9.4 have self-explanatory names so we will not be describing them in detail here. Refer to the WS-SecurityPolicy specification if you need formal definitions for each of these assertions.
Let’s now discuss the last class of WS-Security defined policy assertions that can be attached to an endpoint. These assertions let an endpoint mandate the presence of supporting tokens in addition to the tokens required by the security usage pattern supported by the endpoint.
WS-SecurityPolicy defines four kinds of supporting tokens, as described in table 9.5.
Supporting token type |
Description |
---|---|
SupportingTokens | Tokens included in addition to the token required by the security usage pattern (binding). The inclusion of tokens may necessitate the signing/encryption of more parts. |
SignedSupportingToken | Same as SupportingTokens with the additional assertion that the supporting tokens must be signed using the mechanism described in the security binding. In the case of transport binding, no signing is necessary, as the binding does not use message-level signatures. |
EndorsingSupportingToken | Same as SupportingTokens with the additional assertion that the supporting token should sign the signature produced by the security binding. In the case of transport binding, the endorsing token should simply sign the timestamp in the WS-Security header, as the binding does not produce a message-level signature. |
SignedEndorsingSupportingToken | Combination of SignedSupportingToken and EndorsingSupportingToken. |
Suppose an endpoint wants to specify that we need a SAML 1. 0 token as defined in the SAML Token Profile 1.0 for WS-Security. Here is how it can do so:
<sp:SupportingTokens> <wsp:Policy> <sp:WssSamlV10Token10 sp:IncludeToken=".../Always" /> </wsp:Policy> </sp:SupportingTokens>
Now that you understand several assertions that can be used to describe the security policy of an endpoint, let’s look at the security assertions that describe message-level policies.
Up until now, you’ve seen how WS-SecurityPolicy–defined assertions can be used to specify the requirements, constraints, and capabilities of an endpoint. In this section, we will describe how message-level policies can be defined using the assertions defined by WS-SecurityPolicy.
WS-SecurityPolicy provides assertions to mandate:
1.1 | Signing of specific parts of a message You can sign the entirety of the SOAP body or headers identified by their namespace and, optionally, names. |
1.2 | Signing of selected elements in a message The elements to sign can be identified using XPath. |
2.1 | Encrypting of specific parts of a message You can encrypt the entirety of the SOAP body or headers identified by their namespace and, optionally, names. |
2.2 | Encrypting of selected elements in a message The elements to encrypt can be identified using XPath. |
Listing 9.8 illustrates all of these assertions.
Let’s discuss the assertions defined by WS-SecurityPolicy for declaring operation-level policies.
In table 9.5, we have seen SupportingTokens, the only types of assertion defined by WS-SecurityPolicy that can be associated per operation. There is nothing further to add here about the assertions for operations.
In the past few sections, you have learned about the assertions defined by WSSecurityPolicy. Table 9.6 summarizes the material we covered.
Policy subject |
Assertion topics |
---|---|
Endpoint | Security usage pattern (binding) Conformance with WS-Security and WS-Trust Supporting tokens |
Message | Signing of message parts/elements Encryption of message parts/elements Required elements |
Operation | Supporting tokens |
As we stated before, WS-SecurityPolicy is new, complex, and incomplete. We will discuss its limitations in the next section.
We started this chapter with a vision of declarative security. Any declarative security mechanism has two facets: One is external and supports interoperability and negotiation. Another is internal, which lets an implementation be derived from those declarations. Clearly, WS-SecurityPolicy only aims for the external facet. As yet, it is not suitable for generating a security implementation by itself. We cannot specify the LDAP directory to be used for authentication. SOA security vendors rely on proprietary extensions to fill this void.
Even when we are declaring to others the kind of security we are implementing, WS-SecurityPolicy falls short. We cannot specify the CA to be used for certificates. We can say we need a SAML token, but we cannot specify that the SAML token must contain an authorization assertion. There are several other small details that are needed by a security policy statement but are not covered by WS-SecurityPolicy.
It is worth noting that there are other standards that focus on codification of specific kinds of policies. A standard named XACML (Extensible Access Control Markup Language) provides a language to codify access control policies. XACML is not widely adopted so we will not be covering it in this book.
To summarize, WS-SecurityPolicy supports declarative security that is comprehensive enough for interoperability and negotiation, despite falling short in providing details for a full implementation.
This chapter covers one of the emerging topics in SOA security management. The standards described in this chapter, WS-Policy and WS-SecurityPolicy, are not yet widely used. Yet, several vendors are working on incorporating these standards into their tools.
Let’s recap what we learned in this chapter. Declarative security is driven by three different goals: interoperability among applications, enforcing security policies consistently across several different security solutions in an enterprise, and ease of application development. Of these, the standards currently address only the first goal: interoperability.
Interoperability challenges arise from the choices that applications make in implementing standards. We can eliminate the unneeded choices by adhering to WS-I Basic Security Profile. By itself, it will reduce the complexity of implementation addressing most common requirements.
When our requirements go beyond WS-I Basic Security profile, we can declare the security we need using WS-SecurityPolicy. If you followed the chapter so far, you should understand the details of WS-SecurityPolicy: how to read the policy statements, how to exchange them with another application, and how to even specify a policy with the right syntax.
The standards we have described in this chapter are all very recent and are not yet widely used. It is very likely that they will evolve further to meet real-world needs. We expect future enhancements or modifications to be incremental in nature; the effort you have put in into understanding this chapter should prove to be useful.
Over time, we can expect support from toolkits and solutions to make your job of dealing with security using declarative means easier. For instance, policy discovery, exchange, negotiation, and security decisions can be handled by a framework, without involving any code from the developer side.
This concludes the discussion of standards in implementing security in SOA. Chapter 10 will focus on the real-world issues in implementing solutions built on these standards. We expect more standards to emerge in SOA security over time; the ones we’ve discussed so far will form the core of SOA security.
3.129.217.5