RSS 2.0
# Wednesday, July 26, 2006

One of the great things about a DataSet, from a code generation perspective that is, is that it is defined in an XML Schema with some added features for TableAdapters and such. I wrote a very simple code generator that takes a DataSet definition and an XSLT stylesheet and generates a code file. I also made it possible to call an XSLT stylesheet for each table in the DataSet so I could create Data Transfer Objects and such from the table definition. I had some trouble to get it going though because of a namespace issue. The namespace that you expect to be the default namespace isn't in actual fact as I'll explain with the following fragment:

<xs:schema id="TrackingTracingDataSet"
           targetNamespace="http://tempuri.org/MyDataSet.xsd"
           xmlns:mstns="http://tempuri.org/My.xsd"
           xmlns="http://tempuri.org/MyDataSet.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
           xmlns:msprop="urn:schemas-microsoft-com:xml-msprop"
           attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:annotation>
    <xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">

From the above fragment you would think that the default namespace is http://tempuri.org/MyDataSet.xsd, because the default namespace is declare with the statement xmlns="http://tempuri.org/MyDataSet.xsd. The actual default namespace is however defined in the source attribute of xs:appinfo element, so the default namespace is urn:schemas-microsoft-com:xml-msdatasource.

Wednesday, July 26, 2006 10:39:13 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1] -
Development | English

Recently one of my collegues was trying to create a Web Setup project for an application in VS2005 and he commented "I can't add the Primary Output of the application to the setup, just the content." This is where VS2005 (or actually ASP.NET 2.0) differs from VS2003, so I explained that this was normal behavior and that his application didn't need to have an application assembly because ASP.NET 2.0 compiles everything on the fly. His reply was that you wouldn't want to have your source code sitting in the production enviroment, and he is absolutely right. The solution to this is precompiling your applications with aspnet_compiler.exe. This packages all your files, inlcuding the contents of your .aspx files in an assembly which is used to run the site. The .aspx files are still there, but these are just placeholder files with no contents. By default the .aspx files can't be edited (well, you can but that doesn't change what is sent to the browser), but this can be controlled. Checkout the MSDN article How to: Precompile ASP.NET Web Sites for Deployment on how to use aspnet_compiler.exe. For a complete rundown of precompilation see ASP.NET Web Site Precompilation.

Wednesday, July 26, 2006 10:06:13 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
ASP.NET | English
# 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 few 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 9:18:44 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3] -
.NET | Development | English

This is a great tool that helps you create a sound threat model of your application, leading to a more secure application. Do yourself a favor and download it.

Friday, July 07, 2006 9:22:50 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
Development | English

Eerder al berichtte ik over deze Threat Modeling tool in Eerste hulp bij Threat Modeling toen dit nog een release candidate was. Deze tool is er nu als final release en is hier te downloaden.

Friday, July 07, 2006 9:19:06 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
Development | Nederlands
# Monday, July 03, 2006
Monday, July 03, 2006 9:23:45 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
ASP.NET | Nederlands
Sign In

Archive
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
About
This is the blog of Michiel van Otegem, a Senior Software Architect with Sogeti Netherlands, and author of several books and numerous articles on (ASP).NET, XML, and related technologies.
Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Michiel van Otegem
All Content © 2012, Michiel van Otegem
DasBlog theme 'Business' created by Christoph De Baene (delarou)