9
votes

I need to write a desktop based client application which does some web service method calls to a SharePoint server, after doing a SAML based SSO authentication.

I found that SAML SSO is mostly used from the browser which takes care of all the details. According to this question, it seems there is a technology in SAML 2.0 called ECP just for enabling non browser based clients.

Yet some applications like SharePoint 2010/2013 only support SAML 1.1; what can be used in this case?

1
Fundamentally SAML doesn't require client to be a browser. Essentially "browser" here is just a client that knows how to follow redirects so it can be done by any sufficiently elaborated client. Still the devil is in the details, particularly if HTTP POST redirect is involved into SAML authentication (which will most certainly be the case). Further details might depend on the particular technology you use.SergGr
You have not mentioned any constraint on technology. Perhaps Electron could help: it's a non-non-browser (☺) framework for creating desktop applications... it will handle cookies & follow redirects just well.Hugues M.

1 Answers

2
votes

You haven't mentioned technology - i can share my experience. We're required to have a SSO in the desktop application (WPF) that is using the WCF services. I have started with infomation from this link. The solution is to use WIF for retrieving the SAML token from identity provider and using it to establish the connection to our backend server.

  1. To obtain the token

    WSTrustChannelFactory GetTrustFactory()
    {
        var binding = new WS2007HttpBinding(TrustChannelBindingConfiguration);
        return new WSTrustChannelFactory(binding, StServiceUri);
    }
    
    SecurityToken GetTokenFromSts()
    {
        using (var trustFactory = GetTrustFactory())
        {
            // here is the code to set trustFactory.Credentials
            trustFactory.TrustVersion = TrustVersion.WSTrust13;
            var rst = new RequestSecurityToken
                      {
                          RequestType = RequestTypes.Issue,
                          AppliesTo = new EndpointReference(YourServiceUri),
                          KeyType = KeyTypes.Bearer
                      };
    
            var channel = (WSTrustChannel) trustFactory.CreateChannel();
            try
            {
                return channel.Issue(rst);
            }
            catch (MessageSecurityException msex)
            {
                channel.Abort();
                throw new EMException(msex.InnerException.Message, msex);
            }
        }
    }
    
  2. Then the obtained token is used in service calls:

    securityToken = GetToken();
    
        // 2. Create a channel with issued token to YourServiceInterface
        // create binding and turn off sessions
        var binding = new WS2007FederationHttpBinding(FederationBinding);
    
        try
        {
            var factory = new ChannelFactory<YourServiceInterface>(binding,
                              new EndpointAddress(YourServiceUri));
    
            factory.Credentials.SupportInteractive = false;
    
            var channel = factory.CreateChannelWithIssuedToken(securityToken);
    
            // 3. Call YourMethod() on secured channel
            return channel.YourMethod();
    }
    catch {...}
    

The main approach from the link hasn't been really changed - we just added token caching and incorporated this code in our channel handling framework. The code is used to authenticate desktop client against ADFS server and use claims in our backend server for authorizations.