WCF Message Credential Implementation Details
I'm looking for some technical detail on where the actual username + password (credentials) are being stored during the message exchange using a WCF binding like the below.
<bindings>
<wsHttpBinding>
<binding name="wsHttp">
<security mode="TransportWithMessageCredential">
<t开发者_如何转开发ransport/>
<message clientCredentialType="UserName"
negotiateServiceCredential="false"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
Then inside the client application I call this service passing a valid set of creds like so
using (SupplierServiceClient client = new SupplierServiceClient()) {
client.ClientCredentials.UserName.UserName = "admin";
client.ClientCredentials.UserName.Password = "password";
SupplierList = client.GetSupplierCollection();
}
At first I assumed that WCF was taking this data and putting it into the SOAP header but it doesn't appear that way from the WSDL ... any help?
Edit:
The below is what the security configuration for the client looks like in production
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
By setting the UserNameCredentials you are in fact leveraging the Username Token Profile. This causes the token to be added to the message as a SOAP header. The SOAP header will look something like this:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<env:Header>
<wsse:UsernameToken>
<wsse:Username>jdoe</wsse:Username>
<wsse:Password>passw0rd</wsse:Password>
<wsse:Nonce><!-- optional nonce here --></wsse:Nonce>
</wsse:UsernameToken>
</env:Header>
<env:Body>
<!-- body here -->
</env:Body>
</env:Envelope>
Now, I'm not exactly sure why you're mentioning WSDL. The token wouldn't appear in the WSDL, though the WSDL should contain the proper WS-Policy annontations on the operation. This would let consumers of the WSDL discover that they actually need to send in the UsernamePasswordToken to the request.
Finally, someone brought up RequestSecurityToken (RST), but there shouldn't (need to) be an RST involed if you're just using simple UsernameToken authentication. The only time an RST needs to be involved is if you're doing a token exchange with a Secure Token Server (STS) using WS-Trust.
Here's how a sample SOAP message might look like:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
<a:MessageID>urn:uuid:01d3a7d2-dc5a-42cf-acf0-3dd6bd50230e</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://localhost:9999/Service1.svc</a:To>
</s:Header>
<s:Body>
<t:RequestSecurityToken Context="uuid-7c240c06-c14b-42af-82dd-10f44f423928-1" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType>
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:KeySize>256</t:KeySize>
<t:BinaryExchange ValueType="http://schemas.xmlsoap.org/ws/2005/02/trust/spnego" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">YGsGBisGAQUFAqBhMF+gJDAiBgorBgEEAYI3AgIKBgkqhkiC9xIBAgIGCSqGSIb3EgECAqI3BDVOVExNU1NQAAEAAAC3shjiBgAGAC8AAAAHAAcAKAAAAAUBKAoAAAAPU0cyMjA1Nk1BVE1VVA==</t:BinaryExchange>
</t:RequestSecurityToken>
</s:Body>
</s:Envelope>
精彩评论