Atomia Identity

Configuring WCF to use Identity STS Authentication 

25 views 0

Configuring the WCF application config file, client configuration and certificates locations.

WCF application config file

We are starting from configuration like this:

<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="CoreServiceBehavior"
name="Service.CoreService">
<endpoint address="" binding="wsHttpBinding" contract="Service.ICoreService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8700/CoreService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CoreServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

As we can see we are starting with one WCF service ICoreService that does not need any authentication.

To enable authentication using Atomia Identity in this file we will add config section for microsoft.identity.

<!-- NEW -->
<configSections>
<section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=0.6.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<microsoft.identityModel>
<service>
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=0.6.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<add name="CN=Atomia Identity" thumbprint="72071a7a2b933bd5b73bbb4b026c575ccb2d2ca4"/>
</trustedIssuers>
</issuerNameRegistry>
<securityTokenHandlers>
<remove type="Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler, Microsoft.IdentityModel, Version=0.6.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add type="Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler, Microsoft.IdentityModel, Version=0.6.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<samlSecurityTokenRequirement>
<nameClaimType value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"/>
<roleClaimType value="http://schemas.troxo.com/ucp/2009/04/ucpcore/claims/groups"/>
</samlSecurityTokenRequirement>
</add>
</securityTokenHandlers>
</service>
</microsoft.identityModel>

In this config file few things are important to note:

  • line 09 – We define with which issuer our WCF application has trusted relation.
  • line 17 – Defines value of which token type will be interpreted as username.
  • line 18 – Defines value of which token type will be interpreted as users role.

Now, we should configure our service to use federated authentication:

<system.serviceModel>
<services>
<service behaviorConfiguration="CoreServiceBehavior"
name="Service.CoreService">
<endpoint address="" binding="wsFederationHttpBinding" contract="Service.ICoreService" bindingConfiguration="wsFed" >
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8700/CoreService/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsFederationHttpBinding>
<binding name="wsFed"  >
<security mode="Message">
<message issuedKeyType="SymmetricKey" issuedTokenType="">
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="false"/>
<add claimType="http://schemas.troxo.com/ucp/2009/04/ucpcore/claims/groups" isOptional="true"/>
</claimTypeRequirements>
<issuer address="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/username/" />
<issuerMetadata address="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/mex" />
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CoreServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization principalPermissionMode="None"/>
<serviceCredentials>
<issuedTokenAuthentication allowUntrustedRsaIssuers="false" certificateValidationMode="PeerOrChainTrust" audienceUriMode="Never" revocationMode="Online" trustedStoreLocation="LocalMachine">
<knownCertificates>
<add findValue="UCP Authorization Service" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
</knownCertificates>
</issuedTokenAuthentication>
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="UCP Core">
</serviceCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
  • Line 06 – Defines that we use now wsFederationHttpBinding.
  • Lines 19 to 31 – Describes federated http bindings setting.
    • Lines 23 to 26 – What claim types we are requesting from Atomia Identity for our WCF.
    • Lines 27 and 28 – Defines location of identity provider for.

On the STS side we should add RP (Rely party) certificate and inform STS that for given URI should use that certificate. This is done in two steps:

1. Set which RpCertProvider to use for given RP URI.

<type type="IRpCertProvider" mapTo="AtomiaRpCertificateProvider" name="http://localhost:8700/CoreService/"></type>

2. For AtomiaRpCertProvider set how to find certificate.

<add storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" findValue="CN=MyWebService" rpAddress="http://localhost:8700/CoreService/" />

Of course, you will have to install that certificate on given location.

Client configuration

If we now update service reference on client side Visual Studio will generate config file like:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsFederationHttpBinding>
<binding name="WSFederationHttpBinding_ICoreService" 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.troxo.com/ucp/2009/04/ucpcore/claims/groups"
isOptional="true" />
</claimTypeRequirements>
<issuer address="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/username/" />
<issuerMetadata address="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/mex" />
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8700/CoreService/" binding="wsFederationHttpBinding"
bindingConfiguration="WSFederationHttpBinding_ICoreService"
contract="CoreServiceNamespace.ICoreService" name="WSFederationHttpBinding_ICoreService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

If you look line 24 you will see that is set what is address of STS server but its not set how to authenticate to this service. We will need to update that line like:

<issuer address="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/username/" binding="wsHttpBinding"
bindingConfiguration="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/username/">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAAu0r+Dvx..." />
</identity>
</issuer>

Now we should add new bindingConfiguration:

<wsHttpBinding>
<binding name="http://localhost:50680/AtomiaIdentityStS/AtomiaSts.svc/username/"
closeTimeout="00:01:00" openTimeout="00:10: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="UserName" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>

With this binding configuration we have set how the client will be authenticated to the STS.

Certificates locations

If we assume that certificate for Atomia Identity is AtomiaIdentity.cer and certificates for RP are WCFService.cer andWCFService.pfx locations for them will be:

  1. On STS Side:
    1. WCFService.cer => LocalComputer|TrustedPeople
  2. On RP Side:
    1. AtomiaIdentity.cer => LocalComputer|Trusted root certificate authorities
    2. AtomiaIdentity.cer => LocalComputer|Trusted people
    3. WCFService.pfx => LocalComputer|Personal
  3. On client side:
    1. WCFService.cer => LocalComputer|Trusted root certificate authorities

Was this helpful?