How to pass custom object between WCF client app and custom issued security token provider

There are two options:

1. OperationContext.Current.

Pros: This is pretty straightforward and relatively hard to discover. 

Cons: This is a thread local storage, and you are invoking a async call, it does not work well.

2. ChannelParameterCollection

This is very sneaky. You will need to add the object to channel first in your client app code,

                                // add the token to the channel parameter collection

                               ChannelParameterCollection parm = (ChannelParameterCollection)( (IChannel)client ).GetProperty<ChannelParameterCollection>();

                parm.Add( myState);

Then you can retrieve it from the requirement, and set it on the custom token provider

public override SecurityTokenProvider CreateSecurityTokenProvider( SecurityTokenRequirement tokenRequirement )

        {

            // retrieve the ChannelParameterCollection from the token requirements

                                ChannelParameterCollection collection = null;

                if ( !tokenRequirement.TryGetProperty<ChannelParameterCollection>( ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty, out collection ) )

                {

                    Console.WriteLine( "could not found ChannelParameterCollection" );

                }

                  // now add the collection to your issuedsecuritytokenprovider

            CustomIssuedSecurityTokenProvider federationTokenProvider = new CustomIssuedSecurityTokenProvider(collection);

}

The last step is to simply retrieve it from the BeginGetTokenCore() method

 public class CustomIssuedSecurityTokenProvider : IssuedSecurityTokenProvider

    {

        ChannelParameterCollection _collection;

        /// <summary>

        /// Constructor

        /// </summary>

        public CustomIssuedSecurityTokenProvider(ChannelParameterCollection collection)

            : base()

        {

            _collection = collection;

        }

        ChannelParameterCollection Collection

        {

            get

            {

                return _collection;

            }

        }

        protected override IAsyncResult BeginGetTokenCore( TimeSpan timeout, AsyncCallback callback, object state )

        {

            foreach ( object o in _collection )

            {

                if ( o is someType)

                {

                    // turn it into your type

                }

            }

           

            …

        }

}

Hope it helps