- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
WCF: Using binary encoding with security
Joined: 31-Mar-2009
Hello! I've just downloaded the trial of llblgen and am working with the (very helpful) WCF example I downloaded. (DISCLAIMER: I'm clearly not a WCF expert, so be gentle.)
Here's my dilemma. I'm trying to add security (based on the ASP.NET membership provider) to that tutorial, and it works when I use this binding (and set up X509 certificates, etc etc.):
<wsHttpBinding>
<binding name="testWsBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
But as I'm gathering from other threads, my best performance would come from using binaryMessageEncoding, so i'm trying to get a combination of that with security, and it's all kinds of cranky about it. If I use:
<customBinding>
<binding name="NetHttpBinding">
<reliableSession />
<security authenticationMode="UserNameForCertificate">
</security>
<compositeDuplex />
<oneWay />
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
then I get errors about it not liking the order of the parameters, which since the parameters are IN the order it suggests, I assume it's really code for 'you're trying to do something you shouldn't, you idiot.' On the other hand, if I just do:
<binding name="SecureNetHttpBinding">
<security authenticationMode="UserNameForCertificate">
</security>
<binaryMessageEncoding />
<httpTransport />
</binding>
then I get errors about not finding the certificate in the client settings(even though it works just fine with the wsHttpBinding version). Plus, I don't know if leaving out those other parameters is going to have an impact on me/my application.
I realize this is much more a WCF question than a llblgen question, but I really do need the combination of WCF, security, AND not-totally-terrible performance.
.NET 3.5 SP1, Visual Studio 2008 SP1, (and llblgen 2.6 final demo, with the WCF example downloaded yesterday)
Help? Is there a best practice here?
Thanks in advance, Scott
For the brave - here's the whole servicemodel section of my web.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="CN=localhost"/>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="TASDashboardMembershipProvider" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="NetHttpBinding">
<reliableSession />
<compositeDuplex />
<oneWay />
<binaryMessageEncoding />
<httpTransport />
</binding>
<binding name="SecureNetHttpBinding">
<security authenticationMode="UserNameForCertificate">
</security>
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
<wsHttpBinding>
<binding name="testWsBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="SD.LLBLGen.Pro.Examples.WCF.Service.NorthwindService" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address=""
binding="customBinding"
bindingConfiguration="SecureNetHttpBinding"
contract="SD.LLBLGen.Pro.Examples.WCF.ServiceInterface.INorthwindService">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine" findValue="CN=localhost"/>
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
and the whole app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetHttpBinding">
<reliableSession />
<compositeDuplex />
<oneWay />
<binaryMessageEncoding />
<httpTransport />
</binding>
<binding name="SecureNetHttpBinding">
<security authenticationMode="UserNameForCertificate">
</security>
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
<wsHttpBinding>
<binding name="testWsBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<!-- remove behaviorConfiguration on next line for production -->
<endpoint address="http://localhost/WCFService/CustomerService.svc"
behaviorConfiguration = "ServiceCertificate"
name="WCFServer"
binding="customBinding"
bindingConfiguration="SecureNetHttpBinding"
contract="SD.LLBLGen.Pro.Examples.WCF.ServiceInterface.INorthwindService">
<!-- remove this identity section for production -->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name = "ServiceCertificate">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode = "PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Joined: 31-Mar-2009
Well, I think I've gotten farther, but I'm certainly open to a WCF expert to tell me what I could do better.
Courtesy of http://blog.salamandersoft.co.uk/CommentView,guid,0b691f56-47eb-4715-8ffd-134250a70817.aspx I was able to translate the wsHttpBinding into a customBinding, and then add the various extra parameters, including binaryMessageEncoding. So my custom binding now looks like:
<binding name="SecureNetHttpBinding">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />
<reliableSession />
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
<localClientSettings cacheCookies="true" detectReplays="true"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="false"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="true" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="false" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap defaultAlgorithmSuite="Default"
authenticationMode="UserNameForSslNegotiated" requireDerivedKeys="true"
securityHeaderLayout="Strict" includeTimestamp="true" keyEntropyMode="CombinedEntropy"
messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
<localClientSettings cacheCookies="true" detectReplays="true"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="true" issuedCookieLifetime="00:15:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
</secureConversationBootstrap>
</security>
<compositeDuplex />
<oneWay />
<binaryMessageEncoding />
<httpTransport />
</binding>
I'm guessing I don't need all that detail but it does seem to work. Time to sleep. Again, totally open to input on doing this better...