I have been working on a POC for outside users to authenticate to a WCF service using ADFS 2.0 with a username/password.
I have the client configure to use https:///adfs/services/trust/13/username and a security mode of TransportWithMessageCredentail. And after pulling my hair out for a few days I have the authentication working and the STS is issuing the tokens. I am able to see the success events on the server when the tokens ,with the claims, are issued.. However, once I try to access the claims from within the context of the service it is showing as null. I have turned on all of the tracing and I am not seeing any errors listed in the trace files. I am using ADFS 2.0 with WIF 4.5 in Visual Studio 2012.
I plan on using a backend attribute SQL store to pull info out of so I have planned on keeping everything in house, but every example I am finding is integrating the Azuer ACS. Once I have the claims I am going to deciding within the logic of the service how a call is processed.
Does anyone see something that I am doing wrong or have suggestions of a different approach.
Client App.confg
<bindings>
<customBinding>
<binding name="WS2007FederationHttpBinding_IDataServices">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
requireDerivedKeys="true" includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
requireSignatureConfirmation="false" canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default"
authenticationMode="IssuedTokenForSslNegotiated" requireDerivedKeys="true"
includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
requireSignatureConfirmation="true">
<issuedTokenParameters keySize="256">
<additionalRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
<trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">256</trust:KeySize>
<trust:KeyWrapAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
<trust:EncryptWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
<trust:SignWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignWith>
<trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</additionalRequestParameters>
<issuer address="https://<adfs>/adfs/services/trust/13/usernamemixed"
binding="ws2007HttpBinding" bindingConfiguration="https://<adfs>/adfs/services/trust/13/usernamemixed" />
</issuedTokenParameters>
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</secureConversationBootstrap>
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</security>
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
<ws2007HttpBinding>
<binding name="https://<adfs>/adfs/services/trust/13/usernamemixed">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:62838/DataServices.svc" binding="customBinding"
bindingConfiguration="WS2007FederationHttpBinding_IDataServices"
contract="ServiceReference1.IDataServices" name="WS2007FederationHttpBinding_IDataServices">
<identity>
<dns value="adfs.server"/>
</identity>
</endpoint>
</client>
Service config
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
<add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />
<add key="ida:FederationMetadataLocation" value="https://<advs>/FederationMetadata/2007-06/FederationMetadata.xml" />
<add key="ida:ProviderSelection" value="productionSTS" />
</appSettings>
<location path="FederationMetadata">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime requestValidationMode="4.5" targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<pages controlRenderingCompatibilityVersion="4.5" />
<machineKey compatibilityMode="Framework45" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
<serviceCredentials useIdentityConfiguration="true">
<clientCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
</clientCertificate>
<serviceCertificate findValue="8054B36FA61FB4AA53CD8C6F9575E1192C2B3151" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
<protocolMapping>
<add scheme="http" binding="ws2007FederationHttpBinding" />
</protocolMapping>
<bindings>
<ws2007FederationHttpBinding>
<binding name="">
<security mode="Message">
<message>
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="true" />
<add claimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" isOptional="true" />
</claimTypeRequirements>
<issuerMetadata address="https://<adfs>/adfs/services/trust/mex" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
</system.serviceModel>
<system.identityModel>
<identityConfiguration>
<audienceUris mode="Never">
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add thumbprint="8054B36FA61FB4AA53CD8C6F9575E1192C2B3151" name="http://<adfs>/adfs/services/trust" />
</trustedIssuers>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="myUserTraceSource" switchValue="Information, ActivityTracing">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Traces1.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
Service logic
IList<string> Names = new List<string>();
Names.Add(Thread.CurrentPrincipal.Identity.Name.ToString()); // returns ""
Names.Add(ServiceSecurityContext.Current.PrimaryIdentity.Name.ToString()); // returns ""
Names.Add(ServiceSecurityContext.Current.WindowsIdentity.Name.ToString()); // returns ""
var principal = ClaimsPrincipal.Current;
foreach (var claim in principal.Claims)
{
Names.Add(claim.Subject.ToString());
}
return Names;
Client Logic
static void Main(string[] args)
{
ServiceReference1.DataServicesClient client = new ServiceReference1.DataServicesClient();
client.ClientCredentials.UserName.UserName = @"UserName";
client.ClientCredentials.UserName.Password = @"Password";
client.ChannelFactory.Credentials.SupportInteractive = false;
var test = client.DoWork("Test");
...............