SSO Services

These services require the client to first authenticate with the eHealth STS. The ticket of the STS can then be reused to authenticate itself with different services.

Introduction

The service uses SSL (https) to ensure the confidentiality and integrity of the message. Confidentialy means only the client and service can read the message while integrity means that the sender is sure the messages arrives unaltered at the service. The identify of the caller if verified by an signature and a Holder-Of-Key SAML-AttributeAssertion. Unfortunately the configuration of eHealth is incompatible with WCF by default.

Security in WS-* Terms

While WS-SecurityPolicy does define issued tokens, it requires WS-Trust to acquire them. Unfortunately WS-Trust isn't the best fit for the kind of services that are offered via eHealth. SSO means that the received token must be as re-usable as possible, in practice WS-Trust focuses on the automatic issuing and not on the re-usability of the tokens. Therefore the issuing of tokens is done via SAML-Protocol (not a WS-* Standard) and the services simply require a SAML-Token (instead of an issued token that is of type SAML). This means more manual actions, but this is handled by this library.

Security Token Service (STS)

The STS a regular MSO Service (security wise) that implements the SAML-Protocol. The implementation of the SAML-Protocol allows the issuing of a assertion that contain attributes. These attributes represent the claims about the users that are verified by eHealth. The library provides a custom client "StsClient", currently this client is directly used by the SSO Binding (see below) but you can also use it standalone. For the moment it isn't possible to manually provide the ticket to the SSO Binding, but it will be in the future.

When using the StsClient directly you must provide a set of information
  • Package name, used in the request
  • Session certifcate (aka HOK certficate) with private key
  • Period or the requested duration of the issued token
  • List of claims that you provide to eHealth (which it will validate)
  • List of claims that you request eHealth to provide for you

The claims that you provide to eHealth are in xml form and should be complete "saml:Attribute"-elements. The actual values of this and other parameters are out of scope of this library. See the various eHealth documentation for more information about this.

The response is also in XML format and the exact (non formatted to preserve the signature) content of the SAML-Protocol response. This should be an SAML assertion. In case there is an error, this includes SOAP faults and errors defined by the SAML-Protocol, an exception is thrown. A non exclusive list is
  • SOAP Exception: FaultException
  • SAML-Protocol error: SamlFault

The SSO Service

The SSO Service requires a SAML-Token as provided by eHealth, buth that isn't all. Since it is a HOK SAML-Token the request must also be signed with the private key that corresponds to the certificate in the SAML-Token. The requirements of this signature are basically the same as for MSO Services as was the solution, the only difference is that it must not sign itself. Off course, it did require a lot of extra.

To avoid a lot of redundant code, the configuration and binding inherits from the WS Federation Http Binding. Warning, it isn't just an extension of the binding, it alters certain parts and greatly limits the capabilities because they aren't applicable for eHealth. The result can be found in the SsoBinding class.

Specifying the binding isn't enough, you must also specify a custom client credential: SsoClientCredentials. This will make sure that our own version of the token provider, the SsoSecurityTokenProvider is used. This provider will then use the STS client to retrieve the token. Currently this token provider isn't very configurable yet, while we improve this you will most likely have to adapt this code to suite your needs.
The few thinks that are configurable in the token provider can be configured with a custom binding SessionBinding. Actually, there isn't a default yet, so the session binding is required.

Adding Service Reference

Adding a reference can be done in your favorite way. Warning the generated code must be addapted each time you (re)generate the code!

Locate the ServiceContractAttribute in the generated code and add the ProtectionLevel = ProtectionLevel.Sign property.

Example:
[ServiceContractAttribute(ProtectionLevel = ProtectionLevel.Sign, Namespace = "nnn", ConfigurationName = "ccc", Name = "sss")]
public interface XxxPortType {
   //snip
}

Configuration

The clients should use the custom defined SsoBinding. This binding does require the same configuration as WSFederationHttpBinding. It should also use the SSOClientCredentials instaid of the standard client credentials and have an additional SessionBinding.

Via app.config/web.config

In the app.config or web.config the configuration looks as follows

<configuration>
  <system.serviceModel>
    <extensions>
      <bindingExtensions>
        <add name="stsBinding" type="Siemens.EHealth.Client.Sso.Sts.Configuration.StsBindingCollectionElement, Siemens.EHealth.Client"/>
        <add name="ssoBinding" type="Siemens.EHealth.Client.Sso.Configuration.SsoBindingCollectionElement, Siemens.EHealth.Client"/>
      </bindingExtensions>
    </extensions>
     <ssoBinding>
        <binding name="s1">
          <security mode="Message">
            <!-- The following attributes must be set as is, other values aren't supported -->
            <message issuedKeyType="AsymmetricKey" negotiateServiceCredential="false"  establishSecurityContext="false">
              <!-- Specify here the address of the eHealth STS (see eHealth doc), the binding must always be stsBinding -->
              <issuer address="https://www.ehealth.fgov.be/sts_z_z/SecureTokenService" binding="stsBinding" />
              <tokenRequestParameters>
                <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" AttributeNamespace="sss" AttributeName="nnn">
                  <saml:AttributeValue xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">vvvv</saml:AttributeValue>
                </saml:Attribute>
                <!-- More provided claims in exact xml format here... -->
              </tokenRequestParameters>
              <claimTypeRequirements>
                <add claimType="{sss}nnn"/>
                <!-- More requested claims in "{namespace}name" format here... -->
              </claimTypeRequirements>
            </message>
          </security>
        </binding>
    </ssoBinding
    <client>
      <endpoint address="https://hhh/zzz" binding="SsoBinding" bindingConfiguration="s1" behaviorConfiguration="b1" contract="xxx" name="yyy"/>
    </client>
    <behaviors>
      <endpointBehaviors>
         <behavior name="b1">
          <!-- Specify our custom client credentials via the standard client credentials behavior with an extra attribute -->
          <clientCredentials type="Siemens.EHealth.Client.Sso.SsoClientCredentials, Siemens.EHealth.Client">
            <!-- Reference the certificate that will be used for authentication, this is in general your eID certificate -->
            <clientCertificate storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" findValue="iii"/>
          </clientCredentials>
          <session duration="1:0:0:0">
            <!--  Reference the certificate that will be used a session (HOK) certificate, this is in general your eHealth certificate, but self signed are also possible (rare cases) -->
            <sessionCertificate selfSigned="false" storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" findValue="eee"/>
          </session>
        </behavior>
      </endpointBehaviors>
  </system.serviceModel>
</configuration>

Via code

SsoBinding ssoBinding = new SsoBinding();
//Override the required settings
ssoBinding.Security.Mode = WSFederationHttpSecurityMode.Message;
ssoBinding.Security.Message.IssuedKeyType = SecurityKeyType.AsymmetricKey;
ssoBinding.Security.Message.NegotiateServiceCredential = false;
ssoBinding.Security.Message.EstablishSecurityContext = false;
//Set the STS address (see eHealth document) and STS binding
ssoBinding.Security.Message.IssuerAddress = new EndpointAddress("https://www.ehealth.fgov.be/sts_z_z/SecureTokenService");
ssoBinding.Security.Message.IssuerBinding = new StsBinding();
ssoBinding.Security.Message.IssuedTokenType = SecurityTokenTypes.Saml;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<saml:Attribute xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" AttributeNamespace=\"sss\" AttributeName=\"nnn\">" +
   "<saml:AttributeValue xsi:type=\"xs:string\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">vvv</saml:AttributeValue>" +
   "</saml:Attribute>");
ssoBinding.Security.Message.TokenRequestParameters.Add(doc.DocumentElement);
//More provided claims in exact xml format here... 
ssoBinding.Security.Message.ClaimTypeRequirements.Add(new ClaimTypeRequirement("{urn:be:fgov:identification-namespace}urn:be:fgov:kbo-cbe:cbe-number"));
//More requested claims in "{namespace}name" format here... 
XxxClient kgssClient = new XxxClient(ssoBinding, new EndpointAddress("https://hhh/zzz"));
//Replace the standard client credentials with the sso client credentials
XxxClient.Endpoint.Behaviors.Remove<ClientCredentials>();
XxxClient.Endpoint.Behaviors.Add(new SsoClientCredentials());
//set the required cert, normaly the eID
XxxClient.ClientCredentials.ClientCertificate.Certificate = cert1; 
//Add the session behaviour, specifying the certificate (normaly the eHealth certficate) and the timespan for which the session should be requested
XxxClient.Endpoint.Behaviors.Add(new SessionBehavior(cert2, new TimeSpan(1, 0, 0)));

Last edited Dec 2, 2010 at 3:58 PM by egelke, version 4

Comments

No comments yet.