Welcome to MSDN Blogs Sign in | Join | Help

Milet's Logbook

BizTalk, .NET development, and more
Flowing credentials through BizTalk

Scenario: You  have a client application, with a user logged on with a domain user ( kerberos credentilas ). The application calls a BizTalk Server 2004 orchestration ( a business process ) that calls a Back End Web Service. The Web Service needs to know who is the logged user to take a decision on which task it has to execute.

Solution: Extract from the input message the OriginatorSID context property (that
contains the LogonUser string ) then impersonate it using a helper
component :

for example with an expression shape like this:
bizImpHelper.Impersonate(IncomingMessage(Microsoft.BizTalk.XLANGs.BTXEngine.OriginatorSID));

This is the helper class that does the impersonation:

[Serializable]
public class BizTalkImpersonationHelper
{
  private BizTalkImpersonationContext bizImpCtxt;
  public BizTalkImpersonationHelper()
  {}

  public void Impersonate( string logonUser )
  {
    int slash = logonUser.IndexOf("\\");
    if( slash > 0 ){
           string domain = logonUser.Substring(0,slash);
           string user = logonUser.Substring(slash+1);
           logonUser =  user + "@" + domain;
     }
     bizImpCtxt = new BizTalkImpersonationContext();
     bizImpCtxt.Impersonate(logonUser);
  }

   public void UnDo()
   {
      if( bizImpCtxt != null )
         bizImpCtxt.Undo();
   }
}

[Serializable]
internal class BizTalkImpersonationContext
{
   private System.Security.Principal.WindowsIdentity identity;
  [ThreadStatic]
  static WindowsImpersonationContext wic ;
  internal void Impersonate( string logonUser )
  {
     if( wic != null )
         wic.Undo();
     identity = new System.Security.Principal.WindowsIdentity(logonUser);
     wic =
((System.Security.Principal.WindowsIdentity)identity).Impersonate();
  }

  internal void Undo()
  {
    if( wic != null)
       wic.Undo();
  }
}
 
Declare the WindowsImpersonationContext thread static, to avoid
collisions between different running orchestrations.

In the orchestration you should define a scope to:

1. Impersonate the caller
2. Send the message and receive the response
3. Undo the impersonation to restablish the biztalk service security context

In the exception handler
Undo the impersonation

Note that the BizTalk host has to run under a domain account, that you have to create a service principal name for that account, and configure it to be trusted for delegation to the specified service


A better approach maybe is to encapsulate that logic inside a pipeline
component, that you can apply to any send port that needs to flow
credentials.

Posted: Friday, February 13, 2009 4:54 PM by pierreml
Attachment(s): ad.png

Comments

M.Papas said:

Hi Pierre.

I tried following your recepie for flowing credentials through biztalk, but I did not get it to work. When I do the impesonation through the helperclasses above the Biztalk Host shuts down with the following error:

"An error occurred that requires the BizTalk service to terminate. The most common causes are the following:

1) An unexpected out of memory error.

OR

2) An inability to connect or a loss of connectivity to one of the BizTalk databases.

The service will shutdown and auto-restart in 1 minute. If the problematic database remains unavailable, this cycle will repeat."

Seems to me that the second option in the error message is causing this to happen because of the impersonation.

Do you have any ideas about why this is happening?

If you have a sample/example project where you have implemented the scenario you describe in your blog, it would be very helpful if I you could send it to me (mpapas @ gmail . com) or post it through your blog.

Cheers,

M.Papas

# November 13, 2009 4:20 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker