© 2004 Microsoft Corporation. All rights reserved.
Figure 1 IPrincipal and IIdentity
namespace System.Security.Principal {
  interface IPrincipal {
    IIDentity Identity { get; }
    bool IsInRole(string role);
  }

  interface IIdentity {
    bool    IsAuthenticated     { get; }
    string  AuthenticationType  { get; }
    string  name                { get; }
  }
}
Figure 2 Imperative Role Check
void Withdraw(double amount) {
  if (amount <= REASONABLE_AMOUNT) {
    // any teller can do this
    // ...
  }
  else {
    IPrincipal p = Thread.CurrentPrincipal;
    if (!p.IsInRole("Supervisors")) {
      string msg = "A supervisor must agree " +
                   "to this withdrawal";
      throw new SecurityException(msg);
    }
    // only supervisors can do this
    // ...
  }
}
Figure 3 App::foo
.method private hidebysig static void  StartTheMachinery() cil managed
{
  .permissionset noncasdemand = 
      (3C 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00   // <.P.e.r.m.i.s.s.
       69 00 6F 00 6E 00 53 00 65 00 74 00 20 00 63 00   // i.o.n.S.e.t. .c.
       6C 00 61 00 73 00 73 00 3D 00 22 00 53 00 79 00   // l.a.s.s.=.".S.y.
       73 00 74 00 65 00 6D 00 2E 00 53 00 65 00 63 00   // s.t.e.m...S.e.c.
       75 00 72 00 69 00 74 00 79 00 2E 00 50 00 65 00   // u.r.i.t.y...P.e.
       72 00 6D 00 69 00 73 00 73 00 69 00 6F 00 6E 00   // r.m.i.s.s.i.o.n.
       53 00 65 00 74 00 22 00 0D 00 0A 00 20 00 20 00   // S.e.t."..... . .
       20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00   //  . . . . . . . .
       20 00 20 00 20 00 20 00 20 00 76 00 65 00 72 00   //  . . . . .v.e.r.
       73 00 69 00 6F 00 6E 00 3D 00 22 00 31 00 22 00   // s.i.o.n.=.".1.".
       3E 00 0D 00 0A 00 20 00 20 00 20 00 3C 00 50 00   // >..... . . .<.P.
       65 00 72 00 6D 00 69 00 73 00 73 00 69 00 6F 00   // e.r.m.i.s.s.i.o.
       6E 00 20 00 63 00 6C 00 61 00 73 00 73 00 3D 00   // n. .c.l.a.s.s.=.
       22 00 53 00 79 00 73 00 74 00 65 00 6D 00 2E 00   // ".S.y.s.t.e.m...
       53 00 65 00 63 00 75 00 72 00 69 00 74 00 79 00   // S.e.c.u.r.i.t.y.
       2E 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00   // ..P.e.r.m.i.s.s.
       69 00 6F 00 6E 00 73 00 2E 00 50 00 72 00 69 00   // i.o.n.s...P.r.i.
       6E 00 63 00 69 00 70 00 61 00 6C 00 50 00 65 00   // n.c.i.p.a.l.P.e.
       72 00 6D 00 69 00 73 00 73 00 69 00 6F 00 6E 00   // r.m.i.s.s.i.o.n.
       2C 00 20 00 6D 00 73 00 63 00 6F 00 72 00 6C 00   // ,. .m.s.c.o.r.l.
       69 00 62 00 2C 00 20 00 56 00 65 00 72 00 73 00   // i.b.,. .V.e.r.s.
       69 00 6F 00 6E 00 3D 00 31 00 2E 00 30 00 2E 00   // i.o.n.=.1...0...
       32 00 34 00 31 00 31 00 2E 00 30 00 2C 00 20 00   // 2.4.1.1...0.,. .
       43 00 75 00 6C 00 74 00 75 00 72 00 65 00 3D 00   // C.u.l.t.u.r.e.=.
       6E 00 65 00 75 00 74 00 72 00 61 00 6C 00 2C 00   // n.e.u.t.r.a.l.,.
       20 00 50 00 75 00 62 00 6C 00 69 00 63 00 4B 00   //  .P.u.b.l.i.c.K.
       65 00 79 00 54 00 6F 00 6B 00 65 00 6E 00 3D 00   // e.y.T.o.k.e.n.=.
       62 00 37 00 37 00 61 00 35 00 63 00 35 00 36 00   // b.7.7.a.5.c.5.6.
       31 00 39 00 33 00 34 00 65 00 30 00 38 00 39 00   // 1.9.3.4.e.0.8.9.
       22 00 0D 00 0A 00 20 00 20 00 20 00 20 00 20 00   // "..... . . . . .
       20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00   //  . . . . . . . .
       20 00 20 00 76 00 65 00 72 00 73 00 69 00 6F 00   //  . .v.e.r.s.i.o.
       6E 00 3D 00 22 00 31 00 22 00 3E 00 0D 00 0A 00   // n.=.".1.".>.....
       20 00 20 00 20 00 20 00 20 00 20 00 3C 00 49 00   //  . . . . . .<.I.
       64 00 65 00 6E 00 74 00 69 00 74 00 79 00 20 00   // d.e.n.t.i.t.y. .
       41 00 75 00 74 00 68 00 65 00 6E 00 74 00 69 00   // A.u.t.h.e.n.t.i.
       63 00 61 00 74 00 65 00 64 00 3D 00 22 00 74 00   // c.a.t.e.d.=.".t.
       72 00 75 00 65 00 22 00 0D 00 0A 00 20 00 20 00   // r.u.e."..... . .
       20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00   //  . . . . . . . .
       20 00 20 00 20 00 20 00 20 00 20 00 52 00 6F 00   //  . . . . . .R.o.
       6C 00 65 00 3D 00 22 00 53 00 75 00 70 00 65 00   // l.e.=.".S.u.p.e.
       72 00 76 00 69 00 73 00 6F 00 72 00 73 00 22 00   // r.v.i.s.o.r.s.".
       2F 00 3E 00 0D 00 0A 00 20 00 20 00 20 00 3C 00   // /.>..... . . .<.
       2F 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00   // /.P.e.r.m.i.s.s.
       69 00 6F 00 6E 00 3E 00 0D 00 0A 00 3C 00 2F 00   // i.o.n.>.....<./.
       50 00 65 00 72 00 6D 00 69 00 73 00 73 00 69 00   // P.e.r.m.i.s.s.i.
       6F 00 6E 00 53 00 65 00 74 00 3E 00 0D 00 0A 00 ) // o.n.S.e.t.>.....
  // Code size       11 (0xb)
  .maxstack  8
  IL_0000:  ldstr      "Starting the machinery..."
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  ret
} // end of method App::foo
Figure 5 asm.cs
using System;
using System.Web;
using System.Security;

public class MyModule : IHttpModule {
  public void Init(HttpApplication app) {
    app.Error += new EventHandler(OnError);

  }
  public void Dispose() {}

  static void OnError(object sender, EventArgs args) {
    HttpContext ctx = HttpContext.Current;
    foreach (Exception x in ctx.AllErrors) {
      if (hasSecurityException(x)) {
        // Ask IIS to authenticate the user
        // if they are currently anonymous.
        // This may allow a second request to succeed.
        ctx.Response.StatusCode = 401;
        ctx.Response.StatusDescription = "Unauthorized";

        // don't show the user that vanilla error page
        ctx.ClearError();

        ctx.Response.Write("<h2>You are not authorized " +
                           "to view this page</h2>");
        break;
      }
    }
  }
  static bool hasSecurityException(Exception x) {
    if (x is SecurityException) {
      return true;
    }
    else if (null != x.InnerException) {
      return hasSecurityException(x.InnerException);
    }
    else return false;
  }
}
Figure 6 Evil Code Access
using System.Threading;
using System.Security.Principal;

public class EvilComponent : ICalculator {
  public int Add(int a, int b) {
    string[] roles = { "Supervisors" };
    IPrincipal fake =
      new GenericPrincipal(
        new GenericIdentity("Bob"),
        roles);

    // the following line of code
    // should worry you!
    Thread.CurrentPrincipal = fake;

    return a + b;
  }
}

Home
Topics
Issues
Columns
Downloads
Subscribe
Contact Us

MSDN Magazine