Here's something very weird I had noticed.
I'm writing a CRM 2011 Silverlight extension and, well, all is fine on my local development instance. The application uses OData to communicate, and uses System.Threading.Tasks.Task a lot to perform all the operations in the background (FromAsync is a blessing).
However, I decided to test my application in CRM 2011 Online and found, to my surprise, that it would no longer work; I would receive a Security Exception when ending retrieve tasks.
Using Fiddler, I found that CRM is trying to redirect me to the Live login page, which didn't make much sense, considering I was already logged in.
After some more attempts, I found that the errors were because I was accessing the service from a different thread than the UI thread.
Here's a quick example:
    //this will work
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        var query = ctx.AccountSet;
        query.BeginExecute((result) =>
        {
            textBox1.Text = query.EndExecute(result).First().Name;
        }, null);
    }
    //this will fail
    private void button2_Click(object sender, RoutedEventArgs e)
    {
        System.Threading.Tasks.Task.Factory.StartNew(RestAsync);
    }
    void RestAsync()
    {
        var query = ctx.AccountSet;
        var async = query.BeginExecute(null, null);
        var task = System.Threading.Tasks.Task.Factory.FromAsync<Account>(async, (result) =>
        {
            return query.EndExecute(result).First(); // <- Exception thrown here
        });
        textBox1.Dispatcher.BeginInvoke(() =>
        {
            textBox1.Text = task.Result.Name;
        });
    }
It seems almost obvious that I'm missing some fundamentals on how threads use permissions. Since using a separate thread is preferable in my case, is there any way to "copy" the permissions / authentication? Perhaps some sort of impersonation?
EDIT: In case anyone else is struggling with this, using other threads (or Task, as the case may be) is possible as long as query.BeginExecute(null, null); is executed on the UI thread. You need a way to retrieve the returned IAsyncResult back to the calling thread, but you can do that using a ManualResetEvent.
But I'd still like to know why the darned permissions / authentication isn't shared between the threads...
 
     
    