February 27, 2012

SAML tokens and WS-Trust Security Token Service (STS)

I've been working actively in the Apache CXF community with respect to SAML tokens and the WS-Trust SecurityTokenService (STS) since Talend's donation of the STS to the community. I've noticed in various WS-Trust projects that there is a lack of documentation about the different use cases for SAML tokens and the WS-Trust STS.

I'll give a brief introduction into SAML and STS before bringing the two together.


SAML


SAML is an OASIS standard and consists of several specifications. A SAML token is issued by an identity provider. A service provider relies on the identity provider to authenticate a principal (a user). The SAML assertion is provided to the service provider allowing it to make an access control decision. The main problem SAML tries to solve is Web Single Sign On.

There is a clear layering between the SAML specifications thus they can be fairly easy reused in other contexts. Another context besides Web SSO is Web Services communication - which I'll be covering here. Therefore, we only need to look into the SAML Core specification as it describes the syntax and semantics of SAML assertions. The SAML protocols are covered by SAML core too but there are not relevant for Web Services communication. This is also the case for the SAML bindings (how SAML messages are transmitted from one system entity to another) as well as for SAML profile which describes use cases for Web application Single Sign On.

A SAML assertion (also known as SAML security token) contains different kinds of statements: authentication-, attribute- and authorization decision statements. The "authorization decision statement" became deprecated in SAML 2.0 specification as it is covered in XACML and in claims based authorization based on standard SAML attribute statements. The former is quite complex whereas the latter provides already good options for fine grained authorization at less complexity. You can find more information about the latter here.


A SAML assertion contains a subject which identifies the principal. The subject can also contain additional information like key material and the subject confirmation method. One of the main topics in this blog are the different kind of subject confirmation methods and how they correlate to an STS.


As a side note, the subject confirmation method is not defined in the SAML core. Instead, the SAML profile specification defines the following three subject confirmation methods:
  • Holder of Key (HOK)
    The subject must contain key material so the service provider is able to validate that the requestor is in the possession of the key(s)
  • Bearer
    The subject doesn't contain key material and it is up to the service provider to accept the assertion or not
  • Sender vouches (SV)
    The subject doesn't contain key material and it is up to the service provider to accept the assertion or not. The requestor and the identity provider are usually the same.

For more information about SAML I recommend Wikipedia and the documentation at the OASIS committee.

Web Services and SAML

SAML in the context of Web Services is standardized in the SAML token profile here. It describes on the one hand how a SAML token is embedded in a SOAP message and on the other hand what kind of requirements must be met dependent on the SAML version and subject confirmation method.


I can highly recommend the following web services security usecases from OASIS as it describes very interesting use cases by combining transport level and message level security (ex. SAML HOK is very complex and has a performance impact as XML signature is required. This document describes how to use mutual SSL handshake for the proof-of-possession processing)

In 2011, many new security features have been added to CXF. Check the following blog for more information.



WS-Trust STS


The WS-Trust standard introduces a runtime component called Security Token Service (STS). A service consumer requests a security token from the STS which is sent to the service provider. Either the service provider can validate the security token on its own or sends a request to the STS for validation. This pattern is based on an indirect trust relationship between the service provider and the STS instead of between the service provider and service consumer. As long as the service consumer is in the possession of a security token issued by a trusted STS, the service provider accepts the token sent by the service consumer. This is the same pattern as for certificates and certificate authorities. This approach has significant advantages compared to a direct (brokered) trust established between a service provider and service consumer. The specification is an OASIS standard and can be downloaded here.

The STS can issue security tokens based on requirements provided by the service consumer and/or service provider. The requirements of the service provider are either expressed in a WS-Policy document according to WS-SecurityPolicy or out-of-band agreement.


A key benefit of the STS is the reduced complexity for web service consumer. A web service consumer doesn't have to know how to create the various types of security tokens its service providers require. Instead, it sends a request to the STS containing the requirements of the client and the service provider and attaches the returned security token to the outgoing SOAP message to the service provider. One service provider could require a SAML 1.1 token, another a SAML 2.0 token and another a custom binary security token. The service consumer doesn't have to understand SAML 1.1, SAML 2.0 or the custom binary security token. All he has to do is grab the returned token from the STS and attach it to the message. Thus, you can reduce the complexity in your application and move it to a centralized component.


How does a web service consumer know whether it has to go to an STS to request a token? The policy of the service provider contains an IssuedToken assertion with some additional information like the address of the STS, token type, claims, etc.


Now, it's time to explain a few parameters of the request (RST) to the STS.


TokenType
specifies the type of security token requested (ex. SAML 1.1, 2.0, X.509, ...). URIs are defined for all standard security tokens.

KeyType
specifies the type of key desired in the security token. There are three URIs defined:
  • PublicKey
  • SymmetricKey
  • Bearer

Claims
specifies the required and optional claims in the security token. A claim can be the email address, role information, country, etc.


AppliesTo
specifies the scope for which the security token is required. This can be the URL of the service provider.


Lifetime
specifies the creation and expiration time of the security token. The STS is not obligated to honor this range.

These parameters can be retrieved from the WS-SecurityPolicy document also. In that case, they are added as child elements of the SecondaryParameters element in the RST.



SAML and STS 


How does a SAML token and the parameters sent to the STS match with each other. How does the STS know which subject confirmation method should be used? OK, let's start with the more obvious one.

1) TokenType
the token type is either SAML 1.1 or SAML 2.0. The STS creates the corresponding SAML assertion

2) AppliesTo
the AppliesTo element defines the scope and thus match to the SAML AudienceRestriction element in the SAML condition

3) Lifetime
the value of the lifetime or the lifetime choosen by the STS matchs to the SAML conditions NotBefore and NotAfter

4) Claims
the claim values maps to a SAML attribute statement. It's standardized here how claims are encoded as a SAML attribute statement. You can get more information about claims here.


How is the trust between the service provider and the STS established? This is fairly easy. The SAML assertion is signed by the STS. The signing certificate must be configured in the service provider to be trusted.


But how can the STS know whether the subject confirmation method should be HoK, SV or Bearer.
If the KeyType contains the value PublicKey or SymmetricKey, the subject confirmation method is Holder-Of-Key.
If the KeyType contains the value Bearer, the subject confirmation method is Bearer.

The benefit of HoK is that even if somebody gets into the possession of a SAML token he can't 
send requests masquerading as the subject in the SAML token as he doesn't know the key (symmetric or private key). However SAML tokens with Bearer subject confirmation method must be protected. In most cases, Bearer combined with HTTPS is sufficient to prevent that "a man in the middle" can get into the possession of the SAML token.

The subject confirmation methods Bearer and Holder-Of-Key are widely used for all STS use cases as well as for Web Single Sign On in WS-Federation Passive Requestor Profile and SAML Post Profile.


OK, what about sender-vouches? Even it is not clearly stated it makes no sense to request a SAML token from an STS with sender-vouches subject confirmation method.


You might know this paper from IBM which describes how to get a SAML token from the STS with sender-vouches. Even though it's from IBM, I won't change my opinion ;-)

Let's step back once and have a look what the differences are between a SAML token with subject confirmation method Bearer and Sender-Vouches. Utlimately, it is just a string in the ConfirmationMethod element. Of course, an STS can put the string for Sender-Vouches into the SAML token - not a big deal.

The WS-Security SAML token profile defines the processing rules for HoK and Sender Vouches. In the case of Sender-Vouches it says that the attesting entity, (presumed to be) different from the subject, vouches for the verification of the subject. The receiver MUST have an existing trust relationship with the attesting entity. The attesting entity MUST protect the assertion in combination with the message content against modification by another party. The trust is established based on certificates where the attesting entity (service consumer) creates a signature which protects the SAML token and the SOAP body. The service provider verifies the signature to have the confirmation that nobody made changes either to the token or the SOAP body. The receiver (service provider) must have imported the certificate of the service consumer.
A SV SAML token itself is not signed in contrast to Bearer and HoK because there is no third party like an STS. It wouldn't make sense for an STS to issue unsigned SAML tokens as there would be no way to protect against other entities adding additional statements.

Therefore, Sender-Vouches doesn't make sense in the context of STS.

Where is SAML Sender-Vouches used? I blogged about this topic here.


February 6, 2012

Configure Fediz IDP and ASP.NET using WIF

Fediz provides different components to support single sign on and claims based authorization for web applications based on WS-Federation. As described here, the IDP/STS is the central component which authenticates users and issues security tokens (ex. SAML) which includes information about the authenticated identity, their keys and claims. The other component is deployed within the relying party, the web application. How you can enable WS-Federation for Tomcat is described here.
What about other technologies like Microsoft. WS-Federation is supported by Microsoft out-of-the-box by the Windows Identity Foundation (WIF). ASP.NET supports similar extension points like Tomcat to intercept and customize request processing and authentication. The counterpart of a Tomcat Valve is a .NET HttpModule.

WIF is a .NET assembly (DLL) which provides http modules, new config section and other stuff. Thus, you can enable WS-Federation for your ASP.NET based web application by configuration. There is a very good post about WIF and ASP.NET here. There is also a Visual Studio extension to generate a mock IDP based on ASP.NET and WIF but it doesn't have the functionality supported by the mock IDP as part of Fediz. You can create test users and assign any kind of claims to each users thus you can easily test your claims based ASP.NET web application. IMHO, there is another reason, isn't it cool to show how interoperable .NET and Java is !?

You can re-use the updated IDP provided here.

The following steps are required to use this mock IDP in your ASP.NET web application.

1. Deploy Windows Identity Foundation

You can download WIF here and install it. Finally, you only have to deploy the Microsot.IdentityModel.dll‎ to your bin directory of the web application.

 

2. Import the IDP/STS certificate in the Microsoft certificate store
You can get more information about the Microsoft certificate store here.
The relying party must establish a trust with the IDP/STS. This is achieved by trusting the certificate which was used to sign the SAML token. Windows and .NET have their own certificate store and doesn't understand a Java keystore (JKS). Therefore, we have to export the certificate in the JKS in a platform neutral format like PEM. You have to run the following command:

keytool -exportcert -alias mystskey -keystore stsstore.jks
-storepass stsspass -rfc -file sts.pem

Import the certificate file sts.pem into the store as described here.

Ensure that you import the certificate into the "Trusted People" store.


You are able to click on the certificate you imported before. The value of the field "Thumbprint" is required to establish the trust to the IDP within the relying party.






3. Configure WIF in web.config


Different sections of the web.config must be updated. First, you must configure the new config section for WIF:


   <configSections>
      <section name="microsoft.identityModel"
         type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   </configSections>


Second, configure the http modules:

   <system.web>
      <httpModules>
         <add name="SessionAuthenticationModule"
            type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
         <add name="WSFederationAuthenticationModule"
            type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </httpModules>

Disable default authentication/authorization. Instead, the above http modules will handle authentication and authorization:

      <authentication mode="None" />
      <authorization>
         <deny users="?" />
      </authorization>


Configure WIF:


   <microsoft.identityModel>
      <service saveBootstrapTokens="true">
         <issuerNameRegistry      type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <trustedIssuers>
               <add thumbprint="977f0c1c0a2e9534d310a8e05380f5653524ca3f"
                  name="https://b0d0ma02.ch.zurich.com:16050/fedizidp/" />
            </trustedIssuers>
         </issuerNameRegistry>
         <certificateValidation
            certificateValidationMode="PeerTrust" revocationMode="Online"
            trustedStoreLocation="LocalMachine" />
         <audienceUris>
            <add value="https://teinf0095.emea.zurich.test/helloworld/" />
         </audienceUris>
         <federatedAuthentication>
            <wsFederation passiveRedirectEnabled="true"
               issuer="https://b0d0ma02.ch.zurich.com:16050/fedizidp/"
               realm="https://teinf0095.emea.zurich.test/helloworld/"
               requireHttps="true" />
            <cookieHandler requireSsl="false" name="FedAuth"
               hideFromScript="true" path="/helloworld" />
         </federatedAuthentication>
      </service>
   </microsoft.identityModel>



I'd like to highlight the following pieces in the section "microsoft.identityModel".

1) issuerNameRegistry
add the thumbprint to the issuerNameRegistry


2) audienceUris
add the valid uri's which must match with the audience restriction in the SAML token


3) federatedAuthentication
configure the URL of the IDP in the attribute "issuer" and the realm for the application. The realm matches with the audience restriction finally.




More information about WIF configuration can be found here.
That's it. You are ready for testing...


4. If it doesn't work...

1) A generic exception is returned by the .NET application without indicating the root cause.


There should be an error logged in the Microsoft Event Viewer (Administrative Tools) for the log type "Application".


2) SecurityTokenValidationException is returned by the application


exception details:
[SecurityTokenValidationException: The X.509 certificate E=sts@sts.com, CN=www.sts.com, OU=IT Department, O=Sample STS -- NOT FOR PRODUCTION, L=Baltimore, S=Maryland, C=US is not in the trusted people store.]


Certificate not imported into the Microsoft Certificate store (Trusted People store. See section 2.


3) SecurityTokenException


exception details:
[SecurityTokenException: ID4175: The issuer of the security token was not recognized by the IssuerNameRegistry. To accept security tokens from this issuer, configure the IssuerNameRegistry to return a valid name for this issuer.]


Certificate not trusted. Ensure that the correct thumbprint is configured in web.config.