# Wednesday, November 25, 2009

Windows Identity Foundation introduces a new ClaimTypes class. It contains predefined claim type URIs for claims defined by OASIS and Microsoft. In the WIF SDK project templates for a custom STS this ClaimTypes class is mixed with the one already in System.IdentityModel.Claims, which is rather confusing. So, what's the difference?

Functionally: None. All claim type URIs in Microsoft.IdentityModel.Claims.ClaimTypes are identical to corresponding types in System.IdentityModel.Claims.ClaimTypes. That said, Microsoft.IdentityModel.Claims.ClaimTypes adds a few new claim types.

Technically: Claim types in System.IdentityModel.Claims.ClaimTypes are defined as static read only string properties, whereas in Microsoft.IdentityModel.Claims.ClaimTypes the claim types are string constants.

My advice: for clarity always use Microsoft.IdentityModel.Claims.ClaimTypes.

Wednesday, November 25, 2009 1:33:08 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 19, 2009

Windows Identity Foundation, formerly known as "Geneva", has shipped. I've been talking about Geneva/WIF on several occasions and I absolutely love it. It opens the door for a whole new realm of authentication/authorization scenario's. SharePoint 2010 will be the first Microsoft Product to support it, apart from the new Active Directory Federation Services 2.0, which was part of the development effort and was formerly known as "Geneva" Server. Be sure to check it out!

Thursday, November 19, 2009 3:09:16 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, November 17, 2009

Komende zaterdag is Code Camp en daar zal ik een sessie doen over Windows Identity Foundation, de nieuwe basis voor beveiliging. Kom je ook? Het is gratis.

Tuesday, November 17, 2009 12:03:58 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 12, 2009

As an MVP I've had the fortune of being involved early in the VS2010 beta. Because the number of beta participants is relatively small in the beginning, Microsoft is able to have a much more interaction with the testing population and excplicitly goes out for feedback and discussion of some of the features. VS2010 is a great example of Microsoft putting that to good use. Something simple like the Add Reference dialog has improved greatly in VS2010, as Scott Guthrie explains here. I remember the discussion about it, because there were quite a few different ideas about what should come up first and what you use the most. As you can see, Microsoft decided that the Projects tab is the most likely to be used first, so I'm assuming most developers agree on that (I do anyway).

BTW, the rest of the series on VS2010 and .NET 4.0 provides a good overview of what you can expect of the new release.

Thursday, November 12, 2009 2:37:54 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, September 02, 2009

I was working on this little app I wrote a while ago and wanted to add some features requiring (de)serialization. So, I took the original class and made it a DataContract so I could use it with the DataContractSerializer. The class then looked more or less like this:

[DataContract]
public class MyClass
{
    List<Trip> m_Items = new List<Item>();

    [DataMember]
    public IList<Item> Items
    {
        get { return m_Items; }
    }
}

Serialization went fine, but when I tried to deserialize the same object, I got a null reference exception. Of course you say, you should have added a method tied to de OnDeserializing event, because the constructor of the object doesn't work and hence the m_Items field is never initialized. The code I added to solve this looked like this:

[OnDeserializing]
protected void Init(StreamingContext context)
{
    m_Items = new List<Item>();
}

To my surprise I still got the same exception. I finally figured out that the problem was the type of Items. It is was an IList<> instead of a List<>. To avoid tying a class to a specific implementation of a list, I usually use an interface, which is good practice in most cases... however, not when you want to do deserialization :).

Wednesday, September 02, 2009 10:11:22 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 26, 2009

At BataviaLabs we were debating coding guidelines the other day and came across this one: do you use #if or the ConditionalAttribute to indicate to the compiler if a method should be compiled. Let me elaborate...

If you have a method you only want to compile in a debug scenario, you have the following options:

1) Use #if DEBUG as shown below

class Program
{
    static void Main(string[] args)
    {
#if DEBUG
        SomeMethod();
#endif
        Console.WriteLine("End");
        Console.ReadKey();
    }

#if DEBUG
    internal static void SomeMethod()
    {
        Console.WriteLine("SomeMethod");
    }
#endif
}

2) Use the ConditionalAttribute as shown below

class Program
{
    static void Main(string[] args)
    {
        SomeMethod();
        Console.WriteLine("End");
        Console.ReadKey();
    }

    [Conditional("DEBUG")]
    internal static void SomeMethod()
    {
        Console.WriteLine("SomeMethod");
    }
}

The difference between these two methods is enormous. The first sample is very explicit. Any code you don't want to compile into the production build is placed between #if DEBUG and #endif. If you try to call SomeMethod in a production build, the compiler will give you a compile error. The ConditionalAttributeon the other hand doesn't require you to remove the calls to SomeMethod. If a method is marked [Conditional], any calls made to that method are removed from the build by the compiler. A proviso here is that [Conditional] only works with methods that don't return a value (i.e. void).

I much more prefer #if DEBUG, because it is explicit. I can't run into a situation where from reading the code I'm thinking "SomeMethod is being executed", but it actually isn't because the compiler removed the call. Comments anyone?

Wednesday, August 26, 2009 3:59:00 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, March 02, 2009

Thank you for all who attended my sessions in San Francisco. Below are the slides and samples for my sessions.

VTH4 - Understanding Transactions in WCF Slides (561.73 KB) | Samples (540.1 KB)

VTH16 - Supporting POX/REST with WCF Slides (369.58 KB) | Samples (302.82 KB)

VTH25 - Simplify WebPart (and Control) Development with WebPart Skinning Slides (359.85 KB) | Samples (447.66 KB)

The VTH25 samples include the full installer. However, be sure to change the uploadskinfeature.bat to point to the correct server. You can read more about the VirtualPathProvider I mentioned in VTH25 session here.

.NET | ASP.NET | English | Events | SharePoint | WCF
Monday, March 02, 2009 11:25:30 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, January 07, 2009

The wonderful folks at VSLive! have invited me again to do three sessions at their San Francisco event from February 23 to February 27, 2009. These are the sessions I'll do (all on Thursday 26):

  • Understanding Transactions in WCF
  • Supporting POX/REST with WCF
  • Simplify WebPart (and Control) Development with WepPart Skinning

The first two are obviously about WCF. The last talk is primarily about SharePoint, but the discussed techniques will work with ASP.NET WebParts and WebControls as well.

I really like VSLive! because they have some great content and top tier speakers. The speakers (myself included of course) are also very accessible, because the event is not as huge as some of the other conferences these days. So if you intend to go to a conference this year, VSLive! is going to be worth your money.

.NET | ASP.NET | English | Events | SharePoint | WCF
Wednesday, January 07, 2009 10:52:13 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, October 28, 2008

I will be speaking at VSLive! again, this time in Dallas from 8 until 11 December. I'll be doing the following sessions:

  • Introduction to ASP.NET Dynamic Data (Tuesday 9 December, 11:15 AM)
  • POX/REST Strategies with WCF (Thursday 11 December, 1:45 PM)
  • Understanding Transactions in WCF (Thursday 11 December, 4:45 PM)

VSLive! is a very nice and relaxed event with great content. So it's a great opportunity to learn new stuff and new people. If you want to attend the Dallas show and see me speak, you can get a $300 discount by entering the discount code SPVAN. I hope to see you there.

Tuesday, October 28, 2008 9:19:07 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, August 23, 2008

LINQ to SQL ontwikkelt heerlijk als je weet dat je alleen tegen SQL Server hoeft te praten. Maar LINQ to SQL voegt wel weer een extra laagje toe, waardoor de kans groot is dat er vertraging optreedt. Hoewel... LINQ to SQL doet ook aan caching, dus als je veel met dezelfde data moet werken, hoef je niets extra's to doen om code aanzienlijk sneller te laten lopen dan wanneer de database iedere keer benaderd moet worden. Rico Mariani geeft in vijf delen een aardig inzicht in de performance van LINQ to SQL en wat je kunt doen (of niet hoeft te doen) om de performance te verbeteren. Het eerste deel, met links naar de andere delen, vind je hier.

.NET | LINQ | Nederlands
Saturday, August 23, 2008 10:10:33 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 23, 2008

I've now read several books on SharePoint development, such as Developer's Guide to the Windows SharePoint Services v3 Platform , Microsoft harePoint 2007 Development Unleashed, and Programming Excel Services. I've found each of these books lacking, particularly the last two. The Unleashed book is more a reference than anything else and especially in the more advanced topics I really didn't find what I was looking for, which is not what you'd expect from an Unleashed title. The Excel Services book is a disappointment if you are looking for good information about Excel Services. If you want to learn to develop WebParts it is quite good however. In that sense the book has been completely misnamed. I hope that my next pick will be better (that said, two of the three books were given to me).

Wednesday, July 23, 2008 10:37:33 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, March 10, 2008

Log4net is a great tool for logging in a .NET application and everything is well documented. Finding what you need can be a pain though. If you checkout the configuration manual, you read about all the appenders and a little about the pattern of the message that is logged. You can set that pattern if you want. What they fail to provide however is a reference of the tokens you can use in a pattern (for instance %exception). They only show a sort of default pattern. After digging for about 10 minutes, I finally found the list within the SDK reference. It would be great it someone were to add I direct link to there from the configuration manual.

Monday, March 10, 2008 12:18:03 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, January 09, 2008

I've been doing stuff with LINQ to SQL for a while now and there's one thing that keeps bugging me: Proper exception handling. IMHO LINQ to SQL should encapsulate the database. I mean, I don't care which database (SQL Server, Oracle, whatever) I'm working with, but if I call SubmitChanges on the DataContext, I'll get a SqlException if it fails on the database. I know that currently LINQ to SQL only supports SQL Server, but the model is just as valid for any other (relational)database. To my surprise there is no LinqException or something that encapsulates the SqlException, so now I have to write code that is aware of the fact that I'm dealing with SQL. You can of course solve this by using the Exception Handling Application Block, so you don't deal with specific exceptions in code, but it still feels funky.

.NET | English | LINQ
Wednesday, January 09, 2008 11:21:11 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Friday, October 19, 2007

For those interested in the demo of Using Windows Workflow Foundation in ASP.NET, you can download it here (269 kb). Note: this is the demo with the "double bookkeeping". The request/response inside a workflow isn't stable enough yet for release.

.NET | ASP.NET | English | Events
Friday, October 19, 2007 12:52:27 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, September 20, 2007

I'll be at VSLive! in Las Vegas next month. On Tuesday, October 16th, I'll be speaking about two topics:

  • Using Windows Workflow Foundation in ASP.NET
  • Create Scalable Apps with Asynchronous Processing

The first is an introductory session about Windows Workflow Foundation (WF) and adresses how to deal with WF in ASP.NET. Because WF is not request-response by nature, this is more challenging than you would think. The second session discusses ASP.NET 2.0 Async Pages and Handlers and shows you how to use this with web services and databases.

Hope to see you there!

.NET | ASP.NET | English | Events
Thursday, September 20, 2007 8:46:02 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, July 24, 2007

Last year I wrote a book (in Dutch) about ASP.NET 2.0. For that book I did an interview with Scott Guthrie, General Manager of the .NET Developer Platform group at Microsoft. In the book the interview is of course translated and also edited to fit the book. Below is the original unedited version.

Who are you?
My name is Scott Guthrie. I am the General Manager of .NET Developer Platform group within Microsoft, which means I run the development teams that build the CLR, .NET Compact Framework, ASP.NET / Atlas, Windows Presentation Foundation (aka Avalon), Windows Forms, IIS 7.0, Commerce Server, and the Visual Studio development tools for ASP.NET and WPF.

How long have you worked for Microsoft, and in what did you do up to becoming General Manager?
I’ve been at Microsoft for 9 years.  I’ve been focusing on frameworks, tools and servers for developers pretty much the entire time.  Prior to my current role, I ran the teams that built ASP.NET, IIS 7.0, and Visual Web Developer.

You are generally seen as the (co-)creator of ASP.NET. How was ASP.NET conceived and where did you get the ideas from?
We actually started the ASP.NET project in late 1997 and early 1998.  At the time ASP was still relatively new, and we initially weren’t sure whether there was anything left to-do in the web space (little did we know)!  We then spent a lot of time talking with developers and customers using ASP and quickly realized that there were a lot of things left to resolve. 

Some specific issues/requests that came up again and again from customers: provide the ability to write much cleaner code that provided good code/content separation (rather than mixing code up in the HTML), provide the ability to write applications using a variety of coding languages (and not just VBScript and Jscript), deliver a more robust execution environment (avoiding memory leaks and crashes that could bring down the server), provide a much cleaner configuration/code deployment model, deliver a built-in security architecture, enable built-in output caching support to improve scalability, and more.

A colleague of mine (Mark Anders) and I spent about 2 months brainstorming ideas about how we could build a programming model that delivered all of this.  Eventually we decided we needed to put together a prototype to try out the concepts, and I ended up coding it up over the Christmas and New Year’s holiday in 1997/98 (I was a hardcore geek then <g>).   We showed off the prototype to a lot of people within the company, built a lot of excitement, and got the go ahead to build a team to deliver it.

What are the main differences between ASP.NET 1.x and ASP.NET 2.0?
We spent a lot of time working with customers to identify where they spend their time writing code today within web applications, and then worked to add new features in ASP.NET 2.0 to help simplify these tasks dramatically.  Some examples: Master Pages allow you to easily define a consistent layout across your site/application, the new Membership/Roles API provides an easy way to manage users/passwords/roles and allows you to build flexible secure application in only a few minutes, the new GridView/DetailsView/DataSource controls enable you to easily provide data entry and editing views on top of data (including 3-tier data access support), Web Parts provide the ability to enable portal-style layout within any page and enable drag/drop end-user customization that works both in regular ASP.NET applications and SharePoint solutions, Localization support has been added to make it much easier to build multi-lingual applications that can adjust at runtime depending on the culture/language of the incoming user, SQL Output Caching enables developers to output cache any content within a site and have it automatically be invalidated and re-generated when backend data changes on a site (dramatically improving performance), Site Navigation and Menu controls make it much easier to build menu structures and navigation across your sites, Health Monitoring makes it easier to monitor how your application is doing once it is deployed, and there are many more features I could keep calling out.

If you could give one tip to people learning ASP.NET 2.0, what would it be?
I’d recommend spending time on the new http://www.asp.net web-site in the “Getting Started” and the “Learn” sections.  We are putting out several new videos and tutorials each week on the site that help show how you can take best advantage of new features with ASP.NET.  These can make it significantly easier to take full advantage of the platform and build great applications.  I’d also recommend subscribing to my blog: http://weblogs.asp.net/scottgu.  I try and post 1-2 tips/tricks a week that you can use.

What do you (personally) think is the coolest feature of ASP.NET 2.0?
Master Pages is probably the most popular feature that virtually everyone takes immediate use of – so in terms of popularity that is probably the coolest.

I think the new ASP.NET 2.0 AJAX Extensions product we are shipping later this year is also really, really cool (note: this was formerly codenamed “Atlas”).  This will provide a free, fully-supported AJAX library with suite of ASP.NET 2.0 server controls that enable you to easily add AJAX functionality to your ASP.NET 2.0 sites. 

What are the long term goals for ASP.NET, and what will we see of that in the coming years?
The next release of ASP.NET will have a lot of great additions.  You will see even richer support for the AJAX Extensions built-into the next release, as well as much richer support for building more interactive user experiences that take full advantage of the browser.

You’ll also see ASP.NET take advantage of the new LINQ technologies that are coming out with .NET, and which will enable really rich data modeling and mapping support with code which will dramatically improve the productivity of working with data.  When LINQ is combined with the ASP.NET 2.0 GridView, DetailsView and other data controls, you have a tremendously easy and powerful programming model for building AJAX enabled data applications.  I’m really excited to see the applications people build with it.  It is going to be a very exciting future!

.NET | ASP.NET | English
Tuesday, July 24, 2007 12:05:53 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, May 04, 2007

Wil je weten hoe Microsoft Silverlight (aka WPF/Everywhere, WPF in de browser a la Flash) er qua architectuur uit gaat zien? Deze plaat geeft het overzicht. Scott Hanselman geeft een zeer uitgebreid overzicht in zijn blogpost Putting Mix, Silverlight, the CoreCLR and the DLR into context.

Friday, May 04, 2007 9:53:31 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, February 21, 2007

Reflector is een heerlijke tool waarmee je dde code kunt bekijken in asemblies, ook de System... assmeblies van Microsoft (heeeel leerzaam). Als je Reflector nog niet kent, haast je naar http://www.aisto.com/roeder/dotnet/ om 'm te downloaden. Ken je 'm wel al, haast je dan ook naar http://www.aisto.com/roeder/dotnet/ (of doe Check for Updates in je huidige versie).

Wednesday, February 21, 2007 3:51:17 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, February 19, 2007

Het is heel gewoon om classes in een library public te maken, maar eigenlijk is dit helemaal niet handig. Dat betekent namelijk dat de class vanuit alle code die de library gebruikt beschikbaar is. Met andere woorden de class maakt onderdeel uit van de interface van de library. Er zijn meerdere redenen waarom dit onwenselijk is:

  1. De interface is onnodig groot en voor gebruiker van de library kan het daarom onduidelijk zijn welke classes gebruikt moeten worden.
  2. Het is veel lastiger om te achterhalen welke verbindingen er bestaan tussen de library en eventuele clients. Dit is bijvoorbeeld lastig bij refactoring.
  3. Het is in een client mogelijk om een sub-class te maken, terwijl dit wellicht niet de bedoeling is.

Veel beter is om classes internal te maken. Dit is ook standaard zo als je geen access modifier plaatst. Daarmee zijn classes alleen beschikbaar voor code binnen dezelfde assembly (tenzij men reflection gebruikt).

Het is verstandig om opo dezelfde manier even stil te staan bij class members. Die zijn standaard private, en als je dat verandert kun je ze protected (alleen beschikibaar voor de class zelf en sub-classes), internal, protected internal (protected of internal) of public maken. Als je dit consequent toepast kun je ook reflection tegengaan door de class te markeren met [ReflectionPermission(SecurityAction.Deny)]. Daarmee is de boel niet alleen veel handiger, maar ook veel veiliger.

Monday, February 19, 2007 3:19:15 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, February 12, 2007

Ik zie in code geregeld dat het Session object op allerlei plaatsen gebruikt wordt, met name in pagina's en controls, als volgt:

public void Page_Load(object sender, EventArgs e)
{
    Session["MySessionVar"] += 1;
}

public void Page_PreRender(object sender, EventArgs e)
{
    Label1.Text = Session["MySessionVar"].ToString();
}

Dit is om meerdere redenen niet aan te raden:

  1. Omdat de collectie loosely typed is, is er geen compile-time check bij het benaderen van de elementen in de collectie. Het is daarom heel makkelijk om een typfoutje te maken, waardoor je tegen het verkeerde object aan praat.
  2. Door elementen in het Session object te stoppen in de pagina, is er geen centrale administratie van de namen (keys) die in gebruik zijn.

Je kunt beide zaken oplossen door een centraal object te maken waarmee je de elementen in het Session-object benaderd, als volgt:

/// <summary>
/// Strongly typed toegang tot Session-object.
/// </summary>
internal static class TypedSession
{
   public static int MySessionVar
   {
      get
      {

         object o = 
HttpContext.Current.Session["MySessionVar"];
         if(o == null) return 0;

         return (int)o;
      }
      set
      {
         HttpContext.Current.Session["MySessionVar"] = value;
      }
   }
}

public void Page_Load(object sender, EventArgs e)
{
TypedSession.MySessionVar += 1;
}

public void Page_PreRender(object sender, EventArgs e)
{
Label1.Text = TypedSession.MySessionVar.ToString();
}

Merk op dat bij de get-accessor eerst gekeken wordt of het object null is. Dit is nodig omdat een int niet null mag zijn. Voor objecten waarvoor dat wel mag kun je desondanks besluiten dat er een standaardwaarde moet zijn, bijvoorbeeld een nieuw object.

Deze methodiek werkt ook uitstekend voor de Request.QueryString collectie en meer van dat soort collecties die je normaal gezien loosely typed gebruikt. Die zal je niet zo snel centraliseren, omdat het juist op een bepaalde pagina van toepassing is, maar daarmee strongly typed kunnen werken is nog steeds minder foutgevoelig. Bovendien hoeft de ontwikkelaar niet te weten waar de data vandaan komt.

Monday, February 12, 2007 11:40:18 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, January 02, 2007

Deze fout schijnt nogal vaak voor te komen bij het installeren van Visual Studio 2005 SP1. Dit knowledgebase artikel vertelt wat je eraan kunt doen.

Tuesday, January 02, 2007 10:52:37 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, December 18, 2006
Visual Studio 2005 SP1 is beschikbaar. Het lost allerlei bugs op en biedt een aantal verbeteringen, waaronder
  • Nieuwe project types voor ASP.NET
  • Ondersteuning voor nieuwe processor types voor code generatie en profiling
  • Integratie van Excel 2007 en Project 2007 met Team Foundation Server
  • Ondersteuning voor Windows Embedded 6.0 platform en tools
Meer informatie is te vinden op de MSDN pagina Visual Studio 2005 Service Pack 1 (SP1).
Monday, December 18, 2006 1:05:13 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, December 13, 2006

Microsoft heeft een security patch uitgebracht voor Visual Studio. Het "gat" in VS2005 wordt als kritiek beschouwd, dus is het heeeel verstandig de patch te installeren. Zie voor meer informatie en download Microsoft Security Bulletin MS06-073.

Wednesday, December 13, 2006 1:05:09 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, August 24, 2006

Kan met de Augustus CTP van Microsoft Robotics Studio. Zo te zien zijn er ook al heel wat (verkrijgbare) robots die hiermee aan te sturen zijn... leuk speelgoed.

Thursday, August 24, 2006 11:54:48 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, July 07, 2006

Updated August 13, 2006 to reflect Sander's comment.

On my old blog (in Dutch) I commented that I thought the WindowsImpersonationContext was clumsy and I wrote a replacement that you can use as follows:

Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);
WrapperImpersonationContext context = new WrapperImpersonationContext(domain, username, password);
context.Enter();
// Execute code under other uses context
Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);
context.Leave();
Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);

Recently a visitor noted that the code wasn't quite right (missng a view using statements, and I found some other small issues. The correct code (including namespace references) is below. It takes care of all that nasty calls into the Win32 API. The one thing you need to be aware of is that it requires permissions to call into a DLL (i.e. run unsafe code), which is why I added the attributes that indicate this. Unfortunately that renders this class useless in a hosted environment, unless you strong sign the assembly and pursuade the host to allow your assembly to run in Full or High trust. This however is a problem you will run into regardless your use of this class. As soon as you call LogonUser you need at least High trust. If this is something that should be possible under lower trust by default it's up to the folks in Redmond to add this functionality to .NET and handle it as such.

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.ComponentModel;

public class WrapperImpersonationContext
{
   [DllImport("advapi32.dll", SetLastError = true)]
   public static extern bool LogonUser(String lpszUsername, String lpszDomain,
   String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

   [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
   public extern static bool CloseHandle(IntPtr handle);

   private const int LOGON32_PROVIDER_DEFAULT = 0;
   private const int LOGON32_LOGON_INTERACTIVE = 2;

   private string m_Domain;
   private string m_Password;
   private string m_Username;
   private IntPtr m_Token;

   private WindowsImpersonationContext m_Context = null;

   protected bool IsInContext
   {
      get { return m_Context != null; }
   }

   public WrapperImpersonationContext(string domain, string username, string password)
   {
      m_Domain = domain;
      m_Username = username;
      m_Password = password;
   }

   [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
   public void Enter()
   {
      if (this.IsInContext) return;
      m_Token = new IntPtr(0);
      try
      {
         m_Token = IntPtr.Zero;
         bool logonSuccessfull = LogonUser(
            m_Username,
            m_Domain,
            m_Password,
            LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT,
            ref m_Token);
         if (logonSuccessfull == false)
         {
            int error = Marshal.GetLastWin32Error();
            throw new Win32Exception(error);
         }
         WindowsIdentity identity = new WindowsIdentity(m_Token);
         m_Context = identity.Impersonate();
      }
      catch (Exception exception)
      {
         // Catch exceptions here
      }
   }

   [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
   public void Leave()
   {
       if (this.IsInContext == false) return;
       m_Context.Undo();

       if (m_Token != IntPtr.Zero) CloseHandle(m_Token);
       m_Context = null;
   }
}

 

Friday, July 07, 2006 8:18:44 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  |