Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Including SAML2.0 token in WCF service call without using WIF

I'm trying to set up a WCF service protected by ADFS. I'm currently able to request a token and send it with the request using WIF and Thinktecture IdentityModel 4.5 with the following code:

static SecurityToken GetToken()
{
    var factory = new WSTrustChannelFactory(
          new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
          "https://fs2.server2012.local/adfs/services/trust/13/usernamemixed") 
    {
        TrustVersion = TrustVersion.WSTrust13 
    };


    if (factory.Credentials != null)
    {
        factory.Credentials.UserName.UserName = @"username";
        factory.Credentials.UserName.Password = "password";
    }

    var rst = new RequestSecurityToken
    {
        RequestType = RequestTypes.Issue,
        KeyType = KeyTypes.Symmetric,
        AppliesTo = new EndpointReference(
            "https://wcfservicecertificate/wcfservice/Service.svc/wstrust"),
    };

    var channel = factory.CreateChannel();
    RequestSecurityTokenResponse rstr;
    return channel.Issue(rst, out rstr);
}

With this I can call the WCF service by using ChannelFactory.CreateChannelWithIssuedToken:

var factory = new ChannelFactory<IService>(binding, 
    new EndpointAddress("https://wcfservicecertificate/wcfservice/Service.svc/wstrust"));
if (factory.Credentials != null)
{
    factory.Credentials.SupportInteractive = false;
    factory.Credentials.UseIdentityConfiguration = true;
}

var proxy = factory.CreateChannelWithIssuedToken(GetToken());
var result= proxy.GetData(2);

This works as expected but can only be used on (mobile) windows platforms. I would also like to be able to use the same principle on iOS and Android. Using this article I was able to request a security token from ADFS using the following code:

const string soapMessage =
@"<s:Envelope xmlns:s=""http://www.w3.org/2003/05/soap-envelope""
    xmlns:a=""http://www.w3.org/2005/08/addressing""
    xmlns:u=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">
    <s:Header>
        <a:Action s:mustUnderstand=""1"">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
        <a:To s:mustUnderstand=""1"">https://fs2.server2012.local/adfs/services/trust/13/UsernameMixed</a:To>
        <o:Security s:mustUnderstand=""1"" xmlns:o=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"">
            <o:UsernameToken u:Id=""uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1"">
            <o:Username>username</o:Username>
            <o:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"">password</o:Password>
            </o:UsernameToken>
        </o:Security>
    </s:Header>
    <s:Body>
        <trust:RequestSecurityToken xmlns:trust=""http://docs.oasis-open.org/ws-sx/ws-trust/200512"">
            <wsp:AppliesTo xmlns:wsp=""http://schemas.xmlsoap.org/ws/2004/09/policy"">
            <a:EndpointReference>
                <a:Address>https://wcfservicecertificate/wcfservice/Service.svc/wstrust</a:Address>
            </a:EndpointReference>
            </wsp:AppliesTo>
            <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>                        
            <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
            <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>
        </trust:RequestSecurityToken>
    </s:Body>
</s:Envelope>";


var webClient = new WebClient();

webClient.Headers.Add("Content-Type", "application/soap+xml; charset=utf-8");

var result = webClient.UploadString(
        address: "https://fs2.server2012.local/adfs/services/trust/13/UsernameMixed",
        method: "POST",
        data: soapMessage);

This results in a SAML2.0 token which I would like to send in a request to our WCF service in order to authenticate. There are various sources (including the article mentioned earlier) which state that this should be possible but I've yet to find a solution.

Any help would be appreciated.

like image 307
Wouter Roos Avatar asked Jan 22 '14 20:01

Wouter Roos


1 Answers

You can use one of hybrid solutions which use SAML with OAuth or other authorization technologies. This is more secure against phising techniques. For SAML only approach, you can refer to following link: How to pass security tokenfrom one wcf service to another wcf service. It is said that you need to enable saveBootstrapTokens property on webconfig.

This link can be useful too: Availability of Bootstrap Tokens

like image 55
Kuzgun Avatar answered Oct 18 '22 19:10

Kuzgun