OASIS Web Services Security - SOAP message security defines a standard way to attach security tokens to SOAP messages. In a multi-layered application, which digital identity should authenticate with the web service provider? Mario Guido Finetti guides you through the maze.
There are two ways to approach the problem, both of which have followers among packaged application vendors as well as custom web service developers. Let us take, for example, a very simple application made of two software components: a frontend web application and a backend service accessed by the web application via SOAP. The web application needs to authenticate with the backend service. The possible approaches are:
1. The credentials represent the web application
Our web application authenticates using a set of credentials that represent the web application itself. For example, a service account associated with the web application. If, in turn, the backend service provider needs to authenticate with another web service, it will use its own identity to do this.
2. The credentials represent the user of the application
In this case, the web application acts as a mere intermediary between the user and the web service. If, in turn, the backend service needs to authenticate with another web service, the credentials of the user will be propagated. Such propagation of user identity among the tiers of a complex application is generally called 'identity flow'. When the identity flow is implemented by transferring user's credentials like passwords or SSO tokens it is called 'credentials flow'.
This article describes the pros and cons of the two approaches and the solutions available if you need to implement a credentials flow while preserving platform independence and interoperability.
The 'trusted subsystem' approach
When following this approach, the web application authenticates with the downstream resource using its own identity. As far as user authentication is concerned, the backend service provider entirely trusts the frontend web application. The frontend web application must either check user's credentials against a directory service or verify that the user authenticated with an external identity provider.
The backend service might not even be aware of the identity of the end-user. If the identity is part of the data exchanged between the web application and the service, the service will be able to use this information and keep track of the user who originated the request. Otherwise, the web service is not aware of the identity of the user and all actions will be recorded as performed by the web application's service account. In either case, nor password nor any other kind of security token associated with the identity of the user is transmitted from the web service consumer to the web service provider.
Not sharing the identity of the user with the service provider may help you to design the backend service in a way that is completely independent from the design of the frontend web application thus increasing the chances that the backend service will be reused by different consumers in order to meet new business requirements. On the other hand, the service provider needs this information when it is the entity responsible for authorisation decisions regarding the user of the application. There is no point in replicating the authorisation logic in more than one place and the backend service could be that place.
Another good reason for sharing the identity of the end-user with the backend system is auditing. It is generally preferable to keep auditing in a single place rather than correlating information from different log files. A web service provider managing an approval workflow is a good example of both the authorisation and the auditing issues. The service provider needs to know the identity of the end-user because it first needs to check that the user is authorised to approve a specific resource and then in must keep track of the person who approved it.
However, sharing the identity of the user does not mean that you need to use user's credentials to authenticate with the backend service. The Simple Authentication and Security Layer specifications (RFC 4422) offer a clean example of this 'trusted subsystem' approach:
Authentication and authorisation may involve multiple identities, possibly in different forms. […]
The SASL framework involves two identities: firstly an identity associated with the authentication credentials (termed the authentication identity), and secondly an identity to act as (termed the authorisation identity). […]
The client provides its credentials (which include or imply an authentication identity) and, optionally, a character string representing the requested authorisation identity as part of the SASL exchange. When this character string is omitted or empty, the client is requesting to act as the identity associated with the credentials (e.g., the user is requesting to act as the authentication identity).
SASL goal is to provide an abstraction layer between authentication mechanisms and protocols like SMTP, LDAP and Liberty Alliance ID-WSF. These protocols are out of the scope of this article, but SASL definition of authentication and authorisation identities is valid in general and will be used in the next sections.
In practice, the trusted subsystem paradigm can be implemented in several different ways. As an example, the web service consumer could authenticate with the web service provider by means of digital certificates. The digital certificate is associated with the web service consumer itself, acting as the 'authentication identity'. The 'authorisation identity' is then attached to the SOAP messages exchanged between the service consumer and the service provider. It can be part of the body of the SOAP message, it can be attached as a WSS username token header or it can be attached as a digital certificate. Since it is an 'authorisation identity' and not an 'authentication identity', you will provide neither password nor any proof of possession of the private key associated with the digital certificate.
The integrity of the communications play a critical role in this architecture. You can either rely on SSL/TLS with mutual authentication (in this case, the certificate of the web service consumer acts as the client certificate) or you can use the certificates to sign and encrypt SOAP messages according to the WS-security specifications. The best approach is to use both, taking into account that SSL/TLS that does not allow you to put SOAP-aware intermediaries between the two parties involved in a SSL/TLS handshake. Complex architectures where SOAP-aware intermediaries are present require messages to be signed by the web service consumer and by the web service provider, while the SSL/TLS channel is terminated at each SOAP-aware intermediary.
Unfortunately, not all web service providers are smart enough to distinguish between 'authentication identities' and 'authorisation identities'. Existing packaged applications generally do not support this paradigm, even if they support SOAP and basic web services standards. Later in this article, the 'alternative identity flow' section explains how this problem could be worked around.
From a security perspective, the term 'trusted subsystem' may be slightly misleading. Even if you follow a different approach, the web service provider relies on the integrity of the web service consumer for a number of reasons, no matter how user authentication is performed. A compromised web service consumer, for example, could act as a man-in-the-middle between the user and the backend service, thus performing malicious action on behalf of a legitimate user. As a consequence, the web service consumer must always be trustworthy, both if you follow the 'trusted subsystem' approach and if you follow the 'credentials flow' approach.
On the other hand, the 'trusted subsystem' approach requires that the identity of the web service consumer is granted elevated privileges on the backend system. This is generally not required when following an alternative approach based on user credentials flow. This problem is not peculiar to web services technology. Web applications based on Microsoft IIS and SQL server, for example, used to implement a credentials flow from the frontend layer to the database layer in order to enforce user authentication, authorisation and accounting at every stage and avoid creating user accounts with elevated privileges. With traditional multi-layered applications, this approach is now getting less popular: it is more and more common to see DB servers only accessed by service accounts representing a 'trusted subsystem' rather than frontend application users.
The 'credentials flow' approach
As an alternative to the 'trusted subsystem' approach, the web service consumer could authenticate with the backend service provider by means of credentials that represent the user of the application. This means that the backend system is in charge of user authentication, authorisation and accounting. As mentioned above, the frontend web application plays a critical role in the security of the solution, even if you follow a 'credentials flow' approach. As a consequence, you generally need to authenticate both the web service consumer and the user of the application. For example, the web service consumer establishes a SSL/TLS session with the web service provider using its own digital certificate as a SSL/TLS client certificate. User credentials are then attached to the SOAP messages exchanged between the web service consumer and the web service provider as WS-security headers.
A solution based on credentials flow is practical when the frontend web application is only responsible for translating client requests into SOAP messages without adding much information. On the other hand, credentials flow is difficult to implement while preserving interoperability among service consumers and service providers based on different platforms. The next sections describe some solutions.
Identity flow based on user passwords or proprietary SSO tokens
Perhaps, the worst option for flowing user identity among the layers of a distributed application is using user's password to authenticate web service consumers with the backend service providers. A solution of this kind tightly couples all the systems involved in the identity flow to the user authentication mechanism. Introducing two factor authentication, for example, is very difficult if users passwords are used to implement an identity flow.
Using proprietary single sign-on tokens is a better option, assuming that a web single sign-on system is in place. The proprietary SSO token is generated when the user first authenticates with the SSO system and it is recognised by all the web applications that trust the SSO system. The SSO token is generally wrapped in a HTTP cookie that clients send to the web applications in order to be recognised without any additional authentication request. A web application can use the SSO token to authenticate with the backend service, if the backend service trusts the SSO system. This way, the identity of the user will flow from the frontend to the backend systems.
The main problem with this solution is that you lose interoperability. Web services will be consumed only by the applications that can provide the proprietary SSO token. All service providers need to be able to decrypt and recognise the proprietary SSO token. This will either limit your options in terms of development platform (e.g. the proprietary SSO token is only recognised by a particular family of application servers) or require the deployment of an agent on each service provider (e.g. an agent from the SSO system vendor).
Identity flow based on Kerberos tickets
OASIS WS-Security explains how to encode and attach a Kerberos ticket to a SOAP message for authentication purposes. This approach is very similar to the abovementioned proprietary SSO token solution except for the fact that both Kerberos and the WSS Kerberos Token profile are consolidated standards. This allows interoperability among different platforms. Unfortunately, a solution based on Kerberos authentication does not allow different organisations to share services across internet.
Identity flow based on SAML assertions
A SAML assertion is a collection of statements about a subject including his user ID, when he was authenticated and possibly his entitlements. The SAML assertion is generally signed by a trusted entity responsible for subject's authentication, called Identity Provider. WSS SAML token profile explains how to attach a signed SAML assertion to a SOAP message.
If the SAML assertion is valid and the service provider trusts the entity that signed it, the SOAP request should be treated as if it was originated by the user of the web application. Unlike Kerberos, SAML was born to allow different organisations to share services across internet.
To implement a SAML-based architecture you need to clearly identify, at least, the entities below within your architecture:
· The identity provider: a trusted entity that is responsible for authenticating users
· The service providers: applications or web services responsible for providing a particular service. SAML allows you to implement them without caring about the specific authentication mechanism implemented by the Identity Provider. This is one of the great values of using SAML
· Web service consumers. They need to access protected resources, possibly acting on behalf of an end-user
· End-users. They could either belong to the same organisation that is providing them with the service or they could belong to a different organisation.
To achieve interoperability among all these entities, an agreement on the format of the SAML assertion is required, but it is not enough. All these entities need to share standards on how to interact in order to produce and consume SAML assertions. While SAML assertion format is regulated by a consolidated and widely accepted standard, the protocols responsible for regulating the abovementioned interactions were finalised recently. For example, a successful SAML 2.0 protocol interoperability test among the major software vendors was completed in September 2009 (see links section for details). Similar tests will follow on other specifications, including the WS-Trust family (WS-Trust, WS-Security Policy, WS-Secure Conversation) that regulates the way in which web service consumers collect SAML assertions.
Alternative identity flow solutions
If the web service provider is not smart enough to support the abovementioned solutions, you need to consider alternative approaches. A common solution consists in introducing a new security layer on the service provider side that can deal with any of the abovementioned authentication solutions and then force the service provider to treat SOAP requests as if they were sent by the end-user of the application.
This task is not trivial and, above all, there is a potential for creating a security flaw. Following the best practices for secure coding is critical during the development of a solution of this kind. In particular, the design and the code should be reviewed by an independent team with the appropriate skills.
The technical solution very much depends on the specific architecture of the service provider. Let us take, as an example, a Windows-based application relying on Active Directory for authentication. Windows 2000 did not allow you to programmatically impersonate a user unless you had either his password or a valid Kerberos ticket. Therefore, this approach was not feasible unless incoming SOAP requests included a Kerberos ticket.
Windows 2003 introduced a new option. A piece of code running with 'act as part of the operating system' privileges is allowed to programmatically impersonate an Active Directory user without providing user's password. However, this approach is not encouraged by Microsoft: “Where possible, you should avoid this approach because an attacker who manages to inject code and compromise your web application will have almost unrestricted capabilities on the local computer.”
Recently, Microsoft introduced a service called 'Claims to Windows Token Service (C2WTS)' as part of the Windows Identity Foundation (.NET framework 3.5 SP1). This service allows you to programmatically impersonate a Windows user who was successfully authenticated by means of SAML assertions.
Putting it all together
The solutions described in this article all belong to one of the four classes below.
1. Trusted Subsystem approach without identity flow. The service consumer authenticates with the service provider by means of a service account representing the web service consumer itself. The web service provider is not aware of the identity of the end-user of the application.
2. Trusted Subsystem with identity flow. The service provider is smart enough to distinguish between an 'authentication identity' and an 'authorisation identity'. The 'authentication identity' is associated with authentication credentials (e.g. digital certificates), while the 'authorisation identity' is not associated with any security token. As far as authorisation is concerned, the service provider should handle SOAP requests as if they were originated by the 'authorisation identity'.
3. Credentials flow with Web service consumer authentication. Both the web service consumer and the end-user of the application authenticate with the web service provider.
4. Credentials flow without Web service consumer authentication. The web service consumer acts as a mere intermediary between service and users while the web service provider trusts the security tokens presented by the users of the application.
In my opinion, all scenarios can be implemented according to best security practices. Typically, the same recommendations apply, no matter which solution you choose. For example, it is critical that the authorisation logic is based on a declarative framework, rather than being hard coded in the application code. It is also critical that communications are properly encrypted, that keys and certificates are properly managed and so on. Highly privileged service accounts represents a potential threat that is peculiar to the trusted subsystem approach. However, this threat can be mitigated using certificate-based authentication. Digital certificate authentication does not require secrets to be exchanged manually, thus reducing the chances that secrets are stolen.
In a complex scenario where services and consumers are based on different platforms, the decision on which approach to implement is not driven by security considerations only. Interoperability requirements as well as technological constraints coming from the resources to be integrated play an important role. Enforcing security while preserving interoperability is perhaps one of the biggest challenges in a Service Oriented Architecture initiative.
Mario Guido Finetti works as an ICT program manager at Eni Spa (www.eni.com). He is mainly focused on application level security, IAM, SOA and configuration management.
Web Services Security – SOAP message security
Interoperability test: WS-I Basic Security Profile 1.1
Interoperability test: SAML 2.0 protocol
Interoperability test: Kantara initiative
A paper on Trusted Subsystem Design (Microsoft)
The Trusted Subsystem design pattern (Microsoft)
Claims to Windows Token Service (Microsoft)