Can WCF Authentication be disabled for a single Operation - wcf

I have recently read the WCF Security Guide and am using it to create an application where users need to create their own account, and then access the application with message security. Below is the web.config file I have come up with so far from the book. The issue I am having revolves around user registration. Since the application requires username/password authentication, the method to register a new user consistently fails.
I know of one way around this (switching to role based authentication and creating a single user in a role that has registration privileges, and just hard coding that information into the registration method) but am seeking an alternative solution. Is there a way to declare, at the operation level, that a particular method does not require authentication? If not, is there a way to expose a separate endpoint with a different service contract, and have that contract not require authentication? So much of the web.config file is related to the membership provider and message security, I am a little concerned, but for the method to properly register a new member in the database it does have to know about the membership provider obviously...
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<connectionStrings>
<add name="MyLocalSQLServer"
connectionString="Initial Catalog=aspnetdb;data source=DESKTOP;Integrated Security=SSPI;"/>
</connectionStrings>
<system.web>
<authentication mode="Forms" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<clear />
<add name="mySqlMembershipProvider"
connectionStringName="MyLocalSQLServer"
applicationName="Mech"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
</system.web>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="wsDualHttpEndpointBinding">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<services>
<service name="MechService.MechService">
<endpoint address="localhost/MechService" binding="wsDualHttpBinding" bindingConfiguration="wsDualHttpEndpointBinding"
name="wsDualHttpEndpoint" contract="MechService.IMechService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="CN=TempCert" />
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="MySqlMembershipProvider" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
This is the function for registering new users.
public string CreateUser(String Name, String Password, String Email, String Question, String Answer)
{
MembershipCreateStatus status;
try
{
MembershipUser newUser = Membership.CreateUser(Name, Password, Email, Question, Answer, true, out status);
if (newUser == null)
{
return GetErrorMessage(status);
}
else
{
return "MECH_CODE_SUCCESS";
}
}
catch (Exception ex)
{
return ex.Message;
}
}

You cannot opt out authentication from a single operation (although you could opt out authorization but this is note helpfull to you). The good news is that authentication settings are per endpoint and endpoint has one contract. So move the registerUser operation to a new ServiceContract and create a separate binding for it with no authentication.

Related

Custom X509CertificateValidator with configuration?

I'm setting up client certificates on my wcf service. All works great. The service requires client certs, my client test app supplies the cert and is able to make a request to one of the service end points.
No I want to implement a custom validator. I created a new class inheriting from X509CertificateValidator, and set it up in the services web config. I can put a breakpoint in the validate method and see it gets called. Awesome possum.
Now I want to be able to supply custom configuration parameters to the validator. The X509CertificateValidator has a LoadCustomConfiguration method which I can override, but it doesn't get called, I'm assuming it's because I'm not supplying any actual custom configuration anywhere - if that assumption is correct, how do I define my custom configuration parameters? Or is there some other way I should be doing this?
public class CustomValidator : System.IdentityModel.Selectors.X509CertificateValidator
{
/// <summary>
/// If the passed certificate is not valid according to the validation logic, this method throws a SecurityTokenValidationException. If the certificate is valid, the method returns to the caller.
/// </summary>
/// <param name="certificate"></param>
public override void Validate(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
{
bool bValid = true;
// Check that there is a certificate.
if (certificate == null)
{
throw new ArgumentNullException("certificate", "Certificate was not supplied.");
}
bValid = certificate.Verify() &&
DateTime.Now <= certificate.NotAfter &&
DateTime.Now >= certificate.NotBefore;
if (!bValid)
{
throw new System.IdentityModel.Tokens.SecurityTokenValidationException("Certificate is not valid.");
}
}
public override void LoadCustomConfiguration(System.Xml.XmlNodeList nodelist)
{
base.LoadCustomConfiguration(nodelist);
}
}
Configuration
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="WCFTransportAuthCertificateCustomValidation.Service1"
behaviorConfiguration="MapClientCertificates">
<endpoint binding="basicHttpBinding"
bindingConfiguration="TransportCertificateAuthentication"
contract="WCFTransportAuthCertificateCustomValidation.IService1">
</endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="TransportCertificateAuthentication">
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="MapClientCertificates">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="X509CertificateValidation.CustomValidator, X509CertificateValidation" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

How to make a secure WCF Service with AD FS

I'm trying to add claims-based security on a WCF service, using ADFS. I've succesfully done so for a Web Application (Passive federation), but I find myself stuck due to lack of documentation on the subject.
I've been playing with the Web.Config files to make it work... however, I just seem to be going from one problem to the next. Here's the Security Part of the client side web.config:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding_IService1">
<security mode="Message">
<message>
<issuer address="https://myIssuer/adfs/services/trust/13/windows" binding="basicHttpsBinding" />
<issuerMetadata address="https://myIssuer/adfs/services/trust/mex" />
<tokenRequestParameters>
<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>
</tokenRequestParameters>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/Services/Service1.svc"
binding="ws2007FederationHttpBinding" bindingConfiguration="WS2007FederationHttpBinding_IService1"
contract="ServiceRef.XISecurity.IService1" name="WS2007FederationHttpBinding_IService1" />
</client>
</system.serviceModel>
I'm unsure if I'm using the correct binding type or endpoint here. When I run the following code:
Service1Client obj = new Service1Client();
string str = obj.GetData(5);
I get the following exception:
Addressing Version 'AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)' is not supported.
Here's my web.config on the server side
<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="ida:FederationMetadataLocation" value="https://myIssuer/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 targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials useIdentityConfiguration="true">
<!--Certificate added by Identity and Access Tool for Visual Studio.-->
<serviceCertificate findValue="CN=localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="ws2007FederationHttpBinding" />
<!--<add binding="basicHttpsBinding" scheme="https" />-->
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<ws2007FederationHttpBinding>
<binding name="">
<security mode="Message">
<message>
<issuerMetadata address="https://myIssuer/adfs/services/trust/mex" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true" />
</system.webServer>
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="http://localhost:2017/Service1.svc" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="http://myIssuer/adfs/services/trust">
<keys>
<add thumbprint="7502424014D0A1BD87A5DEEF0D1EB13390101F07" />
</keys>
<validIssuers>
<add name="http://myIssuer/adfs/services/trust" />
</validIssuers>
</authority>
</issuerNameRegistry>
<!--certificationValidationMode set to "None" by the the Identity and Access Tool for Visual Studio. For development purposes.-->
<certificateValidation certificateValidationMode="None" />
</identityConfiguration>
</system.identityModel>
</configuration>
My first question is: is there a good, step by step tutorial on how to set up my web.config files for that? Ideally one with .NET 4.5?
Second question: I'm really confused about which binding ADFS endpoint or binding to use. Here's what it's currently set to.
<issuer address="https://myIssuer/adfs/services/trust/13/windows" binding="basicHttpsBinding" />
Any help would be hugely appreciated. Thank you
In answer to your second question you can find some information on endpoints at http://technet.microsoft.com/en-us/library/adfs2-help-endpoints(WS.10).aspx. An endpoint basically specifies an address that you can use to communicate with the ADFS server. The type of endpoint will also tell you some things about its requirements such as whether you need to provide a certificate or a username.
There is also a mapping between endpoints and WIF bindings at http://blogs.msdn.com/b/alikl/archive/2011/10/01/how-to-use-ad-fs-endpoints-when-developing-claims-aware-wcf-services-using-wif.aspx. This has been helpful to me when I have been using code instead of the configuration file to communicate with the endpoint.

The provided URI scheme 'http' is invalid; expected 'https'.\r\nParameter name: via

I am trying to create a call out to a WCF Service using the Channel Factory. But I am getting the error above in the title. If I take out the mode of transport then I get an "Access is Denied" error. I have been working with this for 3 days now.
What I have is one WCF lets call that WCF1 and that calls WCF2. WCF1 has a config file that pertains to WCF2. Now, I want to call WCF1 from another application (NopCommerce). When I call WCF1 from NopCommerce don't I just need to provide the web.config information for WCF1 and not WCF2?
So what I have done so far is I have written this code to invoke the WCF1 Service:
AddressService.Address verifiedAddress = null;
AddressService.VerifyThisAddressKeys keys = new AddressService.VerifyThisAddressKeys();
keys.LicenseId = new Guid("LicenseKey");
var myBinding = new BasicHttpBinding();
var myEndpoint = new EndpointAddress("http://www.verifythisaddress.com/AddressVerification/AddressVerificationService.svc");
myBinding.Security.Mode = BasicHttpSecurityMode.Transport;
var myChannelFactory = new ChannelFactory<AddressService.IAddressVerificationService>(myBinding, myEndpoint);
AddressService.IAddressVerificationService client = null;
try
{
client = myChannelFactory.CreateChannel();
verifiedAddress = client.VerifyThisAddress(address.FirstName, address.LastName, address.Company, address.Address1, address.Address2, address.City, address.StateProvince.Abbreviation, address.ZipPostalCode, address.Country.TwoLetterIsoCode, address.PhoneNumber, address.Email, keys);
((ICommunicationObject)client).Close();
}
catch(Exception ex)
{
if (client != null)
{
((ICommunicationObject)client).Abort();
Console.WriteLine(ex.Message);
}
}
My goal is not to use a Web.Config file if I don't have to.
Here is the WCF Config file I am trying to communicate with:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="DBCS" connectionString="Data Source=Server" providerName="System.Data.SqlClient"/>
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
<trust level="Full" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService">
<security mode="Transport" />
</binding>
<binding name="soapEndpointGlobalAddressCheck">
<security mode="Transport" />
</binding>
<binding name="soapSSLEndpointGlobalAddressCheck">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://addresscheck.melissadata.net/v2/SOAP/Service.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService"
contract="MelissaDataService.IService" name="BasicHttpBinding_IService" />
<endpoint address="http://address.melissadata.net/v3/SOAP/GlobalAddress"
binding="basicHttpBinding" bindingConfiguration="soapSSLEndpointGlobalAddressCheck"
contract="globalcheck.AddressCheckSoap" name="soapEndpointGlobalAddressCheck" />
<endpoint address="https://address.melissadata.net/v3/SOAP/GlobalAddress"
binding="basicHttpBinding" bindingConfiguration="soapSSLEndpointGlobalAddressCheck"
contract="globalcheck.AddressCheckSoap" name="soapSSLEndpointGlobalAddressCheck" />
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Can't Sleep!

Bad request 400 error while acessing wcf rest service frequently

I am facing the problem of Bad request 400 while accessing the wcf service. I have tried all the solution related to this topic but still not solved. Wcf service is on IIS7 .
I am trying to call the service with below code.
try
{
WebClient client = new WebClient();
byte[] data = client.DownloadData(ApplicationRunTimeSettings.ServiceURL() + userID);
Stream stream = new MemoryStream(data);
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(string));
result = obj.ReadObject(stream).ToString();
}
catch (Exception)
{
}
return result;
The config file at service is below, the config file is same for the wcf as well as web application. Actually wcf service is developed with in the web application and the web app hosted on iis7 and we are accessing the service with in it.
The configuration file is below. Most of the time it does not return error but it is breaking after some time. Request on the wcf service is frequent . Data is form of JSON.
Now after making the below suggested changes for serviceThrottling the web.config file look like mentioned below but it still gives the same error some times.
<system.web>
<sessionState timeout="1440"/>
<customErrors mode="Off"/>
<httpRuntime executionTimeout="90" maxRequestLength="104857600" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" enableVersionHeader="true"/>
<!--set compilation defug="false" when releasing-->
<compilation targetFramework="4.0" >
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="86400"/>
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers"/>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<!-- maxAllowedContentLength = bytes -->
<requestLimits maxAllowedContentLength="104857600"/>
</requestFiltering>
</security>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.serviceModel>
<services>
<service name="Glance.DynamicBusinessService.DynamicBusinessService" behaviorConfiguration="ServiceBehaviour">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="customBinding" binding="customBinding" bindingConfiguration="basicConfig" contract="Glance.DynamicBusinessService.IDynamicBusinessService"/>
<endpoint address="" binding="webHttpBinding" contract="Glance.DynamicBusinessService.IDynamicBusinessService" behaviorConfiguration="REST">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="throttleThis">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True" />
<serviceThrottling
maxConcurrentCalls="40"
maxConcurrentInstances="20"
maxConcurrentSessions="20"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding maxReceivedMessageSize="999999999" receiveTimeout="24" closeTimeout="24" maxBufferPoolSize="999999999" maxBufferSize="999999999">
<readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="99999" maxBytesPerRead="4096" maxNameTableCharCount="99999" />
</binding>
</webHttpBinding>
<customBinding>
<binding name="basicConfig">
<binaryMessageEncoding/>
<httpTransport transferMode="Streamed" maxReceivedMessageSize="67108864"/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0"/>
</system.serviceModel>
</configuration>
Thanks for any suggestion and help.
I'd be tempted to comment out that configuration line on the client and host, and then trying running it. That config seems to set minimums and performance limits. If that doesn't change anything, you might try setting the performance throttling.
You could add this to the configuration and tinker with the settings until the performance of your web service smooths out. The default, for instance, for concurrent calls is 16, but if you raise that number using the ServiceThrottling, you might get better results.
<serviceBehaviors>
<behavior name="throttleThis">
<serviceMetadata httpGetEnabled="True" />
<serviceThrottling
maxConcurrentCalls="40"
maxConcurrentInstances="20"
maxConcurrentSessions="20"/>
</behavior>
</serviceBehaviors>

Why does this WCF call fail when passing in a federated security token

I'm trying to pass a security token from a client application into a WCF service for authentication.
For this example I'm just using the standard File, New WCF Application project and trying to call the GetData method.
I get the following exception on the client
{"The message could not be processed. This is most likely because the
action 'http://tempuri.org/IService1/GetData' is incorrect or because
the message contains an invalid or expired security context token or
because there is a mismatch between bindings. The security context
token would be invalid if the service aborted the channel due to
inactivity. To prevent the service from aborting idle sessions
prematurely increase the Receive timeout on the service endpoint's
binding."}
If I enable tracing on the WCF service I can see the following error
There was no channel that could accept the message with action
'http://tempuri.org/IService1/GetData'.
The Web.Config for my service looks like this
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<!--Configure STS-->
<system.identityModel>
<identityConfiguration>
<audienceUris>
<add value="https://stsserver.security.int/myApp" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089">
<trustedIssuers>
<add thumbprint="‎3c8fc34bd483b07ba0d1509827fc4788c36247e4" name="StartSSL Login" />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="None"/>
</identityConfiguration>
</system.identityModel>
<system.serviceModel>
<bindings>
<ws2007FederationHttpBinding>
<binding name ="IdentityServer">
<security mode="TransportWithMessageCredential">
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="Services.Service1" behaviorConfiguration="CertificateBehavior">
<endpoint name="ws" binding="ws2007FederationHttpBinding" bindingConfiguration="IdentityServer" contract="Services.IService1" address=""/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CertificateBehavior">
<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The method in my client application that calls this WCF service looks like this
static void CallSecuredService(SecurityToken samlToken)
{
var binding = new WS2007FederationHttpBinding((WSFederationHttpSecurityMode.TransportWithMessageCredential));
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = false;
var factory = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost/myservice/Service1.svc"));
factory.Credentials.SupportInteractive = false;
factory.Credentials.UseIdentityConfiguration = true;
var proxy = factory.CreateChannelWithIssuedToken(samlToken);
Console.WriteLine(proxy.GetData(1));
}
Any pointers as to things I should check would be great as I'm at a bit of a loss with this one now. I'm not sure how I can debug this any further?
I finally managed to get past this error. The problem was a small miss match between the service and client bindings.
Changing my bindings in the web.config to this fixed the issue
<bindings>
<ws2007FederationHttpBinding>
<binding name ="IdentityServer">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" establishSecurityContext="false"/>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>