Nielsen's Weblog : .NET [use your Context dude]
Updated: 09-04-2008; 19:36:13.

 

Home

Subscribe to "Nielsen's Weblog" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.

 
 

9. april 2008

Just back from Vietnam yesterday, jetlag... darn tired. Next week I am taking some time off, going to London on a small vacation...so what's up in London ?

Essential Windows Workflow Foundation

what else is there to do in London ?

:-D


7:32:02 PM    comment []

23. januar 2008

The project we're working on currently is using ServiceAuthorizationManager for authorizing incoming request.

 

The current implementation is expecting the RequestMessage.Headers.Action field to contain the incoming soap action. Here is the catch, if you have a method that is decorated with IsOneWay=true, then guess what the RequestContext is null!...

 

This makes sense as one way calls is not the usual request/response pattern, but it sure did break our implementation :).

 

So a quick fix would be to look at the IncomingMessageHeaders instead like this:

 

  for (int i = 0; i < operationContext.IncomingMessageHeaders.Count; ++i)

  {

      MessageHeaderInfo h = operationContext.IncomingMessageHeaders[i];

      if (h.Name == "Action")

      {

          XmlReader xr = operationContext.IncomingMessageHeaders.GetReaderAtHeader(i);

          action = xr.ReadElementContentAsString();

 

 

BTW. Happy new year!, we spend the holidays in New York. We stayed at the Hilton Millenium on 54th floor. Amazing view, we had the governor suite (I think it was called that way). On my right side we could see the Brooklyn bridge, strait out the window we could see the Empire State Building (upper Manhattan) and on our left side we had the Statue of Liberty and of course Ground Zero.

 

Okay I don't get it, what fun is it standing on Times Square from 13.00 to 23.59 waiting for a ball drop ?!? J. Well glad I was watching this from my room instead J. We're definitely going to visit New York again.

 

Start spreading the news I'm leaving today … .


2:39:41 PM    comment []

22. september 2007

 

Say you are doing a banking SmartClient application, people finally got tired of phissing and "fat" clients is the answer here.

Now my SmartClient uses WCF (duh) as the communication infrastructure between the end user and the bank. The end user is presented with the usual login box + some extra security id RSA key she must enter.

The credentials is then stored in memory and each time I call out to my WCF proxy I pass in those credentials + the extra rsa custom token. I am holding on to the username token in memory using SecureString of course.

So here is my concern, say I am holding on to my session aware channelfactory for many reasons, performance amongst other things. Obviously I have to set the Username and Password on the channel, fine but the UserNamePasswordClientCredential class uses string to hold my identity!! WTF. Great eh, out goes the SecureString idea.

We're not talking about securing the token when it crosses the wire, that part is secured, but I am talking about the fact that my password and username is visible to prying eyes in memory, the second I set my credentials on the channelfactory.

Might not be a big deal, but why not use SecureString on the UserNamePasswordClientCredential in the first place!.

I might be missing the obvious reason as why UserNamePasswordClientCredential is designed like this, comments are welcome here.

Btw: a possible implementation of the cached identity could be written like this (given the fact that UserNamePasswordClientCredential uses System.String ;-)).

public sealed class CacheClientCredentials

{

        private static SecureString usr = new SecureString();

        private static SecureString  pwd= new SecureString();

 

        public static string UserName

        {

            get  { return SecureStringToString(usr); }

            set

            {

                char[] chars = value.ToCharArray();

                foreach (char c in chars)

                    usr.AppendChar(c);

                usr.MakeReadOnly();

            }

        }

 

        public static string Password

        {

            get { return SecureStringToString(pwd);  }

            set

            {

                    char[] chars = value.ToCharArray();

                    foreach (char c in chars)

                        pwd.AppendChar(c);

                    pwd.MakeReadOnly();

            }

        }

 

        private  static string SecureStringToString(SecureString value)

        {

            IntPtr bstr = Marshal.SecureStringToBSTR(value);

            try

            {

                return Marshal.PtrToStringBSTR(bstr);

            }

            finally

            {

                Marshal.FreeBSTR(bstr);

            }

        }

    }

The average, healthy, well-adjusted adult gets up at seven-thirty in the morning feeling just plain terrible.
    -- Jean Kerr


10:41:57 AM    comment []

19. september 2007

Sigh, it's the client proxy that throws the exception.

We have setup the usual universal error handler implementing the IErrorHandler interface, all good I figured.

The ProvideFault implementation is strait forward, if any exception occurs, wrap it up in a FaultException and return that to the client. I believed that this was it, no faulted channels on my shift and client was happy.

The problem we ran into was the implementation of the ProvideFault. The symptoms was that, when ever a SecurityAccessDeniedException was thrown, the client would catch that exception and show a localized message to the enduser, except the client never got the SecurityAccessDeniedException, it got an untyped FaultException!.

The reason why is actually obvious, if the exception thrown by the service is already an exception derived from the CommunicationException aka a FaultException, the ProvideFault should of course not wrap that fault up into yet another FaultException, it should simply just return from the ProvideFault and let the faultexception travel.

So the implementation must have the following check:

public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)

{

       if (error is FaultException)

           return;

this way the faultexception is propagated to the client proxy and then the client proxy will turn the FaultException into the SecurityAccessDeniedException and then re throw it.


My theory is that all of Scottish cuisine is based on a dare.
-- Mike Myers


4:43:54 PM    comment []

15. september 2007

Back from Vietnam. I survived the first 6 days without any stomach trouble, but then oh boy... for another 5 consecutive days I was in deep shit sort of speak. Long live Coca Cola!.

 

Okay we ran into the TimeStampHasCreationTimeInFuture, cool. Now it's not possible to extend the default bindings with the maxClockSkew setting, so you have to resort to custom bindings.

 

We are using basicHttpBinding for maximum interoperability, so creating a similar custom binding given this default binding here:

 

<basicHttpBinding>

        <binding name="basic">

          <security mode="TransportWithMessageCredential">

            <message clientCredentialType="UserName"/>

          </security>

        </binding>

      </basicHttpBinding>

 

is strait forward converting this into a custom binding like this:

 

       <customBinding>

        <binding name="basic">

          <security authenticationMode="UserNameOverTransport">

            <localClientSettings maxClockSkew="00:10:00"/>

            <localServiceSettings maxClockSkew="00:10:00"/>

          </security>

          <textMessageEncoding messageVersion="Soap11"/>

          <httpsTransport/>

        </binding>

      </customBinding>

 

First you apply the security element which enables you to set the maxClockSkew values.

 

MaxClockSkew has a default value of 5 minutes and using svcutil to generate the client config, it stays that way ;-), correct svcutil does not pick up the server side values so you would have to set them manually afterwards.

 

Next we setup the mandatory encoding element and the soap version, in our case we use text encoding and soap 1.1 for maximum interoperability with external clients.

 

We finish our custom binding with specifying the mandatory transport element, which in our case is HTTPS securing a username token.

 

Off topic:

Say you're not concerned about interoperability but instead are picking a battles with the paranoid it-guys responsible for the all the firewalls in the company. These guys tends to lock down every port but port 80, 443. <rant>They even close port 1433 behind firewalls forcing us to write "rpc" services! don't get me started. ;-)</rant>

 

In situations like that I would recommend using a custom binding also but with a binary encoding instead.

 

For example given the above bindings you could build your custom binding exactly the same way but with a binary message encoding instead.

 

       <customBinding>

        <binding name="basic">

          <security authenticationMode="UserNameOverTransport">

            <localClientSettings maxClockSkew="00:10:00"/>

            <localServiceSettings maxClockSkew="00:10:00"/>

          </security>

          <binaryMessageEncoding />

          <httpsTransport/>

        </binding>

      </customBinding>

 

Performance is optimal with the binary encoder and you keep the it-guys happy.

 

"As long as you're going to be thinking anyway, THINK BIG."


- Donald Trump

 


9:38:38 PM    comment []

13. juli 2007

 

Say you have a service which requires a UsernameToken, the client would be responsible for passing in this token. Where do you get this token from, well usually the user is prompted for her credentials. There is the standard UI dialogbox for this kind of thing here.

               

So let's try and complicate things a bit by NOT just passing in the username and password on the proxy.ClientCredentials.UserName.UserName, oh no, not this time.

Now the WCF team have provided us with this little (rarely used imo) interface called IInteractiveChannelInitializer

 

This interface helps us implement the "lets bother the user with a tedious login box" but BEFORE a channel is opened, this is the key thing to remember here and the sole motivation for this interface.

 

The documentation on this interface is rather weak and I completely missed out on the fact that I had to implement a ClientCredentialsSecurityTokenManager also, so I got some hard to understand exceptions on my first implemention.

 

Okay the basic song goes like this, create a class that derives from ClientCredentials and override the ApplyClientBehavior by adding your own class which implements the IInteractiveChannelInitializer interface… and yes override the CreateSecurityTokenManager with your own SecurityTokenManager (I messed that part up initially).

 

So a sparse implementation of the ClientCredentials would turn out this way :

 

public class ClientCredentialsEx : ClientCredentials

{

    public ClientCredentialsEx(): base() {}

    public ClientCredentialsEx(ClientCredentialsEx other): base(other){}

    public override SecurityTokenManager CreateSecurityTokenManager()

    {

        return new MyClientCredentialsSecurityTokenManager(this);

    }

 

public override void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)

    {

            behavior.InteractiveChannelInitializers.Add(new ShowCredentialsUI());

            base.ApplyClientBehavior(serviceEndpoint, behavior);   

    }

    protected override ClientCredentials CloneCore()

    {

        return new ClientCredentialsEx(this);

    }

}

 

 

And then your implementation of the IInteractiveChannelInitializer

Would look something like this, note I didn't go all the way with the standard CreUIPromptForCredentials dialogbox, google it.

 

public class ShowCredentialsUI : IInteractiveChannelInitializer

{

    public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel,

AsyncCallback callback, object state)

    {

        //call the CredUIPromptForCredentials and get back a user and password.

        ChannelParameterCollection col = channel.GetProperty<ChannelParameterCollection>();

col.Add(new System.Net.NetworkCredential(username, password));       

return new AsyncResult();

    }

 

    public void EndDisplayInitializationUI(IAsyncResult result)

    {

        AsyncResult ar = (AsyncResult)result;

        ar.isCompleted = true;

    }

}


 

 

Now a very sparse implemention of the IAsyncResult, I blogged about this long time ago.

 

public class AsyncResult : IAsyncResult

{

    public bool isCompleted = false;

 

    public object AsyncState

    {

        get { throw new Exception("The method or operation is not implemented."); }

    }

 

    public System.Threading.WaitHandle AsyncWaitHandle

    {

        get { throw new Exception("The method or operation is not implemented."); }

    }

 

    public bool CompletedSynchronously{get{return true;}}

 

    public bool IsCompleted { get { return isCompleted; }

    }

}

 

 

Now for the implementation of the custom ClientCredentialsSecurityTokenManager.

The crux of this is you would dig out the NetworkCredential from the ChannelParameterCollection which was set by the BeginDisplayInitializationUI.

 

class MyClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager

{

    public MyClientCredentialsSecurityTokenManager(ClientCredentials parent): base(parent){}

   

    public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)

    {

        if (tokenRequirement.KeyUsage == SecurityKeyUsage.Signature)

        {

            NetworkCredential token = null;

            ChannelParameterCollection obj = (ChannelParameterCollection)tokenRequirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty];

            token = obj[0] as NetworkCredential;

            if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)

            {

                return new MyUsernameSecurityTokenProvider(token);

            }

        }

        return base.CreateSecurityTokenProvider(tokenRequirement);

    }

 

My custom SecurityTokenProvider which just creates the UserNameSecurityToken for the channel to use.

 

    class MyUsernameSecurityTokenProvider : SecurityTokenProvider

    {

        NetworkCredential cre = null;

        public MyUsernameSecurityTokenProvider(NetworkCredential credentials)

        {

            this.cre = credentials;

        }

        protected override SecurityToken GetTokenCore(TimeSpan timeout)

        {

            UserNameSecurityToken token = new UserNameSecurityToken(cre.UserName,cre.Password);

            return token;

        }

    }

 

Now that was easy, all we need todo now is to hook up our new behavior on the proxy. This can be done in many ways, I choose to override the ClientBase which then would add our new "lets bother the user with a tedious login box". This is a matter of replacing the standard ClientCredentials class on the proxy behaviour, with our own IEndpointBehavior implemented by our custom ClientCredentialsEx class like this:

 

public partial class PartnerSubscriptionProxy : ClientBase<IPartnerSubscriptionService>, IPartnerSubscriptionService

{

        public PartnerSubscriptionProxy(string address)

        {

            Endpoint.Address = new EndpointAddress(address);

            Endpoint.Behaviors.Remove< ClientCredentials >();

            Endpoint.Behaviors.Add(new ClientCredentialsEx());

        }

......

 

Right so all you have to do now is just invoke the proxy and call out to a method, this will invoke our ui box before the channel is opened giving the user a chance to think real hard about her credentials (which btw. always can be found on that yellow slip on your desk).

"Some cause happiness wherever they go; others, whenever they go."
 --Oscar Wilde


8:45:57 PM    comment []

2. april 2007

I think Microsoft did a great job with WCF, totally in love with this framework.

 

For years I have been using an xsd editor when designing my asmx messages, this is no different when choosing WCF as your favorite communication framework.

 

My frustration is when you design your xsd's and set the max occurs to unbounded on any simple type or complex type, the code generated by the svcutil sucks big time.

 

Take for instance this xsd:

 

<?xml version="1.0" encoding="utf-16"?>

<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://datacontract/2007/03/OrderMessage" elementFormDefault="qualified" targetNamespace="http://datacontract/2007/03/OrderMessage" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="OrderMessage" nillable="true" type="OrderMessage" />

  <xs:complexType name="OrderMessage">