Atomia Identity

Identity delegation

27 views 0

Overview

Use of WCF services with Atomia Identity 1
Use of WCF services with Atomia Identity 2

Image 1: Use of WCF services with Atomia Identity authorization.

This part is for developers of web applications who want to use WCF services with Atomia Identity authorization. It will show you how a web application can issue calls to WCF service with the privileges of the user who authenticated to that web application. This mechanism is called Identity Delegation . In the Identity Delegation mechanism, web application is able to use WCF by providing the appropriate SAML token to the WCF service.

This token should contain:

  • identity claims and
  • delegation information

Web application configuration for identity delegation

Step 1:  Adding a service reference

Add a service reference to the Web application

Add service reference

Image 2: Add service reference.

After adding a service reference to the web application, the web.config file is automatically updated – we have a new section withinconfiguration :

<system.serviceModel>
<bindings>
<wsFederationHttpBinding>
<binding name="WSFederationHttpBinding_IUcpCoreService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message algorithmSuite="Default" issuedKeyType="SymmetricKey"
negotiateServiceCredential="true">
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
isOptional="false" />
<add claimType="http://schemas.microsoft.com/ws/2006/04/identity/claims/role"
isOptional="true" />
</claimTypeRequirements>
<issuer address="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/username/" />
<issuerMetadata address="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/mex" />
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<client>
<endpoint address="http://t098/UCP/UcpCoreService.svc" binding="wsFederationHttpBinding"
bindingConfiguration="WSFederationHttpBinding_IUcpCoreService"
contract="UcpCoreService.IUcpCoreService" name="WSFederationHttpBinding_IUcpCoreService">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAAkI...." />
</identity>
</endpoint>
</client>
</system.serviceModel>

Step 2: Configuring web.config

We need to adjust Web Application’s web.config file in order to use Token delegation to the WCF service. First, we need to change the issuer section within the security->message tag in our binding section – our web application will be authenticated on the STS via certificate instead of username/password combination. So, instead of:

<issuer address="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/username/" />

we should have this kind of section:

<issuer address="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/cert/" binding="wsHttpBinding" bindingConfiguration="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/cert/">
<identity>
<certificate encodedValue="MIIByzCCATSgAwIBAgIQ2PtXByKML5dI68y5...." />
</identity>
</issuer>
XML SECTION PROPERTY DESCRIPTION EXAMPLE
identity-> certificate encodedValue The certificate (public key) web application is using to sign and encrypt messages to STS (can be found at STS’s wsdl) MIIByzCCATSgAwIBAgIQ2PtXByKML5dI68y5….

Since we’re specifying the way of communication between the web application and the STS via the binding and bindingConfiguration attributes, we need define this binding within the bindings section:

<wsHttpBinding>
<binding name="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/cert/" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>

In the above example, the following part defines that the web application will be authenticated at the STS via its own certificate:

<security mode="Message">
<message clientCredentialType="Certificate" />
</security>

Step 3: Defining location of application certificate

The next thing we need to do is to define where web application’s certificate can be found. Let’s add behaviorConfiguration=”ClientCertificateBehavior” attribute to the <endpoint> tag of our WCF service:

<endpoint address="http://t098/UCP/UcpCoreService.svc" behaviorConfiguration="ClientCertificateBehavior"
binding="wsFederationHttpBinding" bindingConfiguration="WSFederationHttpBinding_IUcpCoreService"
contract="UcpCoreService.IUcpCoreService" name="WSFederationHttpBinding_IUcpCoreService">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAAkI0urWJG...." />
</identity>
</endpoint>

Then we add a behaviors section above the client section:

<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="My web application" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>

where the following setting needs to be adjusted

XML SECTION PROPERTY DESCRIPTION EXAMPLE
clientCertificate findValue A string in the X.509 certificate store that contains the certificate used for authenticating web application at the STS My web application

Step 4: Modifying the service certificate

The last thing we need to do is to modify the serviceCertificate within microsoft.identityModel section in the web.config file:

<serviceCertificate>
<certificateReference x509FindType="FindBySubjectName" findValue="Your Application Name" storeLocation="LocalMachine" storeName="My"/>
</serviceCertificate>

Change the following properties :

XML SECTION PROPERTY DESCRIPTION EXAMPLE
serviceCertificate-> certificateReference findValue A string in the X.509 certificate store that contains the certificate STS for encrypting the issued tokens for the web application Your Application Name

Example of system.serviceModel section

The following is an overview of what the web.config system.serviceModel section should look like:

<system.serviceModel>
<bindings>
<wsFederationHttpBinding>
<binding name="WSFederationHttpBinding_IUcpCoreService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message algorithmSuite="Default" issuedKeyType="SymmetricKey"
negotiateServiceCredential="true">
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
isOptional="false" />
<add claimType="http://schemas.microsoft.com/ws/2006/04/identity/claims/role"
isOptional="true" />
</claimTypeRequirements>
<issuer address="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/cert/" binding="wsHttpBinding" bindingConfiguration="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/cert/">
<identity>
<certificate encodedValue="MIIByzCCATSgAwIBAgIQ2PtXByKML5dI68y5ADms+DANBgkqhkiG9w0BAQUFADAkMSIwIAYDVQQDExlVQ1AgQXV0aG9yaXphdGlvbiBTZXJ2aWNlMB4XDTA5MDYwMTExMDEyOFoXDTM5MDYwMTExMDEyOFowJDEiMCAGA1UEAxMZVUNQIEF1dGhvcml6YXRpb24gU2VydmljZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAkT+edt1kwnjNE0JU0Yq4n2WHz/NK3O5a4h6V7kfG3D1iixvPEqzgbCaNw8OpM6+lLEMFoFvTRIMhSr3vM7Y9AxaoaXCY8oQ9oJgnK6XEnuh4zh234jAFokkvkiUx1t/E/J6vAgGmTdm84SrAK+0Lc7pONW8qnNnJzv18EglVkrcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAYlziJ46RFEWtarXbZlscFAOwyu8VQaafKrNLTMDfvv9i1rVCHeQZZK9DmyWHsgtreinVXr09Sio8djaKIroPXBod6HaeRLKaJT8xlqTJncc3zUn+NCNEDGr1OXcyeuldd3ckTZRzc9Up7jIi1kQjDnfe3A51IRGYc2dX9WwWE7Q==" />
</identity>
</issuer>
<issuerMetadata address="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/mex" />
</message>
</security>
</binding>
</wsFederationHttpBinding>
<wsHttpBinding>
<binding name="http://localhost/AtomiaIdentityStS/AtomiaSts.svc/cert/" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="Atomia Web Frame" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://t098/UCP/UcpCoreService.svc" binding="wsFederationHttpBinding"
bindingConfiguration="WSFederationHttpBinding_IUcpCoreService" behaviorConfiguration="ClientCertificateBehavior"
contract="UcpCoreService.IUcpCoreService" name="WSFederationHttpBinding_IUcpCoreService">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAAkI0urWJGQQsCDdWMWI4QlfxNP6kgAAAAAQAAAK0BAAAwggGpMIIBEqADAgECAhApKYqxXRgmq0D335zyfiZeMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNVBAMTCFVDUCBDb3JlMB4XDTA5MDYwMTExMDEyOVoXDTM5MDYwMTExMDEyOVowEzERMA8GA1UEAxMIVUNQIENvcmUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMqLb1jz9bB2AZpnASVmvxCB4iWxBb1IbvmPwfPDJTVuvbvAtihO34lt77z4SNa8ivxUOi1EFsj7V8DBiHGHiCc8Cgp6B2WT6fiOaKUXHKWHbEqVNfi6fKYidfjXtK6axIZH3sw1rceGYIHCHNO3n/Iq7Av7vNVU9GSAMhZ2qQqVAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAMJFJWpNirhnHhzws7O80V3dvV0XHWuhJIeGg8Ds35MUNO4y4K2aE/l9QtzH8De3+TECarAOabaD3iz8K+aBqgem1VfkIB+bWgckRYkdwimCpGuxKqSDO9xEOcSaQitUphmj63as/ddi7ccUTlHAGwtLMRJcD4iHiA144w3sD+Ms=" />
</identity>
</endpoint>
</client>
</system.serviceModel>

Web application code changes for Identity delegation

There are a few things that need to be done in the code in order to use the Identity delegation.

  1. Open the Global.asax.cs of your web application.
    public static readonly string CachedChannelFactory = "WFE_CachedChannelFactory";
    void SessionAuthenticationModule_ConfigurationLoaded(object sender, EventArgs e)
    {
    ChannelFactory<UCPAuthPrototype.WebMvcApplication.CoreService.ICoreService> service2CF = new ChannelFactory<UCPAuthPrototype.WebMvcApplication.CoreService.ICoreService>("WSFederationHttpBinding_ICoreService");
    FederatedClientCredentials.ConfigureChannelFactory<UCPAuthPrototype.WebMvcApplication.CoreService.ICoreService>(service2CF);
    Application[CachedChannelFactory] = service2CF;
    }
    
  2. Copy the code above.
    1. Here we initialize the ChannelFactory instance for the service we will use. In UCPAuthPrototype.WebMvcApplication.CoreService.ICoreService you provide the proxy class of your service.
    2. Put that instance in the global Application dictionary.
  3. Before the you call of the method of some service you need to initialize it first:
    // Get the caller's token from custom state
    SessionSecurityToken sessionToken = null;
    if (System.Web.HttpContext.Current.Items.Contains(typeof(SessionSecurityToken).AssemblyQualifiedName))
    {
    sessionToken = System.Web.HttpContext.Current.Items[typeof(SessionSecurityToken).AssemblyQualifiedName] as SessionSecurityToken;
    }
    SecurityToken callerToken = null;
    // We expect only one token to be specified during Bootstrap.
    if ((sessionToken != null) && (sessionToken.BootstrapTokens.Count == 1))
    {
    callerToken = sessionToken.BootstrapTokens[0];
    }
    if (callerToken == null)
    {
    // We lost the session state but the user still has the federated ticket
    // Let's sign the user off and start again
    FederatedAuthentication.SignOut();
    return LogOff();
    }
    // Get the channel factory to the backend service from the application state
    ChannelFactory<ICoreService> factory = (ChannelFactory<ICoreService>)System.Web.HttpContext.Current.Application[MvcApplication.CachedChannelFactory];
    // Create and setup channel to talk to the backend service
    ICoreService channel;
    lock (factory)
    {
    // Setup the ActAs to point to the caller's token so that we perform a delegated call to the backend service
    // on behalf of the original caller.
    channel = factory.CreateChannelActingAs<ICoreService>(callerToken);
    //factory.Credentials.IssuedToken = callerToken;
    //channel = factory.CreateChannel();
    }
    
  4. First you need to get callerToken (it represents the SAML token of the currently authenticated user).
  5. Then in the line: take the factory instance – initialized in the previous code section in the Global.asax.cs.
  6. Use the factory instance to create the Channel for your service:
    channel = factory.CreateChannelActingAs<ICoreService>(callerToken);
    
  7. Change ICoreService to the interface of your service
  8. you can call your service method
    var UcpAccounts = channel.ListAccounts();
    

Atomia Identity update to support authentication of web application using certificate

Web.config file of Atomia Identity update with:

  1. On element with xpathconfiguration\microsoft.identityModel\service\issuerNameRegistry\trustedIssuers add line like:
    <add name="CN=MyWebApplication" thumbprint="1C18704DF16069DCDD90CE6C6D2FFDE3002E2929" />
    
  2. On element with xpathconfiguration\microsoft.identityModel\service\securityTokenHandlers\securityTokenHandlerConfiguration\issuerNameRegistry\trustedIssuersadd line like:
    <add name="CN=MyWebApplication" thumbprint="1C18704DF16069DCDD90CE6C6D2FFDE3002E2929" />
    

Was this helpful?