Search code examples
wcfwifsamlws-trust

How to pass a certificate to WSTrust to get Saml Token


Here is an example of getting tokem using WSTrustChannelFactory. From here.

var stsBinding = new WS2007HttpBinding();
stsBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
stsBinding.Security.Message.EstablishSecurityContext = false;
stsBinding.Security.Message.NegotiateServiceCredential = false;
stsBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;


WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(
    stsBinding
    , new EndpointAddress(tokenurl)
    );
trustChannelFactory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13;

X509Store myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection coll = myStore.Certificates.Find(X509FindType.FindBySerialNumber, "MycertSerialNumber", true);
X509Certificate2 cert = coll[0];
trustChannelFactory.Credentials.ClientCertificate.Certificate = cert;

WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();

RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue, keyType);
rst.AppliesTo = new EndpointAddress(realm);
RequestSecurityTokenResponse rstr = null;
rst.TokenType = SecurityTokenTypes.Saml;

SecurityToken token = channel.Issue(rst, out rstr);

Now I don't have a username/password but the provider has given me certificate .pfx file. How do I pass it to the WSTrushChannelFactory? I have tried using CertificateBinding but no success.

Updated Code above: 11/05/2014:

Getting this error: ID3242: The security token could not be authenticated or authorized.


Solution

  • Use the ClientCertificate property:

    var stsBinding = new WS2007HttpBinding();
    stsBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
    stsBinding.Security.Message.EstablishSecurityContext = false;
    stsBinding.Security.Message.NegotiateServiceCredential = false;
    
    // select the authentication mode of Client Certificate
    stsBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
    
    var wifChannelFactory = new WSTrustChannelFactory(stsBinding, stsEndpoint);
    wifChannelFactory.TrustVersion = TrustVersion.WSTrust13;
    
    // Supply the credentials
    wifChannelFactory.Credentials.ClientCertificate.Certificate = config.Certificate;
    

    The PFX you can import to your certificate store via the certmgr.msc snapin. Make sure that the account your application is running as has access to the private key. You can reference it in the store using the x509certificate2 classes.