IT:AD:WCF/Concepts:The Whole Picture:Service Endpoint Bindings
Summary
In the previous section we expressed the structure so far:
{service} 1-* {endpoint} 1-1 [address+binding+contract].
Where customizing the binding settings – specifically security related – was made apparaent.
What does Security Mean in WCF?
What does Security cover?
Security in WCF (Ref:msdn) consists of two primary requirements: transfer security and* authorization.
About Transfer Security: a common mistake is to think that transfer security – at least in terms of HTTP bindings – is just about SSL. It's not. transfer security includes:
* authentication (verifying the identity of both the service and the client),
* confidentiality (message encryption),
* integrity (digital signing to detect tampering).
* timestamping, etc.
About Authorization: is allowing only privileged users access to parts of a message.
* Security, whether provided by Transport or Message is based on Credentials to authenticate the other party. The credentials can be sent in many ways: UserName/Pwd (Basic), a Pwd Hash (Digest), Windows, NTLM, etc.
* Claim: a statement by either party. Generally this is a Claim of Identity stating something equivalent to “I am ServerA”, and vice versa “I am Paul”
* Credential: A claim is worthless/untrustable, until it is backed up by a credential.
* Security Context: Once both parties trust each other, a Security Context is established.
* Once established all messages are exchanged in confidentiality, and all messages are signed to protect their integrity.
>Important:
Not all scenarios require clientCredentialType. If using Transport security using SSL, the server authenticates itself to the Client. Unless the server also needs to authenticate the Client before granting access, the transport credential type can be set to None.
### Setting a Binding's Security Mode ###
Most of the time the mode value is one from the Ref:msdn:SecurityMode enum, but (important) each binding can offer an alternative security enums (eg: Ref:msdn:BasicHttpSecurityMode enum) to offer more or less of the basics types [None|Message|Transport|Mixed].
Generally speacking:
* transport:
* +: (with SSL or equivalent) is less CPU intensive, but only good from one point to another (message security is better for multiple hops).
* +: it's less CPU intensive because once a secure context has been established established, messages flow freely and quickly (unlike Message, where every message contains Identity information embedded in XML soap that needs to be authenticated.
* -: CHECK: once the transport layer has been established, client credential data is no longer used?
* If so, without client credentials in each message, cannot provide authorisation checking.
* message:
* +: credentials and other data (ie hashes) needed to ensure integrity and confidentiality (ie, encryption) are included in every message.
* -: as each message needs to then create and compare hashes, as well as decrypt the messages, it's more CPU intensive.
* +: more flexible as security is independent of transport protocol requirements (ie not stuck to SSL).
* TransportWithMessageCredentials:
* +: best of both (not the same as all of both)
* +: uses transport security (ie SSL in HTTP bindings) to provide confidentiality and integrity.
* +: each message contains credential data, allowing authentication.
* +: authentication of each message in turn means authorization can be implemented.
The Binding's Security Mode ([None|Message|Transport|Mixed]) is set using:
system.serviceModel/bindings/{binding}/binding@name="..."/security@mode="[None|Transport|Message|Mixed]
An important point to note is that when dealing with Transport Security in an HTTP based protocol (ie, basicHttpBinding and wsHttpBinding), we're really talking about SSL. And SSL, when the ServiceHost is in turn hosted within the context of IIS means that there is nothing to do (SSL is handled by IIS, not the ServiceHost) (Ref:msdn).
> Tip:
Note that the TransportCredentialOnly is only found on basicHttpBinding
(Ref:msdn).
>Tip:
Each binding defaults to its own preferred security mode (eg: basicHttpBinding to None, wsHttpBinding to Message, etc.), and being default settings, are not always serialized and included in the config file... Out of sight, but being set anyway, this commonly causes developers who setup in a simple binding (eg: basicHttpBinding) a lot of angst due to not understand clearly why everything stops working as they switch bindings to match production environment settings more closely...
>Just because default settings are not visible in the config file, doesn't mean they're not affecting the outcome... You really have to do your homework to know what the default settings are.
**Example: basicHttpBinding** ([Ref:msdn:basicHttpBinding](http://msdn.microsoft.com/en-us/library/ms731361.aspx)):
* set using:
> system.serviceModel/bindings/httpBinding/binding@name=“…”/security@mode=“[(None)|Transport|Message|TransportWithessageCredential|TransportCredentialOnly]“
* set to [Ref:msdn:BasicHttpSecurityMode enum](http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode):
* Note:
* Default Security Mode is None.
* it is the only binding whose security by default is None.
* If set to Transport, as it is an HTTP protocol, this really means SSL.
* SSL is ***not** configured by WCF in any way* -- that's handled by the hosting IIS.
* If set to TransportWithMessageCredential, then the *Transport* Client Credential Type is ignored ([Ref:msdn](http://msdn.microsoft.com/en-us/library/system.servicemodel.securitymode.aspx)).
* TransportCredentialsOnly is ***only*** available on basicHttpBinding.
* This mode does not provide message integrity and confidentiality. It provides only HTTP based client authentication. Use this mode with caution. It should be used in environments where the transfer security is being provided by other means (such as IPSec) and only client authentication is provided by the infrastructure. ([Ref:msdn](http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode.aspx))
* TransportCredentialsOnly sends credentials in plain unencrypted text and unencrypted. *Recommended for testing only*.
* sends credentials in plain unencrypted text and unencrypted.
* *Recommended for testing only*.
* TransportWithMessageCredential (common to many)
* When setting the security mode to TransportWithMessageCredential, the transport determines the actual mechanism that provides the transport-level security. For example, the HTTP protocol uses Secure Sockets Layer (SSL) over HTTP (HTTPS). Therefore, setting the ClientCredentialType property of any transport security object (such as HttpTransportSecurity) is ignored. In other words, you can only set the ClientCredentialType of the message security object
* [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731172.aspx)
**Example: wsHttpBinding** ([Ref:msdn:wsHttpBinding](http://msdn.microsoft.com/en-us/library/ms731299)):
* set using:
> system.serviceModel/bindings/wsHttpBinding/binding@name=”…”/security@mode=“[None|Transport|(Message)|TransportCredentialOnly]“
* set to [Ref:msdn:SecurityMode enum](http://msdn.microsoft.com/en-us/library/system.servicemodel.securitymode):
* Another way of seeing the differences are:
* Transport: HTTPS transport security.
* Message: WS-Security.
* TransportWithMessageCredential:HTTPS transport protection with SOAP message credential security for authenticating the caller.
* Note:
* Default Security Mode is Message
* Know about:
* binding.Security.Message.EstablishSecurityContext=false [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731925)
* eg:system.serviceModel/bindings/wsHttpBinding/binding@name=”…”/security@mode=“Message”
* For Routing issues:
* consider bypassProxyOnLocal to false in a corp environment (same issue as with browsers really).
* consider setting useDefaultWebProxy to false.
* Or consider using proxyAddress
* [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731172.aspx)
### 5.3.2. Setting a Binding's Credential Types ###
I'll be frank with you: this part is just about the hardest...But if you can stay concentrated a bit longer, you'll be over the hump...
So far we've seen that a binding's Security Mode can require configuration of one or more of the following:
* system.serviceModel/bindings/{bindingType}/binding@name="..."/security@mode="..."/transport
* system.serviceModel/bindings/{bindingType}/binding@name="..."/security@mode="..."/message
The security mechanisms for each are based on credentials to validate the other party.
There two sets of credentials that can come into play for *both* types of security:
* Client credentials
* Server credentials
In other words, we're going to be talking about:
* transport security
* clientCredentialType: used to authenticate the client to the service.
* server credentials
* message security
* clientCredentialType
* server credentials
Got that? It's rather important to get that before moving on to the next part.
* The clientCredentialType options are [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms729700.aspx), [Ref:msdn:more detail](http://msdn.microsoft.com/en-us/library/ms789031):
* Basic:
* :Not installed by default in IIS7 as it's rather insecure.
* -:Username|Pwd sent as a Base64 encoded string (ie no encryption, so really same as being sent in the clear!) (iis config location@path=“…”/system.webServer/security/authentication/basicaAuthentication@enabled=true,@logonMethod=ClearText,@defaultLoginMethod=DEV)
* :If used, only use if
* AnonymousAuthentication is turned off (or else it will preempt and let everything through) (using location@path=“…”/system.webServer/security/authentication/anonymousAuthentication@enabled=false)
* Transport security via SSL is also used.
* [Ref:msdn](http://www.iis.net/ConfigReference/system.webServer/security/authentication/basicAuthentication)
* Digest:
* +: Intended to replace Basic.
* +: Advantage over Basic is that username|pwd are sent over the wire as a hash.
* +: It's a challenge/response system.
* Server sends a string of random data (nonce) to the client as a challenge.
* Clients sends back a hash that includes {username|pwd|nonce|otherstuff}
* Server uses known nonce to verify that it's copy of the username|pwd would produce the same hash.
* -: A Realm (ie Windows Dowmain) must be specified for it to work.
* Windows:
* -:Expects a Kerberos environment to be in place.
* NTLM:
* +: Is a challenge/response system
-: Requires multiple exchanges between server and client.
-: Therefore requires server and all proxies to support *persistent* connections, and complete successfully.
* Kerberos:
* +: Significant improvement over NTLM
* It's faster.
* Allows mutual authentication
* Allows delegation of credentials to remote machines.
* Negotiate:
* +: Automatically selects Kerberos or NTLM depending on availability.
*
***FAQ:***
* Is the full list of clientCredentialType options offered for each binding?
* No. Depending on the binding type *and* on whether Transport or Message, the clientCredentialType options offered for each situation is a different subset of the full list ([None|UserName|Basic|Digest|NTLM|Windows|IssuedToken|Certificate]).
* for example, for basicHttpBinding the options are [None|Basic|Digest|Ntlm|Windows|Certificate].
* and for wsHttpBinding the options are [None|Basic|Digest|Ntlm|Windows|Certificate] ((Ref:msdn:wsHttBinding/security/transport)[http://msdn.microsoft.com/en-us/library/ms731313]))
* Are the *Transport* clientCredentialType options the same as the *Message* clientCredentialType options?
* No. More often than not, the clientCredentialTypes options offered for Transport are not the same as those offered for Message (eg: for basicHttpBinding, Transport client credential types are [None|Basic|Digest|Ntlm|Windows|Certificate], whereas for Message, the clientCredentialType options are only [UserName|Windows]
#### 5.3.2.1 Setting a Binding's Transport clientCredentialType ####
*Client* Credentials are:
* used to authenticate the *client* to the *service* in cases where mutual authentication is required.
* also can be used to specify service certificates for scenarios where the client must secure messages to a service with the *service*'s certificate.
Assuming the binding's SecurityMode is set to Transport or Mixed, you set the clientCredentialType as in the following examples:
**Example: basicHttpBinding**
([Ref:msdn:basicHttpBinding](http://msdn.microsoft.com/en-us/library/ms731361)):
As shown earlier, the default *Binding Security Mode* for basicHttpBinding is None [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731347), but if set to Transport, one can set the transport clientCredentialType to one of the following:
//Only applies if bindind SecurityMode=Transport|Mixed:
system.serviceModel/bindings/{bindingType}@name="..."/security@mode="..."/transport/clientCredentialType="[(None)|Basic|Digest|Ntlm|Windows]"
* Note:
* Element [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731334)
* Set using [Ref:msdn](http://msdn.microsoft.com/en-us/library/system.servicemodel.httpclientcredentialtype)
* Does not support UserName, Certificate, or IssuedToken.
* Default is None.
**Example: wsHttpBinding**
([Ref:msdn:wsHttpBinding](http://msdn.microsoft.com/en-us/library/ms731313)):
As show earlier, the default *Binding Security Mode* is: Message [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731362), but if changed to Transport, or Mixed, one sets the clientCredentialType as follows:
//Only applies if bindind SecurityMode=Transport|Mixed:
system.serviceModel/bindings/wsHttpBinding/binding/security/transport@clientCredentialType=“[None|Basic|Digest|Ntlm|Windows|Certificate]“
Note:
* Element [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731313)
* Set using [Ref:msdn](http://msdn.microsoft.com/en-us/library/system.servicemodel.httpclientcredentialtype)
* Same as for basicHttpBinding
* [CHECK] As there is no default, you'll have to set it by hand.
* In most cases you'll be using either Windows or Certificate (Basic or Hash are not safe enough for much else than POC's).
<WRAP tip>
with these default settings, whereas basicHttpBinding will work out of the box (as Security Mode=None, wsHttpBinding will immediately expect you to be in the same domain, as Security Mode=Windows, as well as other constraints [TODO].
</WRAP>
* If it's set to Certificate, what does that mean? How is the client suppossed to set it?
* We're coming right to that in the next part where we actually set the credential (we're just setting the Type now).
#### 5.3.2.2 Setting a Binding's Message clientCredentialType ####
Assuming the binding's SecurityMode is set to Message or Mixed, you set the message clientCredentialType as follows:
<WRAP tip>
Although appearing repetitious covering something very very similar to the previous section, pay attention. To the following. The reason is that whereas the default SecurityMode is None for basichttpBinding, it is Message for wsHttpBinding, and therefore the default setting comes into effect here.
</WRAP>
**Example: basicHttpBinding**
([Ref:msdn:basicHttpBinding](http://msdn.microsoft.com/en-us/library/ms731361)):
As shown earlier, the default *Binding Security Mode* for basicHttpBinding is None [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731347), but if set to Message, one can set the transport clientCredentialType to one of the following:
system.serviceModel/bindings/httpBinding@name=”…”/security@mode=“…”/message/transport/clientCredentialType=“[(UserName)|Certificate]“
Note:
* Element [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731338)
* Set using [Ref:msdn](http://msdn.microsoft.com/en-us/library/system.servicemodel.httpclientcredentialtype)
* Very few options.
* Default is UserName.
**Example: wsHttpBinding**
([Ref:msdn:wsHttpBinding](http://msdn.microsoft.com/en-us/library/ms731313)):
As show earlier, the default *Binding Security Mode* is: Message [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731362), and therefore is relevant that the default setting is clientCredentialType is Windows.
system.serviceModel/bindings/wsHttpBinding/binding@name=”…”/message@clientCredentialType=“[None|UserName|Windows|Certificate|IssuedToken]“
Notes:
* Element [Ref:msdn](http://msdn.microsoft.com/en-us/library/ms731346)
* Set using [Ref:msdn](http://msdn.microsoft.com/en-us/library/system.servicemodel.messagecredentialtype)
* Of note, missing NTLM as an option.
***FAQ:***
* If it's set to Windows, what does that mean? How is the client suppossed to set it?
* We're coming right to that in the next part where we actually set the credential (we're just setting the Type now).
### 5.3.2.3 Setting a Binding's Service Transport Credential Type ###
### 5.3.2.4 Setting a Binding's Service Message Credential Type ###
### 3. Set the credential values ###
### 3.a Set the Server Credential Values ###
[Ref:msdn:ServiceCredentials element](http://msdn.microsoft.com/en-us/library/ms731782) used for:
* specifying the settings used by the client to validate the certificate presented by the service using SSL *transport* authentication.
* contain any certificate for the service that is explicitly configured on the client to use for encrypting messages to the service using message security.
### 3.b Set the Client Credential Values ###
[Ref:msdn:ClientCredentials](http://msdn.microsoft.com/en-us/library/ms731310.aspx)
* authenticate the client to services in cases where mutual authentication is required.
* This configuration section can also be used to specify service certificates for scenarios where the client must secure messages to a service with the service's certificate.
The last part is the most complex.
Depending on the security mode chosen above, you will have to set the transport or message client credentials.
### Transport ###
If you decide to use transport security for HTTP (in other words, HTTPS), you must also configure the host with an SSL certificate and enable SSL on a port. For more information, see HTTP Transport Security.
### Message ###
### General ###
#### UserName ####
* As it's not the most secure, normally only seen in basicHttpBinding, with security mmode=TransportWithMessageCredential (forcing at least https) on Message.
* Sometimes seen on wsHttpBinding`
* Reminder: just as with Windows authentication, you can't define username/password in the config file, so you do it via code.
* That said, I found this: http://blog.shutupandcode.net/?p=22
* Ref:HowTo
* “The password authentication is defined inside the UserNameAuthentication property of the ServiceCredential. There you can define a custom password validator or a membership provider. “If you choose transport-security, then you should use the option “TransportWithMessageCredential” so that the username and password are communicated in the message.” Ref:forum
* 5) If you use message security (SecurityMode = Message or TransportWithMessageCredentials) to authenticate the client ServiceSecurityContext.Current.AuthorizationContext.ClaimSets will contain a name claim with the username. If the message security binding doesn't use secure conversation OperationContext.Current.SupportingTokens will contain the username token.Ref:forum
Windows: **
If client credential type (2 above) is set to windows:
Nothing to do on server.
* On Client:
* Cannot set username|password from Code ref
* That said, I found this: http://blog.shutupandcode.net/?p=22
* Using code, use existing Network Credentials, or set yours specifically:
Example:
myService.ClientCredentials.Windows.ClientCredential.UserName = “username”;
myService.ClientCredentials.Windows.ClientCredential.Password = “password”
## Behaviors ##
### Service Behaviors ###
There are several (Ref:msdn:serviceBehaviors) but the most common are:
* serviceMetadata
* serviceDebug
* serviceAuthentication
* serviceAuthorization
* serviceThrottling (Ref:msdn:serviceThrottling Element)
### Server Side Behaviour: Exposing Metadata ###
Controls publishing of a service's metadata.
* For security purposes, by default it's turned off.
<system.serviceModel/behaviors/behavior@name=”…”/serviceMetadata
externalMetadataLocation=“String”
httpGetBinding=”String”
httpGetBindingConfiguration=”String”
httpGetEnabled=“Boolean”
httpGetUrl=“String”
httpsGetBinding=”String”
httpsGetBindingConfiguration=”String”
httpsGetEnabled=“Boolean”
httpsGetUrl=“String”
policyVersion=“Policy12|Policy15”
>Note:
httpsGetEnabled is often forgotten.
### Server Side Behaviour: Exposing Debug Info ###
Syntax:
serviceDebug
httpHelpPageBinding=”String”
httpHelpPageBindingConfiguration=”String”
httpHelpPageEnabled=”(true)|false“
httpHelpPageUrl=“Uri” controls where WSDL will show.
httpsHelpPageBinding=”String”
httpsHelpPageBindingConfiguration=”String”
httpsHelpPageEnabled=”(true)|false“
httpsHelpPageUrl=“Uri”
includeExceptionDetailInFaults=“Boolean”
Setting includeExceptionDetailInFaults to true allows the service to return any exception that is thrown by the application code even if the exception is not declared using the FaultContractAttribute. This setting is useful when debugging cases where the server is throwing an unexpected exception. By using this attribute, a serialized form of the unknown exception is returned and you can examine more details of the exception.
system.serviceModel/behaviors/behavior@name=”…“/serviceDebug@includeExceptionDetailInFaults=true|false”
Ref:msdn:serviceDebug Element
## Resources ##
* http://msdn.microsoft.com/en-us/library/ms734736
* (http://www.codeproject.com/Articles/318810/WCF-Service-Method-Level-Security-using-Message-Co)[http://www.codeproject.com/Articles/318810/WCF-Service-Method-Level-Security-using-Message-Co]
* http://msdn.microsoft.com/en-us/library/ms730088.aspx
* [linkref]: link.address.here “link title here”
* [basicHttp]: http://msdn.microsoft.com/en-us/library/ms731361.aspx “MSDN basicHttp”