Using of Impersonation with DataServices

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

When working with web services and ADO.NET services (O-data) you will sometimes have requirement to invoke ADO.NET Data Service from one service.
For example, imagine there is a Silverlight application which invokes some operation DoSomething on Service1. Now imagine the Silverlight application has line of code which invokes the ADO.NET Data Service:

JdMasterEntities ctx = new JdMasterEntities(this.m_JdMasterUri);

var
query = from user in ctx.Entity select user;

IEnumerable<Entity> list = dataQuery.Execute();

return ctx;

If your service operation DoSomething uses impersonation (Link I, Link II) all will work fine, because the browser network stack in Silverlight does this for you.
This is example of using of impersonation:

// Here you need to impersonate imperatively later in code.
[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
public QueryTransportResponse DoSomething(QueryTransportRequest query)

or

// WCF impersonates for you declaratively.
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public QueryTransportResponse DoSomething(QueryTransportRequest query)

The browser do it for you means the browser prepares the token of interactive user for impersonation before request is sent to service. If you didn;t understand what this means take a look on next example. Imagine you write the application which needs to invoke DoSomething. Because you know that DoSomething will perform impersonation you have to send the toke which can be impersonated.
 
To make this working do following:

MyProxyClient proxy = new MyProxyClient()

// If the service needs to access resources at its local machine. For example to invoke the ADO.NET data service
// which is hosted at the same machine as Service1 (implements operation DoSomething).
proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

or

// If the service needs to access resources at some other machine. For example if the ADO.NET data service is hosted at other machine
// than Service1.
proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;


proxy
.DoSomething();


If you want to invoke the ADO.NET data service from some service operation you will do it as follows:

JdMasterEntities ctx = new JdMasterEntities(this.m_JdMasterUri);

var
query = from user in ctx.Entity select user;

DataServiceQuery<Entity> dataQuery = (DataServiceQuery<Entity>)query;

IEnumerable<Entity> list = dataQuery.Execute();

return ctx;

But if the ADO.NET data service requires windows authentication you need to append credentials to web request.

ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;

The question is now what credentials will be used when you setup DefaultCredentials? The typical architect answer is “It depends” :)

The value of default is following call:

System.Security.Principal.WindowsIdentity.GetCurrent()

Whatever this is it will be passed as credentials to the next hop (in this case ADO.NET data service). By default (if no impersonation is used) this is the pool identity like "IIS APPPOOL\\DefaultAppPool".

If the operation DoSomething allows impersonation, but not requires (see example above) you need to do imperative impersonation:

if (Thread.CurrentPrincipal.Identity is WindowsIdentity)
{
 
using (((WindowsIdentity)Thread.CurrentPrincipal.Identity).Impersonate())
 
{
    . . . call to ado.net data service . . .
     // System.Security.Principal.WindowsIdentity.GetCurrent() 
     // gives: DOMAIN\user_who_open_the_browser_which_invoked_DoSomething_within_Silverlight_application.

  }
}

If the ADO.NET data service is permitted for anonymous users of for the application pool user, you do not have to do anything.
If the ADO.NET data service is permitted for specific windows users who started the Silverlight application you need to impersonate.

this is why the answer was “It depends”.


Posted Dec 23 2009, 01:00 AM by Damir Dobric
Filed under:

Comments

Damir Dobric Posts wrote DataServices 0x80070006 error
on 01-26-2010 13:59

When working with Ado.Net data services you may get following error. Could not load file or assembly

DamirDobric wrote DataServices 0x80070006 error
on 01-26-2010 15:03

When working with Ado.Net data services you may get following error. Could not load file or assembly

Things I’ve learned today. « Brad Tillman's Blog wrote Things I&#8217;ve learned today. &laquo; Brad Tillman&#039;s Blog
on 08-10-2010 23:23

Pingback from  Things I’ve learned today. « Brad Tillman's Blog

n674 sex iqvh wrote re: Using of Impersonation with DataServices
on 07-03-2011 4:26

Using of impersonation with dataservices.. Awesome :)

developers.de is a .Net Community Blog powered by daenet GmbH.