Go

Login
56600 members!
Sign
up to stay informed.

Sponsored Links

Resources

.NET Research
Library
Get .NET related white papers, case studies
and webcasts

WS-Security
Interoperability with .NET/WSE and WebLogic Workshop
8.1WS-Security Interoperability with
.NET/WSE and WebLogic Workshop 8.1WS-Security Interoperability with .NET/WSE and
WebLogic Workshop 8.1

Discuss DiscussDiscuss
Printer friendly Printer
friendlyPrinter
friendly

November 2, 2005

Platform tools for Web services have come a long way since
Simple Object Access Protocol (SOAP) and Web Service
Description Language (WSDL) burst onto the scene in 2000.
Early adopters of SOAP - anxious to be free of the integration
challenges across other RPC-based protocols such as DCOM,
CORBA and RMI - were ready to embrace the first SOAP protocol
libraries offered by their respective platforms. By the time
the .NET Framework was released, SOAP was already a household
name (at least among geeks) and thus was fully integrated into
the framework with baked in IDE support in Visual Studio. Of
course Sun and Apache also supplied Java libraries to support
SOAP protocol very early on (among others), and from this the
possibilities of true message level interoperability between
.NET and Java were immediately present. Of course there were
some bumps along the way with respect to incompatibilities
between platform serialization mechanisms, forcing early
adopters of the protocol to stare at XML for hours, drink more
coffee, and lose sleep in order to resolve issues. These
valiant efforts are what fed today's almost seamless
interoperability between implementations as libraries have
evolved and adapted their interpretations of SOAP, WSDL and
XML Schema to be more predictable. Serialization
incompatibilities still exist, but they are far less frequent
and can generally be overcome by intercepting the
serialization process and slinging some custom code to make it
work.

Why the brief history? It just so happens that we’re in the
middle of a déjà vu regarding the evolution and adoption of
other new protocols that extend SOAP. An inescapable pileup of
specifications - affectionately known as WS* - are helping to
standardize mechanisms for secure and reliable messaging,
workflow, transactions and more. As in the early days of SOAP
protocol the early adopters of WS* must come together to work
through interoperability issues so that tool support can
influence mass adoption by simplifying the process of applying
these specifications.

Figure 1 illustrates the core categories of Web services
messaging standards, specifically detailing the core list of
security standards – some ratified, and some on their way to
ratification. WS-Security was the first of the emerging
specifications to be ratified by OASIS with Web Services
Security: SOAP Message Security 1.0 (WSS: SOAP Message
Security) and a number of token profiles including the
UsernameToken Profile 1.0 (UsernameToken Profile) and the
X.509 Certificate Token Profile 1.0 (X.509 Certificate
Profile). Soon after, WS-I provided a set of guidelines for
interoperability through its publication of Basic Security
Profile 1.1 (Basic Security Profile). WS-Security describes an
interoperable way to authenticate the message sender, ensure
message integrity, protect messages with encryption and even
prevent replay attacks.

Figure 1: Standards for securing Web
services

Though WS-Security is an approved standard, the challenge
facing platform vendors is supporting the same level of
seamless interoperability with emerging standards as they have
achieved for the most part with SOAP and WSDL. But this
challenge runs deeper than before, because they must come up
with viable implementations of the standards while they
continue to mature, even before they are ratified. This
requires an escalated release cycle, coupled with platform
configurability and extensibility to overcome discrepancies
during the transition.

There is no doubt that the future of WS* interoperability
is bright with SOA platforms such as the Windows Communication
Framework (formerly code name Indigo) and equivalent major
updates in the world of J2EE. But, the fact is that I receive
numerous requests about interoperability for today’s deployed
platforms. In this article, I will focus on the state of
WS-Security interoperability between the .NET Framework with
Web Services Enhancements (WSE) and BEA’s productivity
platform for Web services, WebLogic Workshop 8.1 (WebLogic
Workshop). In the process I will discuss the core components
of OASIS WS-Security, how to implement relevant security
scenarios in both platforms, and specifically discuss
approaches to configuring WSE in order to address variations
in each platform’s interpretation of the ratified standard.

You Had Me at SOAP…Now Grant me Security!

Before I get to the implementation details of OASIS
WS-Security for WSE and WebLogic Workshop, let me elaborate on
the importance of message level security. The first question
on your mind is probably, “Why isn’t SSL enough?” In fact,
since SOAP didn’t provide any mechanism for securing messages,
SSL has been long considered “good enough security” for Web
services over HTTP. Other transport-level security mechanisms
like TLS and IPSec may also be embraced to transmit SOAP
messages in a similar, encrypted and secure tunnel. For many
companies this may still be good enough, however, the decision
to stick with transport level security should only be made
after being educated on the benefits of message level security
with WS-Security.

SSL, TLS and IPSec are all techniques for creating a secure
channel through which messages can be transported. Through a
secure key exchange a session key is negotiated between sender
and receiver that can be used encrypt messages between parties
for the duration of the session. In the case of a Web service
request, this key is used to encrypt the request that posts
the message to the receiver and the message response returned
(synchronously) to the sender. This point-to-point encryption
relies on a trust relationship between the message sender and
the ultimate receiver as shown in Figure 2 (a). When a message
arrives at either point it is immediately decrypted. But this
does not address the case when an intermediary hop exists
between sender and receiver. Message level security can ensure
messages are encrypted through to the ultimate receiver, as
illustrated in Figure 2 (b).

Figure 2: (a) SSL, TLS and IPSec make it possible
to secure messages point-to-point. (b) With message level
security the actual message is encrypted until safely arriving
at the ultimate receiver, despite transport hops.

In most cases, the involvement of an intermediary will not
be known to applications sending or receiving messages. An XML
firewall could be installed at the receiver to inspect SOAP
headers and handle rejection of messages that don’t comply
with security policy. A router endpoint could receive messages
before deciding the path for the message behind the firewall.
Even on the sender side, proxies are sometimes present to mask
the sender’s IP address. The bottom line is, unless the data
being sent is not considered private or critical to the
business, the fact that the data is in the clear to anyone
other than the intended recipient is just plain risky.

Besides providing confidentiality of the message through to
the ultimate receiver, other principles of message level
security can also be applied to specific message parts despite
the presence of intermediaries and possibly varied protocols
for transporting messages between points, such as:

Encrypting specific message parts enabling
intermediaries to inspect certain message headers, like
those that apply to routing, security or other policy
verification, without gaining access to other protected
message parts.

Authentication to prove not only the physical origin of
the message, but the originating entity as described by
username, X509 certificate or some other symmetric security
token.

Signing specific message parts so that they can be
separately verified for integrity by each signing party.

Preventing message replay beyond that supplied by the
transport protocol. There are many layers to how Denial of
Service (DoS) attacks can be prevented including firewalls
that intelligently inspect packets for suspected replays,
but it can also be useful inspect message parts for specific
elements that should not be replayed.

WS-Security describes how to attach XML and binary tokens
to SOAP messages, and how to leverage the XML Digital
Signature and XML Encryption specifications to achieve these
goals. In the following sections I’ll describe how .NET with
WSE and WebLogic Workshop apply these security principles, and
what we have to do to make sure they work well together.

Authentication with UsernameToken

One of the primary goals of securing a web service is
authentication of the sender of the message. Before
WS-Security, many services rolled their own authentication
mechanism whereby credentials were passed to the service.
Typical patterns included passing credentials in each method
call or the provision of Login and Logout methods that relied
on an active session for method calls in between to be legal.
The former meant receiving credentials in method calls,
littering the business functionality of the method call with
authentication semantics. The latter often relied on HTTP
sessions to authenticate calls to protected methods, coupling
authentication to the underlying transport protocol. Although
the actual data passed to the service providing credential
information could be interoperable across platforms simply by
leveraging WSDL to describe the required parameters, the
inability to switch protocols or authentication mechanisms
without modifying the service and its clients proposes a
problem. Not to mention the productivity loss from rolling
custom code every time a service or client wants to work with
what would seem to be a very simple construct.

The WS-Security UsernameToken profile provides a
standards-based way to send simple user credentials so that
applications and platforms can unify their approach. It moves
credentials outside of the actual operation into SOAP headers,
making it possible to alter authentication without touching
the operation. It also enables platforms to include generic
code to process username and password to remove the work from
developers and allow for interoperability.

UsernameToken can be used to identify different types of
users including the user logged in to the application that
invokes the service or the actual enterprise that has a
partnership with the service provider. Regardless of their
meaning, using the UsernameToken profile these credentials can
be passed in a standards-based way, and both WebLogic Workshop
and WSE 2.0/3.0 support the standard with some minor
variations between them.

Facets of the serialized UsernameToken include:

The actual Username and Password value, where Password
can be omitted (assumes authentication has already taken
place), sent in clear text, or sent hashed according to
specification rules.

A Nonce and Created timestamp value that together
increase the security of the password hash, and can be used
to prevent token replay attacks.

UsernameToken can be used to sign message parts,
typically by calculating a DerivedKeyToken that is used for
signing.

Let’s see how WSE and WebLogic Workshop are able to
exchange messages that authenticate with this token
format.

UsernameToken: From WSE to WebLogic Workshop

To add WS-Security messaging support to a .NET client
application, you have to first enable WSE support for the
project through the IDE. A reference is added to the
Microsoft.Web.Services2.dll and a new configuration section is
defined in the client’s configuration file (app.config or
web.config). Ultimately, the Web service proxy is in charge of
message serialization/deserialization, so it is important to
enable WSE before creating a Web Reference to the target
service’s WSDL. When WSE is enabled, two proxy types are
generated: one inherits SoapHttpClientProtocol (plain old WSDL
support), the other inherits WSE’s WebServicesClientProtocol
(WS* support).

public class ImageLibraryWse :

Microsoft.Web.Services2.WebServicesClientProtocol { … }

WSE provides two ways to configure WS-Security:
declaratively through policy, or imperatively in code using
the WSE library. Policy configuration is achieved through a
wizard interface installed with the WSE Visual Studio
extension. Alternatively code can be written to manually
attach tokens, signatures and encrypted data elements to the
proxy in order to trigger serialization of those objects. The
WSE library includes built-in abstractions of the WS-Security
specification elements, for example a
<wsse:UsernameToken> WS-Security element is represented
by the UsernameToken type found in the
Microsoft.Web.Services2.Security.Tokens namespace. The
internals of the proxy handle serialization of objects you
attach to it. So, after collecting username and password from
the application user you can create a UsernameToken object and
attach that to the Tokens collection of the WSE proxy as
follows:

using Microsoft.Web.Services2.Security.Tokens;

UsernameToken token = new UsernameToken(username, password,
PasswordOption.SendHashed);
this.serviceProxy.RequestSoapContext.Security.Tokens.Add(token);

When a service operation is invoked through the proxy, the
UsernameToken will be serialized into the WS-Security message
header as follows:

<wsse:Security soap:mustUnderstand="1">

<wsu:Timestamp wsu:Id="Timestamp-fd73c1d5-c9c1-4b1d-af4b-f1c6766bbb0d">

<wsu:Created>2005-07-12T18:39:14Z</wsu:Created>

<wsu:Expires>2005-07-12T18:44:14Z</wsu:Expires>

</wsu:Timestamp>

<wsse:UsernameToken xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="SecurityToken-9efa893f-2ab4-4fc7-8ade-cf76fae00dd3">

<wsse:Username>Admin</wsse:Username>

<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-username-token-profile-
1.0#PasswordDigest">NX68xPJrCL2AXsEgYnxz8yUoYxw=</wsse:Password>

<wsse:Nonce>W4rsmktRtlVjBHc2z7xafg==</wsse:Nonce>

<wsu:Created>2005-07-12T18:39:14Z</wsu:Created>

</wsse:UsernameToken>

</wsse:Security>

Notice that the password is hashed - a simple way to
protect it during transport when the message is not otherwise
encrypted. Hashed passwords rely on the Nonce and Created
timestamp to generate the hashed password value based on the
following algorithm defined in the UsernameToken Profile
specification:

Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )

Hashed passwords are not currently supported by WebLogic.
In fact the only password format supported today by WebLogic
Workshop is clear text. So, in the name of interoperability we
must send the password in clear text and use another form of
encryption to protect it which I’ll discuss later.

Changing the PasswordOption parameter to
PasswordOption.SendPlainText will serialize the UsernameToken
to the following:

<wsse:UsernameToken xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="SecurityToken-fda8d5fa-4904-4ab1-9544-8c66641b5ea0">

<wsse:Username>Admin</wsse:Username>

<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-username-token-profile-
1.0#PasswordText">p@ssw0rd</wsse:Password>

<wsse:Nonce>yyN2OvkjSR+fQY3KsjSwXw==</wsse:Nonce>

<wsu:Created>2005-07-12T18:31:10Z</wsu:Created>

</wsse:UsernameToken>

Now let’s see how to configure WebLogic to authenticate the
user specified by the UsernameToken element.

The WebLogic Workshop stack provides built-in support for
WS-Security, so there are no additional installation steps to
gain support within the IDE. It is important to note that for
WebLogic development there are two distinct stacks available:
the WebLogic Server stack and the WebLogic Workshop stack. The
former comprises the low-level APIs for building server
applications including Web services, and the latter provides
additional classes and configuration capabilities for building
applications including Web services more productively through
the WebLogic Workshop development environment. You can assume
for the rest of this article when I say “WebLogic” I am
referring to the WebLogic Workshop stack.

Web service endpoints are exposed by WebLogic through a
.jws file. Its properties include
ws-security-service, a setting that names the
WS-Security configuration file for the service. To add
WS-Security support to a service endpoint you set this
property to the name of the file as shown in Figure 3.
Creating the actual file by this name is done by adding a new
WS-Security Policy File template to the application.

Figure 3: Web services and service controls that
invoke remote services can have a policy file associated with
them to configure WS-Security settings.

The final version of the inbound service configuration for
the sample is shown in Listing 1.

Listing 1 – Security policy configuration for the
WebLogic service receiving messages from a .NET client.

<?xml version="1.0" ?>

<wsSecurityPolicy xsi:schemaLocation="WSSecurity-policy.xsd"

xmlns="http://www.bea.com/2003/03/wsse/config"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<wsSecurityIn>

<token tokenType="username"/>

<encryptionRequired>

<decryptionKey>

<alias>iwserver</alias>

<password>iwserver</password>

</decryptionKey>

</encryptionRequired>

<signatureRequired>true</signatureRequired>

</wsSecurityIn>

<keyStore>

<keyStoreLocation>teststore.jks</keyStoreLocation>

<keyStorePassword>teststore</keyStorePassword>

</keyStore>

</wsSecurityPolicy>

To require a UsernameToken be provided with incoming
messages to the service, the policy configuration file should
include the following <token> element:

<token tokenType="username"/>

This tells the runtime that inbound messages to the
associated service MUST include a valid UsernameToken.
WebLogic by default will authenticate the user against its
application credential store and throw a SOAP fault for
unauthenticated users.

Summary: UsernameToken Interoperability from
WSE to WebLogic Workshop

WSE can serialize UsernameToken using all password
format variations. WebLogic accepts only clear text
passwords today therefore alternate encryption
mechanisms must be used to protect the password.

Thoughts on Password Hashing

In fact sending hashed passwords is not the best way
to communicate with any service due to the fact that
most credential stores store their passwords hashed. If
the UsernameToken password is hashed there will be no
way to reverse the WSE hash and compare the actual
password against the hashed credential store. To solve
this problem clients must either a) use the same
database hashing algorithm on the clear password before
WSE hashes (double hashing), or b) send encrypted clear
text passwords so that the service can decrypt the
password and use its own database hashing algorithm on
the supplied password to compare against the hashed
database value. Option b) keeps the database hashing
algorithm secret from clients, and reduced overhead of
clients invoking the service. For more details on this
implementation see my blog post on the subject:

http://www.dasblonde.net/PermaLink.aspx?guid=e3db75c6-02c5-4b0d-a681-b733035f112f

UsernameToken: From WebLogic Workshop to WSE

Web service platforms usually consume the WSDL contract for
a target service to generate a proxy that can handle messaging
necessary to invoke operations. In the WebLogic environment
the Web service proxy is generated by creating a Web Service
Control from the WSDL (a .jcx file). As a consumer of a target
service that supports WS-Security, this proxy must also be
able to serialize WS-Security elements that match the policy
of the service it is invoking. Configuring a Web service proxy
to use WS-Security is similar to configuring a service
endpoint in Workshop. A policy configuration file is
associated to the proxy through its
ws-security-service property. After
generating the policy file it can be modified by adding the
<userNameToken> element shown in <wsSecurityOut>
section of the sample’s outgoing policy file listed in Listing
2.

Listing 2 – Security policy configuration for the
.NET service proxy sending messages from WebLogic to .NET.

<?xml version="1.0" ?>

<wsSecurityPolicy xsi:schemaLocation="WSSecurity-policy.xsd"

xmlns="http://www.bea.com/2003/03/wsse/config"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<wsSecurityOut>

<userNameToken>

<userName>Partner

<password type="TEXT">password

</userNameToken>

<signatureKey>

<alias>iwserver</alias>

<password>iwserver</password>

</signatureKey>

</wsSecurityOut>

<keyStore>

<keyStoreLocation>teststore.jks</keyStoreLocation>

<keyStorePassword>teststore</keyStorePassword>

</keyStore>

</wsSecurityPolicy>

The first thing you’ll notice is that the UsernameToken
credentials are hard coded into the configuration file.
Furthermore the password value is not encrypted. Of course, if
this were an interactive client application the user’s
credentials would likely be collected when they log in, and be
dynamically attached to the proxy. In the case of a Web
service invoking another service it is possible that a single
credential is used to identify the calling partner, in which
case configuration could be acceptable so long as the
credentials are encrypted in the policy file. Encrypting
policy file contents is quite easy to do and described clearly
in the WebLogic Workshop documentation.

In either case, WebLogic serializes the UsernameToken in
the outgoing message as follows:

<wsse:UsernameToken xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="Id-HfkQGtbqa4NRnIihuGpUDmTx">

<wsse:Username>Partner</wsse:Username>

<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-username-token-profile-
1.0#PasswordText">password</wsse:Password>

</wsse:UsernameToken>

Notice that the Nonce and Created timestamp are missing,
something we’ll have to attend to when the token is processed
by WSE at the target service.

To authenticate the serialized UsernameToken at the target
.NET Web service the first step is enabling WSE support as
discussed for the client application in the previous section.
The WSE wizard provides an interface for configuring a
SecurityTokenManager to handle authentication of tokens
attached to incoming messages. In the case of the
UsernameToken, the incoming message will be contained within
the OASIS-compliant <wsse:UsernameToken> element, and
the WSE configuration should indicate which type will process
this type of token. The default UsernameTokenManager provided
by the WSE runtime will process the header and authenticate
against the configured Windows credential store. For Internet
applications that use custom credential stores such as a SQL
Server database, a derivation of this type must override the
authentication step. WSE will deserialize the UsernameToken
attached to an incoming message and pass it to the
AuthenticateToken method of the UsernameTokenManager type.

To create a custom token manager, create a class that
derives from UsernameTokenManager, and override the
AuthenticateToken virtual method. This method must validate
the username and return the user’s password to WSE for
comparison against the token provided in the serialized
message as shown here:

using Microsoft.Web.Services2.Security.Tokens;

protected override string AuthenticateToken(UsernameToken token)
{
return Membership.Provider.GetPassword(token.Username);
}

To configure this token manager with WSE the wizard will
generate the following section in the web.config for the
service:

<securityTokenManager type="ImagingServices.MyUsernameTokenManager,
ImagingServices" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-wssecurity-secext-1.0.xsd" qname="wsse:UsernameToken" />

Notice that the namespace and qname for the entry match the
OASIS specification for the <wsse:UsernameToken>
element. This indicates that all OASIS-compliant UsernameToken
elements arriving at the service endpoint will be processed by
this configured token manager.

Here’s where things get interesting. Recall that the BEA
token does not include a Nonce or Created timestamp. This
causes the default implementation of the base class
UsernameTokenManager to reject the message with a SOAP fault
indicating that an invalid security token was provided. That’s
because the WSE runtime invokes the token manager’s
DetectReplay method before authenticating the user, which
requires the presence of Nonce and Created elements to prevent
token replay. The base class UsernameTokenManager
implementation caches a list of Nonce values with an expiry
time, and verifies that a token is not replayed with the same
Nonce within that period. If the service owner is willing to
overlook this default replay check, and resort to other
methods of Denial of Service (DoS) prevention at the hardware
or outer message level, this issue can be overcome by
suppressing the call to DetectReplay.

One way to do this is by modifying the SecurityTokenManager
configuration setting to disable replay detection in the
web.config:

<securityTokenManager type="ImagingServices.MyUsernameTokenManager,
ImagingServices" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-wssecurity-secext-1.0.xsd" qname="wsse:UsernameToken">

<replayDetection enabled="false" />

</securityTokenManager>

But this will disable replay detection for all inbound
messages containing the <wsse:UsernameToken> element.
Instead, by overriding the DetectReplay method in
CustomUsernameTokenManager you can selectively prevent replay
detection if the incoming token is missing a Nonce and Created
timestamp value. With this small change, the UsernameToken is
successfully passed from WebLogic and processed by WSE. The
service operation is invoked if the password returned by
AuthenticateToken matches the password sent in the
message.

Summary: UsernameToken Interoperability from
WebLogic Workshop to WSE

WebLogic does not send the Nonce or Created timestamp
portion of the <wsse:UsernameToken> element by
default, however these are not required elements
according to the UsernameToken Profile 1.0
specification. They are, however, RECOMMENDED elements,
and this explains why the WSE runtime is configured to
expect it by default as the best practice. Fortunately,
this default behavior is easy to override to allow the
token to be accepted for
authentication.

UsernameToken: DerivedKeyToken Signing

If the policy wizard had been used to configure the client
to send a UsernameToken, by default this policy will also use
the token to sign core message parts using a DerivedKeyToken.
Likewise, when policy configuration is used on the service
side, the UsernameToken received in incoming messages to the
service is expected to be used to sign message parts with a
DerivedKeyToken.

Though signatures are quite important for verifying the
integrity of messages, the use of UsernameToken to apply
signatures is not generally supported by other platforms. The
technique used for deriving keys is not documented in the
WS-Security specification, therefore subject to
interpretation. In fact, in the interest of interoperability
it is an enlightening experience to read the actual
specifications where you will find statements like this one in
the Web Services Security: UsernameToken Profile 1.0
specification:

“When a UsernameToken is referenced from a
<ds:KeyInfo> element, it can be used to derive a key for
a message authentication algorithm using the password. This
profile considers specific mechanisms for key derivation to be
out of scope. Implementations should agree on a key derivation
algorithm in order to be interoperable.”

The currently non-ratified WS-SecureConversation
specification does in fact define a mechanism for using
derived keys for message signature, and this is the
implementation that WSE is using for username token signatures
through policy. However, interoperable messages should not use
the UsernameToken for signing message parts. Instead, other
symmetric or asymmetric keys should be applied as will be
discussed in the next section.

Summary: UsernameToken Signing from WSE to
WebLogic Workshop

WSE employs the WS-SecureConversation specification
to generate DerivedKeyToken values from a UsernameToken,
in order to sign message with the derived key. WebLogic
does not support signatures with derived key tokens.

Thoughts on WS-SecureConversation and
WS-Trust

WS-SecureConversation and WS-Trust are among the next
generation of security specifications that will soon
become ratified. In many respects their token issuance
and secure conversation mechanisms are superior to the
existing OASIS WS-Security options for authentication
and secure communication because they incorporate the
concept of dynamic key generation for authentication,
signing and encryption and reduce some of the key
management issues that exist today. WSE includes an
early look at these protocols which helps early adopters
to provide useful feedback, but interoperability on that
level will not be reliable until the specifications are
actually approved.

X.509 Authentication and Message Integrity

Though passing UsernameToken information is quite important
for providing an audit trail of the application user invoking
a service, X.509 certificates can be additionally useful to
identify the organization or system sending the message, and
ensure the message was not tampered with en route by signing
message parts with the certificate’s private key. An X.509
certificate makes it possible to identify the message origin
in absolute terms since the owner of the private key is the
only party that can sign messages with that key. Passwords are
subject to dictionary attacks, not to mention they have been
known to be written down on sticky notes attached to the
user’s computer monitor! A properly secured private key
installed into a certificate store that is accessible only
behind the firewall of the calling system, is much less at
risk and can’t be spoofed.

When a message is signed with a private key, the related
public key is sent with the message so that the receiver can
authenticate the message is sent by a trusted party, verify
that signed message parts were signed with the matching
private key, and confirm that signed message parts were not
tampered with during transport.

Combining the use of X.509 tokens with UsernameToken makes
it possible then to identify the organization or system, and
the actual user that logged in to the application triggering
the message. Even in cases where the logged in user does not
have credentials with the target service, an audit trail can
be maintained at a more granular usage level if the user name
is included in the message.

X.509 Signatures: From WSE to WebLogic Workshop

Configuring WSE to sign messages with an X.509 certificate
can be done through the policy wizard or manually by writing
code to create signatures and subsequently attach them to the
proxy. From an interoperability perspective the end result is
the same, so I’ll focus on the use of security policy in this
example. A short walk through the WSE policy wizard allows you
to specify that X.509 Certificate will be the type of token
used to sign outgoing messages, and then select the X.509
certificate to use from the Windows certificate store. By
default this generates a security policy that tells the WSE
runtime to sign core WS-Addressing headers, the WS-Security
Timestamp header, and the body of the message. This policy
file currently follows the WS-SecurityPolicy specification
although it is only used internally to configure the runtime
behavior. The runtime uses this policy to find the signing
certificate and apply the signature to the appropriate message
parts.

In the policy file generated for the client application in
the sample code, the <wssp:Integrity> section indicates
X.509 as the security token type to use for signing. The
policy contains enough information for the runtime to find the
certificate, and to select the correct message parts to sign.
Separate from the signing policy there is also a
<wsp:MessagePredicate> section indicating which message
parts should be present in all outgoing messages:

<wsp:MessagePredicate wsp:Usage="wsp:Required"
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()
wsp:Header(wsa:To) wsp:Header(wsa:Action) wsp:Header(wsa:MessageID)
wse:Timestamp()</wsp:MessagePredicate>

Policy verification verifies all message parts are present,
then proceeds to sign those parts indicated by the signing
policy. The application configuration file (app.config in this
sample) includes a setting for the certificate store to be
used to retrieve certificates specified by policy. In this
example, the CurrentUser store is expected to contain all
signing and encrypting certificates specified by policy. No
additional code to retrieve certificates is necessary at this
point, so let’s move to the WebLogic configuration required to
receive signed messages.

A WebLogic service can require an X.509 signature be
applied to incoming messages by configuring its security
policy to include the <signatureRequired> section in the
<wsSecurityIn> section shown in Listing 1. In addition
to requiring signatures, notice that a java key store is also
specified. This is the key store where the public key portion
of the certificate should be found for authentication.

This configuration assumes the use of X.509 certificates
for signing, and expects only the body of the message to be
signed since WebLogic doesn’t currently require or process
WS-Addressing headers or the security Timestamp header (WSE
supplies these by default). Superfluous, signed message parts
are simply ignored by WebLogic, therefore the message is still
processed according to plan.

WebLogic will require the body to be signed and validate
the message signature. However, the runtime does not actually
authenticate the signature against the key store. To achieve
authentication additional code must be written on the WebLogic
side.

Summary: X.509 Signature from WSE to WebLogic
Workshop

Signing messages from WSE to WebLogic is
interoperable although their runtime implementations
differ significantly. WSE by default supplies
WS-Addressing headers and a security Timestamp header.
WSE security policy will by default sign those headers
along with the message body. WebLogic ignores the
presence of WS-Addressing and security Timestamp headers
in its current implementation, but will validate the
signature of the message body if it is signed. For the
signature to be useful for authentication purposes,
additional code must be written on the WebLogic side to
process the signing token. This is outside of the scope
of the WS-Security specification.

Other binary security tokens can be used to sign
messages, for example derived keys based on the
UsernameToken, Kerberos tokens, other binary security
tokens, and any XML token including SAML tokens. WSE
provides built-in support for UsernameToken, Kerberos
and X.509 through the security policy wizard and is
extensible to support additional token types either by
hand-modifying policy or by writing code to manually
attach tokens to the outgoing message. The current
release of WebLogic currently only supports X.509 tokens
for signing messages.

X.509 Signatures: From WebLogic Workshop to WSE

Now let’s visit the process of signing messages from
WebLogic to .NET. Once again the Web service proxy and its
security policy file must be modified to influence outgoing
messages to the .NET Web service. Referring back to the policy
file shown in Listing 2, the <signatureKey> element of
the <wsSecurityOut> section instructs the WebLogic
runtime to sign the body of the message with an X.509
certificate to be found in the key store: teststore.jks. The
certificate alias is iwserver, and the password to access it,
the same. The WebLogic runtime will use this configuration
setting to add a BinarySecurityToken to the
<wsse:Security> header, representing the public key
portion of the certificate, and subsequently use the private
key to sign the body of the message. Once again, WS-Addressing
headers and a security Timestamp header are not serialized in
the outgoing message from WebLogic.

To require inbound messages to be signed at the .NET target
service, the WSE security policy wizard can be used to
configure a server side policy that not only requires specific
message parts to be signed, but also includes a list of
trusted public keys for authentication. By default, this
policy will require that messages include WS-Addressing
headers, a security Timestamp header, and of course a message
body. The <wssp:Integrity> setting will also require
these message parts be signed.

Since we already know that WebLogic does not send
addressing and timestamp headers, nor sign them, we know that
the message will fail policy verification by the WSE runtime.
So, the security policy must be hand-edited to reduce the
requirements. This can be done by manually removing all but
wsp:Body() from both the <wsp:MessagePredicate> and the
<wssp:Integrity> section’s <wssp:MessageParts>
list. Once missing elements of the incoming messages are no
longer required by policy, the message will pass verification
by the WSE runtime. After the signed message body passes
verification, the WSE runtime will also authenticate the
source of the message by looking up the public key in the
configured certificate store.

Summary: X.509 Signature from WebLogic
Workshop to WSE

Signing the message body from WebLogic to WSE is
interoperable. The distinction between the platforms
really lies in the default behaviors such as: WSE by
default requires additional headers that are not
required by the specification today; WSE also provides
an authentication step against the signature, although
this also is not a requirement of the
specification.

X.509 Encryption and Message Confidentiality

In this final section I’ll discuss how messages are
encrypted with X.509 certificates to provide message level
encryption regardless of the transport protocol. Any message
part can be encrypted but typically the body of the message is
the primary focus. Sensitive headers, such as security tokens
and timestamps also make great candidates for encryption.

When a message part is encrypted, an encrypted version of
the message part is put in its place in the context of the
message. Information about the encryption key and the
algorithm used to encrypt are sent along with the encrypted
message to provide key material to the receiver. The correct
procedure for attaching key material and encrypted data to a
SOAP message are collectively defined by the WSS: SOAP Message
Security, X.509 Certificate Profile, XML Encryption and XML
Signature specifications. As you might imagine, given the size
of some of these specifications the number of approaches
toward forming encrypted messages, referencing tokens,
supplying key material and so forth, will make your head spin.

When X.509 tokens are used to encrypt messages, there are
two exchanges to consider. The message sender will use the
public key of the receiver to encrypt messages that can only
be decrypted by that receiver’s protected private key. The
message receiver may encrypt message responses to the sender
by using the public key associated with the private key the
sender used to sign the message. In other words, X.509
signatures can play a role in encrypting responses to signed
requests.

X.509 Encryption: From WSE to WebLogic Workshop

WSE configuration steps for encrypting messages with X.509
certificates is similar to that discussed for signing messages
with X.509 certificates. The policy wizard provides steps for
selecting a public key from the configured Windows certificate
store. This public key should match the private held and
protected by the recipient of the message so that only that
recipient can decipher the encrypted message parts sent.

By default, the WSE security policy generated will encrypt
only the body of the message as indicated by the
<wssp:MessageParts> section of the
<wssp:Confidentiality> element. It is possible to
manually edit this policy to include other message parts in
the encryption process. For example, since the UsernameToken
element is sending clear text passwords, it would be good to
encrypt that token as well. By modifying the confidentiality
section of the policy to include wse:UsernameToken() in the
message parts list, the WSE runtime will properly encrypt it
along with the body of the message:

<wssp:Confidentiality>

…

<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()
wse:UsernameToken()</wssp:MessageParts>

</wssp:Confidentiality>

In fact, according to the WS-SecurityPolicy specification,
the MessageParts element should have required
wsse:UsernameToken() however a typo in the WSE runtime
requires this be wse:UsernameToken(). The point is that
although the wizard configures certain default behaviors for
encryption, the WSE runtime is capable of parsing additional
policy settings not injected by the wizard.

These steps will generate a message that replaces both the
UsernameToken and message body elements with EncryptedData
elements.

To configure WebLogic to require encryption, the security
policy file of the target service will be modified to include
an <encryptionRequired> element within the
<wsSecurityIn> section as shown in Listing 1. The
<decryptionKey> element specifies the private key for
the service, with a password to access it from the specified
key store.

WebLogic doesn’t require the configuration setting to
indicate which parts will be encrypted, so long as at least
one message part is encrypted. In fact, it does not have to be
the body of the message! If the outgoing security policy of
the WSE client requests only the UsernameToken be encrypted,
that will suffice. In this case, since both the body and
UsernameToken are encrypted, WebLogic will properly decipher
both message parts using the key material indicated in the
message, and the user will successfully be authenticated, the
body of the message parsed accordingly.

Summary: X.509 Encryption from WSE to
WebLogic Workshop

Encrypting messages from WSE to WebLogic is
interoperable. The WebLogic runtime will automatically
decipher whatever parts are encrypted, so long as they
are message parts that the WebLogic runtime
recognizes.

X.509 Encryption: From WebLogic Workshop to WSE

Now I’ll once again return to the WebLogic environment to
configure the proxy for sending encrypted messages. The
security policy file thus far associated with the proxy is
listed in Listing 2. In order to add encryption to the
outgoing message the following <encryption> section
should be added to the <wsSecurityOut> section of the
policy:

<encryption>

<encryptionKey>

<alias>wseserver</alias>

</encryptionKey>

</encryption>

The <encryptionKey> setting indicates which public
key from the key store to encrypt the body of the outgoing
message. In this case, the public key name is wseserver, and
the matching private key is held by the .NET service to
decrypt messages.

The policy wizard can be used to configure the .NET service
to require encryption. In this case, the default requirement
of the policy for the message body to be encrypted. Still,
encrypted messages from WebLogic can not be processed by the
WSE runtime due to an interoperability issue.

With encryption policy enabled, the WSE runtime will throw
a security fault as it attempts to decrypt the EncryptedData
value. The error refers to the format of the EncryptedData
using Element type, and incorrectly containing more than one
XML element. Solving a problem like this can get ugly, because
without understanding the way encrypted message parts are
supposed to be serialized according to specification, how is
it possible to determine where the error occurred and if it is
something you have control over?

The EncryptedData element passed from WebLogic looks like
this:

<SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-
gBlyI9_yecYJBlUU_uXGckGH">

<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
Id="Id-pZpR5Z4Clx9m__86ivLULMkM"
Type="http://www.w3.org/2001/04/xmlenc#Element">

<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />

<xenc:CipherData>

<xenc:CipherValue>…</xenc:CipherValue>

</xenc:CipherData>

</xenc:EncryptedData>

</SOAP-ENV:Body>

Notice that the Type attribute indicates the encrypted data
was generated as #Element. This means that the encrypted data
represents the encrypted contents of a child of the body
element. In theory, a single root element exists within the
body element, but in fact multiple children of the body is
supported by the SOAP specification. As a result, the
WS-SecurityPolicy specification which drives the WSE policy
processor looks for EncryptedData to be based on the #Content
type.

Consider this snapshot of the encrypted data element sent
by WSE to WebLogic:

<soap:Body wsu:Id="Id-ea2877b2-5ad2-4d43-a715-07d66fb8a3e4">

<xenc:EncryptedData Id="EncryptedContent-a0529d26-78bf-409d-91bc-
9891ea68b842" Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">

<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />

<xenc:CipherData>

<xenc:CipherValue>…</xenc:CipherValue>

</xenc:CipherData>

</xenc:EncryptedData>

</soap:Body>

Though it is likely the yield from both EncryptedData
elements would be equivalent if performed on the same
originating message, the #Content type absolutely guarantees
that the entire contents of the message body are encrypted.

So, what happens if we remove WS-SecurityPolicy from the
equation and send the EncryptedData from WebLogic to WSE for
processing? A new problem rears its head in this case.
Although the message no longer fails policy verification, it
now fails to retrieve the referenced security token from the
EncryptedKey element.

The error message in fact describes the problem completely.
Deep inside the plumbing of WSE, the EncryptedKey type is used
to parse the key material passed with the message. This
parsing process is looking for a way to reference the actual
security token required to decrypt the message. In fact it is
specifically looking for a key value, and WebLogic is
providing a key name in its stead. Here’s where the water gets
muddy once again: so many specifications; so many
possibilities; and so many technically correct ways to achieve
the same goal. Which specification should we follow?

The desired result was to encrypt the body of the message
and provide key material. That is exactly what WebLogic did,
where the key material was provided in an
<xenc:EncryptedKey> element as follows:

<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">

<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-
1_5" />

<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">

<dsig:KeyName>CN=WSE2QuickStartClient</dsig:KeyName>

</dsig:KeyInfo>

<xenc:CipherData>

<xenc:CipherValue>…</xenc:CipherValue>

</xenc:CipherData>

<xenc:ReferenceList>

<xenc:DataReference URI="#Id-5CkREMYaZ3xdmZ7G2H2xasl_" />

</xenc:ReferenceList>

</xenc:EncryptedKey>

In order to decrypt the message body the recipient of the
message must be able to find the key required to perform the
decryption. KeyName is one legal way to identify the
decryption key – in fact it is the RECOMMENDED way according
to the XML Encryption specification. But according to the
X.509 Certificate Profile, KeyInfo should contain a
SecurityTokenReference that in turn can reference the key in
one of several ways including KeyIdentifier and KeyName (where
the former is preferred). For example, WSE sends the KeyInfo
element in this way:

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<wsse:SecurityTokenReference>

<wsse:KeyIdentifier ValueType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-
1.0#X509SubjectKeyIdentifier" EncodingType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-soap-message-security-
1.0#Base64Binary">+pS7tYztAOJhscYSdiL1MGsXic8=</wsse:KeyIdentifier>

</wsse:SecurityTokenReference>

</KeyInfo>

So, although legal according to the XML Encryption
specification, the way WebLogic serializes encryption violates
the interoperability requirements of WS-Security today.
Fortunately BEA does supply a workaround for this issue that
can be requested directly through their developer support
channels.

Summary: X.509 Encryption from WebLogic
Workshop to WSE

Encrypting messages WebLogic to WSE is not currently
interoperable due to each platform’s interpretations of
the various specifications. According to the OASIS WSS:
SOAP Message Security specification, WebLogic is not
serializing EncryptedKey elements in a compliant manner.
This issue extends also to encrypted responses from
WebLogic to .NET clients.

WS-Security Interoperability and Beyond

Throughout this article I have focused on the current state
of interoperability between WebLogic Workshop 8.1 and the .NET
Framework with WSE. From this, you should be able to draw a
few conclusions:

The same early adoption interoperability pain exists
today with emerging standards as existed when SOAP and WSDL
were first supported by various vendor platforms

Achieving WS-Security interoperability today begins with
vendor tools that simplify the process of generating complex
WS-Security constructs for authentication, encryption and
digital signatures; leads to comparing the underlying
serialized messages when problems arise; and ends with
verifying that XML against WS-Security specifications and
their predecessors to better understand the problem

The state of SOAP and WSDL today has proven to us that we
can achieve fantastic levels of interoperability as standards
stabilize and vendors ship their compliant implementations of
those standards that have been through several rounds of early
adoption feedback. So, achieving interoperability is about
more than just following a set of standards. It is about the
adaptability of each vendor platform, and their respective
ability to inject updates as standards evolve, and to provide
extensibility and configuration hooks that will allow early
adopters to overcome interoperability issues with greater
control.

In the coming months as the next generation of platforms
release for BEA and Microsoft respectively, we’ll see great
improvements in interoperability with this basic set of
WS-Security scenarios. However, that won’t be the end of our
security needs since issues of message bloating, key
management, and federated identity will demand the
implementation of other soon to be implemented standards
including WS-Trust and WS-SecureConversation with SAML.
Interoperability between these emerging security standards
will soon be the focus as WS-Security today stabilizes…so
brace yourself.

Download the code sample for this article at http://www.dasblonde.net/downloads/WSEBEAInteropTSS.zip.

Authors

Michele is a Chief Architect with IDesign, Microsoft
Regional Director for San Diego, Microsoft MVP for Web
Services and a BEA Technical Director. In addition,
Michele is a member of the board of directors for the
International Association of Software Architects (IASA).
At IDesign Michele provides high-end architecture
consulting services, training and mentoring. Her
specialties include architecture design for robust,
scalable and secure .NET architecture; localization; Web
applications and services; and interoperability between
.NET and Java platforms. Michele is a member of the
INETA; a frequent conference presenter at major
technology conferences such as Tech Ed, PDC, SD and Dev
Connections; conference chair for SD’s Web Services
track; and a regularly published author. Michele’s next
book is Windows Communication Framework Jumpstart for
O’Reilly, due out in early 2006. Reach her at
www.idesign.net or visit her blog at www.dasblonde.net.

News | Blogs | Discussions | Tech talks | White Papers | Articles | Media kit | About

All Content Copyright ©2005
TheServerSide Privacy Policy