Greetings,
Our services will be exposed on the Internet. Only specific partners applications should be able to have access to them. At the same time, the partners applications users will need to be authenticated & authorized by our services. We will use role-based security to authorize them. The reason why we need a double validation using a certificate for each application is because we don't want anybody on the internet to be able to query those services directly (that includes our users having usr/pwd credentials who could try to pull the services content from their own app). We want to make sure only "known" applications can call these services.
Is that possible to do and if so, is there any sample in the SDK or somewhere else that demonstrates such configuration
Thanks
-Jonathan

Mixed credentials: Username & Certificate
gorden
Jonathan,
Your service certificate is now being propogated over SSL and so has probably been configured as part of your IIS install, if you are hosted inside IIS, or if you are self-hosted, has been configured via httpcfg.
We essentially ignore the client cert on the service side and just use the message level credentials to authenticate the client.
Gudge
Ramcat
I just tried the TransportWithMessageCredential mode with this config on both sides
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate"/>
<message clientCredentialType="UserName" negotiateServiceCredential="false" />
</security>
What i don't understand is that now, with this config, i don't have to put a certificate anywhere and its still working... I was expecting since i am using negotiateServiceCredential = false to still have to put the service certificate on the client side but i didn't and it works. I don't specify the client certificate to use either and it still works...
Am i missing something
Thx
-Jonathan
drgonjo
Jonathan,
Here is some code that creates a binding that requires both Username and Certificate credentials;
static
Binding CreateCertAndUsernameBinding(){
WSHttpBinding b = new WSHttpBinding();
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
b.Security.Message.NegotiateServiceCredential = false;
BindingElementCollection bec = b.CreateBindingElements();
SecurityBindingElement sbe = bec.Find<SecurityBindingElement>();
if (sbe != null)
{
UserNameSecurityTokenParameters p = new UserNameSecurityTokenParameters();
sbe.EndpointSupportingTokenParameters.SignedEncrypted.Add(p);
}
return new CustomBinding(bec);
}
And here is the code to set up the client credentials on the client side before making the call to the service.
cf.Credentials.UserName.UserName = "Alice";
cf.Credentials.UserName.Password = "ecilA";
cf.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindBySubjectName, "Alice");
Hope this helps,
Gudge
Aibo
I believe it's possible with a custom binding ( although not via config ). I'll try to work up a sample but it won't be today ( and probably not tomorrow either, I'm afraid )
Gudge
Jovo Filips
It turns out we don't allow you to specify client credentials at the transport layer in this mode. Sorry to send you down a blind alley. Will the message level stuff I sent earlier work for you Or do you need an HTTPS based solution
Gudge
Gregory P
Jonathan,
I now have this working with a custom binding over HTTPS. The binding creation code is as follows;
static
Binding CreateCertAndUsernameBinding(){
WSHttpBinding b = new WSHttpBinding();
b.Security.Mode = SecurityMode.Transport;
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
BindingElementCollection bec = b.CreateBindingElements();
TransportSecurityBindingElement sbe = bec.Find<TransportSecurityBindingElement>();
if (sbe == null)
{
sbe = new TransportSecurityBindingElement();
BindingElementCollection bec2 = new BindingElementCollection();
bec2.Add(sbe);
foreach (BindingElement be in bec)
bec2.Add(be);
bec = bec2;
}
UserNameSecurityTokenParameters p = new UserNameSecurityTokenParameters();
sbe.EndpointSupportingTokenParameters.SignedEncrypted.Add(p);
return new CustomBinding(bec);
}
The client side credential specification looks like this;
proxy.Credentials.UserName.UserName = "username";
proxy.Credentials.UserName.Password = "password";
proxy.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "...");
This has the client cert at the HTTPS layer and UsernameToken at the SOAP layer. Both sets of credentials show up in the resulting AuthorizationContext on the service side.
The above code should work with FebCTP.
Hope this helps,
Gudge
Zaph0d
Oh really That means i was on a good track before i got your sample. I was just trying to do that with TransportWithMessageCredential and using Certificate at the transport level. I never finished making it work though. Yes i was planning to use Https in the solution so if you have a ready to use config sample for me it would be great.
Once that work, it will be time for me to dive into making this work with an internal STS using wsFederationBinding
.
Client --> Intermediary Router --> STS
--> BizService
Thx
-Jonathan
JDanon
we have couple of samples in this area,please let me know if you need more info
http://windowssdk.msdn.microsoft.com/library/default.asp url=/library/en-us/WCF_samples/html/e74c66e1-1cff-4485-a61c-7af1563bbd82.asp
http://windowssdk.msdn.microsoft.com/library/default.asp url=/library/en-us/WCF_samples/html/af37b260-7dec-41fd-a44c-c09297f4076a.asp
please install winfx sdk,you can download these samples from winfx sdk
-Thank you
Madhu
Jams1999
Humm... not sure these samples are doing what i need...
I mean, there is a bunch of samples about how to use one mechanism or the other but my question was about how to use both at the same time for authenticating the client.
In the Membership Provider Sample for example, it is mentionned "server authentication using the server's X509v3 certificate". By "server", does that mean the client-side server or the services server If it is the client-side (app) server, then yes i guess this is exactly what i was talking about.
Thx
-Jonathan
elpepe
Jonathan,
Here is another code that does the same thing but I think is more transparent about what needs to be done to set client transport authentication using certificate and to add username on the message-level:
public static Binding CreateBinding()
{
HttpsTransportBindingElement transportBindingElement = new HttpsTransportBindingElement();
transportBindingElement.RequireClientCertificate = true;
SecurityBindingElement securityBindingElement = new TransportSecurityBindingElement();
securityBindingElement.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
CustomBinding binding = new CustomBinding(securityBindingElement, transportBindingElement);
return binding;
}
--Jan
MalcolmB
Jonathan,
My code is RC0 based, so there may be some minor diffs between what I have and existing samples. You can probably do what you want with a standard binding if you use the TransportWithMessageCredential security mode and use Certificate at the transport level and Username at the message level but I wasn't sure what your constraints were so didn't want to limit you to https. If you can use https, let me know and I'll post some code/config that shows how to do that.
Gudge
Tika
I wanted it to be https at least between my clients and my Intermediary Router so i can get the best performance. These services will serve the content of many Web sites, so my guess (according to the documentation) is that using Https will put lesser stress on the servers. Also, P2P security of the messages is more than enough for us. Once the messages are received by the services, they don't need to be secured anymore.
Do you have any suggestion Is it something that would be possible with a custom binding or is it just impossible
Your input & help is very appreciated.
Thx
-Jonathan
Gordon Pollokoff
Thanks Gudge, it really helped. I was hitting my head trying to do that by configuring predefined bindings only without relying on code. I would have try for a long time if it would not be of your post.
I am eager to try it. Btw, while i was looking for references about some of the classes and methods you are using in your example, i found a very interesting sample in the "Extensibility samples" of the SDK named "Supporting Tokens". It looks like it is exactly doing what i need to do. The implementation is slightly different than yours though...
Here is the link for those who are interested:
http://windowssdk.msdn.microsoft.com/library/default.asp url=/library/en-us/WCF_samples/html/27dfb023-0066-494c-be4e-b4d0c3b04d22.asp
I feel bad since i never thought about looking into these extensibility samples because i thought that this scenario would have been possible with predefined bindings only...
Thx again
-Jonathan
willko
hi Gudge,
I m having an issue, so far could not found the solution. Please could you help me with this
ok the main struggle I m using the secure transport. So I dont want any extra message oriented security. here I m building binding with my STS giving my custom token parameters.
TransportSecurityBindingElement transportSecurity = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(new CustomerSecurityTokenParameters()); CustomBinding stsBinding = new CustomBinding(transportSecurity, new HttpsTransportBindingElement());However this equivalent to
transportSecurity.EndpointSupportingTokenParameters.Endorsing.Add(CustomerSecurityTokenParameters);
As I know I will using endorsing token to sign my signature and creating another signature. I dont really need this.
so I would like to have something like
transportSecurity.EndpointSupportingTokenParameters.Endorsing.Signed.Add(CustomerSecurityTokenParameters);
but I do having an error in this case. the error that my message cannot verified.
My question why I should use endorsing token. Or am I building some kind a securetokencontext which tends to substitute transport layer in message level security scenario. I m really lost here. I want to send as just supporting token not endorsing i.e no any keys been creating.
Another question would be, can I use internal RST/RSTR classes of WCF. I was using your implementation so far as many others. but I have been asked why I can tuse the RST/RSTR classes those are within the WCF.
thank you.