Creating Delegation token - can't create a SecurityTokenService

.net-4.5, adfs2.0, c#, visual-studio-2012

Solution

I am requesting tokens from an ADFS 2.0 for caching and looking at the DisplayToken. Maybe this can help you get started.

Here is what I can up with:

    public SecurityToken GetToken(out RequestSecurityTokenResponse rstr)
    {
        Console.WriteLine("Connecting to STS...");

        WSTrustChannelFactory factory = null;

        try
        {
            if (_useCredentials)
            {
                // use a UserName Trust Binding for username authentication
                factory =
                    new WSTrustChannelFactory(
                        new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
                        "https://<adfs>/adfs/services/trust/13/UsernameMixed");

                factory.TrustVersion = TrustVersion.WSTrust13;

                // Username and Password here...
                factory.Credentials.UserName.UserName = "username";
                factory.Credentials.UserName.Password = "password";
            }
            else
            {
                // Windows authentication over transport security
                factory = new WSTrustChannelFactory(
                    new WindowsWSTrustBinding(SecurityMode.Transport),
                    "https://<adfs>/adfs/services/trust/13/windowstransport") { TrustVersion = TrustVersion.WSTrust13 };
            }

            var rst = new RequestSecurityToken
                          {
                              RequestType = RequestTypes.Issue,
                              AppliesTo = SvcEndpoint,
                              KeyType = KeyTypes.Symmetric,
                              RequestDisplayToken = true
                          };

            Console.WriteLine("Creating channel for STS...");

            IWSTrustChannelContract channel = factory.CreateChannel();

             Console.WriteLine("Requesting token from " + StsEndpoint.Uri);
             SecurityToken token = channel.Issue(rst, out rstr);
             Console.WriteLine("Received token from " + StsEndpoint.Uri);

            return token;
        }
        finally
        {
            if (factory != null)
            {
                try
                {
                    factory.Close();
                }
                catch (CommunicationObjectFaultedException)
                {
                    factory.Abort();
                }
            }
        }
    }

You might have to acivate the UsernameMixed Endpoint in your ADFS 2.0 if you want to use it and don't forget to restart the service afterwards!

Problem

I'm trying to build a system working with ADFS and claims. At the moment, this is just a "toy" implementation. I've built a very simple MVC web application, set it up using the "Identity and Access..." wizard in Visual Studio to talk to an ADFS 2.0 server, and deployed it to an IIS server. All works fine, and I can examine and list the received claims. The next step is to build a Web API based REST service (representing back-end services that the MVC application is going to depend on), so I want to pass the credentials across to that back-end server so that it can make suitable authorization decisions. So the first step is for me to create the delegation token (and I'll then, hopefully, work out what to do with it in terms of the `HttpClient` class to make the rest call). I've got this: ``` //We need to take the bootstrap token and create an appropriate ActAs token var rst = new RequestSecurityToken { AppliesTo = new EndpointReference("https://other-iis.example.com/Rest"), RequestType = RequestTypes.Issue, KeyType = KeyTypes.Symmetric, ActAs = new SecurityTokenElement(((BootstrapContext)((ClaimsIdentity)User.Identity).BootstrapContext).SecurityToken) }; var sts = new SecurityTokenService(); //This line isn't valid var resp = sts.Issue(System.Threading.Thread.CurrentPrincipal as ClaimsPrincipal, rst); ``` But, the issue is that `SecurityTokenService` is abstract. I can't find any types derived from this class in either `System.IdentityModel` nor `System.IdentityModel.Services`, and the above doesn't include any reference to the ADFS server which I'll obviously need to provide at some point. Of course, I may be going down completely the wrong route also, or am just hitting a minor stumbling block and not seeing a much larger one looming in the distance, so any advice on that would be appreciated also. I've looked at, for example, Identity Delegation Scenario, but that uses `CreateChannelActingAs`, which I don't think is going to work when I'm talking to a rest service (or will it?), and also doesn't seem to apply to .NET 4.5.

Original source