2

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.

gbs
  • 7,196
  • 5
  • 43
  • 69

2 Answers2

1

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.

Community
  • 1
  • 1
Mitch
  • 21,223
  • 6
  • 63
  • 86
  • Mitch, Your suggestion has got me a step further than I was before but getting this error now: ID3242: The security token could not be authenticated or authorized. – gbs Nov 05 '14 at 17:08
  • @gbs, I assume you mean you are getting that error when you try to use the token you receive. ID3242 is typically caused by the wrong audience uri being specified. Make sure your `AppliesTo` matches what the STS expects, and what the RP is configured to accept. The other thing it can be is that the signing or encryption certificates configured on the STS do not match the RP. – Mitch Nov 06 '14 at 00:07
  • Not using but on requesting the token. STS is sending me that error. I have sent that to the provider and they are looking into it as well. – gbs Nov 06 '14 at 00:28
  • @gbs, did you ever find the solution? It is apparently not a problem I have seen before, and would be interested in how you solved it. – Mitch Nov 10 '14 at 03:19
  • Not yet. I am waiting on provider as they are also looking into their ADFS. I will update as soon as I get more info and/or get it working. – gbs Nov 10 '14 at 17:37
  • The provider gave me new certificate and service endpoint. Also had to update your code to use CertificateWSTrustBinding(SecurityMode.TransportWithMessageCredential) and that all made it work. I have now to deal with second step if you have any idea: http://stackoverflow.com/questions/26857808/using-saml-token-with-web-service-wsdl – gbs Nov 11 '14 at 05:02
0

Here you go.

private static SecurityToken RequestSecurityToken()    
{    
    // set up the ws-trust channel factory    
    var factory = new WSTrustChannelFactory(    
        new UserNameWSTrustBinding(
          SecurityMode.TransportWithMessageCredential),    
          _idpAddress);    
    factory.TrustVersion = TrustVersion.WSTrust13;            

    var authCertificate = X509.LocalMachine.My.Thumbprint.Find(Properties.Settings.Default.RassCertificateThumbprint).FirstOrDefault();
    if (authCertificate == null)
        throw new InternalException(String.Format("No atuhentication certificate found in store with thumbprint {0}.", Properties.Settings.Default.ClientCertificateThumbprint));

    // overenie je na zaklade certifikatu RASS
    factory.Credentials.ClientCertificate.Certificate = authCertificate;

    // create token request  
    var rst = new RequestSecurityToken    
    {    
        RequestType = RequestTypes.Issue,
        KeyType = KeyTypes.Symmetric,    
        AppliesTo = new EndpointReference(_serviceAddress.AbsoluteUri)    
    };

    // request token and return
    return factory.CreateChannel().Issue(rst);    
}

BTW: @Mitch is right about access to the private key. I just took your method and replaced few lines of code.

pepo
  • 8,644
  • 2
  • 27
  • 42
  • pepo, I am following mitch's suggestion and updated my code above but now I am getting an error. – gbs Nov 05 '14 at 17:08
  • Where do you get this error. Is it on `SecurityToken token = channel.Issue(rst, out rstr);` or when you try to use the received token. – pepo Nov 05 '14 at 19:12
  • Do you have access to the private key of the certificate? – pepo Nov 05 '14 at 19:27
  • I think I should have. I got .pfx file from provider with a password. In any case how do I get to that key? Oh and I actually gave Everyone permission to the Certificate in the store as per Mitch's link above. And when I Imported the .pfx in the store I did select "Allow private key to be exported" – gbs Nov 05 '14 at 19:39
  • `X509certificate2` class has a property PrivateKey. If you can access it (i.e. in debug mode in visual studio) then you have access to it. Also check if the certificate is trusted. In mmc console go for details of the certificate and see if you have whol certificate chain. – pepo Nov 05 '14 at 19:41
  • Can you explain the last part of chain? – gbs Nov 05 '14 at 19:45
  • It should look like [this](https://www.sslshopper.com/ssl-certificate-errors.html) in certificate details. If you do not have CA certificates from certificate chain in store it will look different. – pepo Nov 05 '14 at 19:49
  • I do see 3 nodes as in the link image and it also says at the bottom Certificate is Ok. I have sent the provider my error and they are also investigating on their end. Any other pointers? – gbs Nov 05 '14 at 20:56