Searched for : azman

AzManBulkImport Update

Joe sent me a new version of his AzMan bulk importer - in the .zip is a changes document. enjoy!

AzManBulkImport123.zip (6.25 KB)

 


Tools
Tuesday, November 14, 2006 2:43:38 PM UTC  #   

New AzMan Whitepaper

Very detailed read:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetserv/html/AzManApps.asp

On a related note, I can recommend Keith's roadmap article for the big picture:

http://msdn.microsoft.com/security/identityaccess/default.aspx?pull=/library/en-us/dnnetserv/html/DotNetIdM.asp

 


Work in Progress
Friday, August 25, 2006 7:04:04 AM UTC  #   

Update for AzMan Bulk Importer

via Joe Langley:

UPDATED 7/24/2006:
Bug fixed where top level application groups were not copied
Option added so that you can have a patch mode (patch only one application in a store...helpful if you have more than one application in a store)
 
UPDATED 7/10/2006:
Bug fixed where nested roles and nested tasks were not copied

AzManBulkImport12.zip (5.55 KB)

 


Tools
Monday, July 24, 2006 6:06:20 PM UTC  #   

Source Code for AzMan Bulk Importer

Joe finally got permission from his employer to realease the source code for the excellent AzMan Export/Import tool.

Essential if you are doing AzMan development.

AzManBulkImport1.zip (5.17 KB)

 


Tools
Monday, June 26, 2006 7:12:53 AM UTC  #   

Creating an Enum for AzMan Operations

Some time ago I posted a little tool that spits out a constants for operations found in an AzMan store.

Joe Langley extended the code a bit and now generates enums. Furthermore it creates a file and you can specify the namespace. You can download his version here.

 


Tools
Saturday, May 27, 2006 8:17:27 AM UTC  #   

AzMan Bulk Importer / Converter

Joe Langley, a guy I speak to from time to time about AzMAn and other security related stuff sent me a very neat utility to import / convert AzMan stores between different formats (XML to AD and vice versa). This allows to painlessly start with local XML stores and import them into AD at some later point.

This tool was written as part of his day job, so unfortunately he is not allowed to release the source code...

AzManBulkImport.zip (11.48 KB)

 


Tools
Monday, January 09, 2006 8:12:23 PM UTC  #   

Why AspNetTokenRoleProvider?

ASP.NET 2.0 ships with three role providers - one for SQL Server, one for AzMan and one for Windows tokens...

The Windows token provider is special - it only works with Windows authentication whereas all the other providers seem to be more targeted at Forms Authentication (the AzMan provider supports both).

Why do I need a role provider for Windows accounts? You don't have to take care of getting roles for Windows users as they come packaged in the token that gets procuced during authentication in IIS.

Well - the WindowsTokenRole provider can do some optimizations to Windows authentication

  • Instead of a WindowsPrincipal you get a RolePrincipal which features a method called GetRoles() that returns all roles as a string array. This is more straightforward than using the code I showed here. You still have access to the underlying WindowsIdentity (Context.User.Identity) and can create a WindowsPrincipal if you have to.
  • RoleManager can cache the roles. The first time you call IsInRole, RolePrincipal will fetch all roles from the token (which requires round trips to the DC to translate the SIDs to "human-readable" names. These names can get cached in the roles cookie (.aspxroles). This saves the roundtrip to the DC on subsequent requests.

So this is really just an (optional) optimization for Windows authentication based web apps. If you want to use role caching make sure to set reasonable timeouts (e.g. 30mins) - otherwise group membership changes for the user will have a high latency in your application.

 


Work in Progress
Sunday, December 04, 2005 7:07:38 AM UTC  #   

Context.User vs. Thread.CurrentPrincipal

The whole .NET authentication/authorization infrastructure is centered around two interfaces: IIdentity (taking care of who the user is - authentication) and IPrincipal (coupling roles with the Identity - used for authorization). The designated place to store that information is Thread.CurrentPrincipal.

Afterwards you do role checks by calling Thread.CurrentPrincipal.IsInRole - or use PrincipalPermission.Demand or [PrincipalPermissionAttribute] (which does nothing else than calling IsInRole on Thread.CurrentPrincipal under the covers). So far so good.

ASP.NET encourages you to use the "convenience" Context.User / Page.User which also point to an IPrincipal implementation and call IsInRole from there. But because PrincipalPermission relies on Thread.CurrentPrincipal and you maybe want to port a library used in desktop applications (where the Thread.CurrentPrincipal style is used) - ASP.NET has to populate Thread.CurrentPrincipal too - and synchronize it with Context.User.

When you want to plug into Forms Authentication in ASP.NET 1.1, you typically handled the AuthenticateRequest event in the HTTP pipeline. There you fetched the roles for the authenticated users, created an IPrincipal implementation and set Context.User to this new principal. Directly after AuthenticateRequest a (mostly) undocumented event fires called "DefaultAuthentication" and a module called DefaultAuthenticationModule subscribes to this event. This module has only one job, to copy Context.User to Thread.CurrentPrincipal so both values are in-sync.

In ASP.NET 2.0 there is the new PostAuthenticateRequest event and I like to think about the relationship between these two events in this way: AuthenticateRequest is used to create the IIdentity (identity information) and PostAuthenticateRequest is used to couple roles to that identity (authorization). The RoleManagerModule which has the job to couple roles from the provider backed store to the authenticated identity subscribes to exactly this event.

There is one gotcha though - ASP.NET does not take care of syncing Context.User and Thread.CurrentPrincipal after PostAuthenticateRequest - which is a bug IMO. So if you follow the pattern you know from 1.1 and set Context.User in PostAuthenticateRequest, Context.User and Thread.CurrentPrincipal will have different values. You may write really complex ASP.NET application whithout ever noticing that, but recently I plugged a custom IPrincipal implementation for AzMan into an ASP.NET 2.0 application and saw strange errors until I found out what the problem was. I set Context.User in PostAuthenticateRequest and my implementation contains an  [AzManPrincipalPermission] which relies on Thread.CurrentPrincipal - but this was set to the wrong value because I relied on ASP.NET to sync to Context.User - which is not the case.

I wonder why the DefaultAuthentication event fires before PostAuthenticateRequest - maybe to guarantee that Thread.CurrentPrincipal and Context.User are correctly populated when the even fires. But why doesn't it also fire then after PostAuthenticateRequest to sync again??

So you basically have 2 choices:

1. Put the code in AuthenticateRequest and set Context.User. There are some implications:

  • Make sure your module runs after the built-in authentication modules
  • You run before RolesManager
  • If you call code from AuthenticateRequest (or another module handles the event after you) that relies on Thread.CurrentPrincipal you have to set it anyway.

2. Put the code in PostAuthenticateRequest (which seems to be the designated place) and set Context.User = Thread.CurrentPrincipal = myPrincipal;

RoleManager also fires a GetRoles event where you can override the role fetching, but if this event is handled (and you set the EventArgs.RolesPopulated property to true) all RoleManager logic will be bypassed (including the step that syncs Context.User and Thread.CurrentPrincipal - aargh).

Proposed solution: Always set Thread.CurrentPrincipal and see those implementation details leak through or Microsoft has to sync both values after PostAuthenticateRequest.

This implementation detail was nicely hidden in 1.1 - why do i have to think about that in 2.0 ??

any thoughts?

 


Work in Progress
Wednesday, November 23, 2005 8:25:43 AM UTC  #   

Authorization Manager and Vista

I just spotted that AzMan under Vista (build 5219) now support three types of authorization stores. Active Directory/ADAM, XML and ...tada.. SQL Server.

 


Work in Progress
Sunday, September 18, 2005 9:10:59 PM UTC  #   

Authorization Manager Table of Contents

just a summary of AzMan related content on this blog (will be updated when new stuff comes in)

Some off-site links:

 


For Your Favourites
Monday, May 09, 2005 5:24:14 AM UTC  #   

Back from the Indigo SDR

Last week I attended the Indigo SDR in Munich. First of all it was fun to hang out with my fellow DM buddies Marcus and Marvin, and of course Aaron, who was our instructor for the 3 days.

I will not be too over-enthusiastic, but what i've seen so far is a nice programming model, which seems to make sense (after thinking about it) and will hopefully reduce a lot of the complexities that many devs face today (e.g. choosing which technology over the other or painfully try to combine several technology stacks).

A lot of effort has been put into the bridging of the XML/Objects impedance mismatch, and time will tell if we can build XML messaging based systems in the future without touching (or maybe even knowing) angle brackets.

Here comes the obligatory security part :)

  • Seems that all binding (besides WSI-BP) have security enabled by default - which is good
  • I suggested to force even WSI-BP to work only over SSL by default (and that we have to manually disable that). The other attendees didn't like the idea :)
  • I really like that there is now an easy mechanism for services to provide a certificate with which a client can encrypt UsernameTokens (config setting, no coding)
  • Indigo config files will get tremendously complex, and complexity is the natural enemy of security. We really need good tools that check config files for plausability. In addition i want something like the WSE Policy Advisor and big red lights if something with the security config is wrong. As a side note - i just assume the Indigo configs are compatible with the .NET 2.0 ProtectedConfiguration providers (but haven't tried, yet).
  • What's really annoying is, that there is no built-in validation of the incoming messages against schema. While this is a general problem, everybody knows that input validation is maybe the most crucial part in today's application security. Please, Microsoft, include a validator - this does not have to be the standard behaviour - but it would be so nice to just flip a switch and have validation (and support for XSD Patterns and other restrictions).
  • I was happy to see that the authorization demos were centered around AzMan.
  • System.Security.Authorization seems to be an interesting new namespace. Pierre wrote about it already.

Will Indigo put instructors and consultants out of business (quoting dbox) ? Surely not. I expect a lot of people to use the straightforward programming interface right out of the box - but problems will arise later in the project (meet LOLA) - we will see if we can solve these problems then by reconfiguring and rebinding, without changing the code in the function.

The three days were a really nice overview, and i will definitely dive into the security APIs as soon as they look a little more stabilized. Good work!

 


Work in Progress
Sunday, May 08, 2005 6:41:08 PM UTC  #   

Another way of integrating AzMan

I am currently playing around with a custom IPrincipal implementation that uses AzMan as a backing store. There are other implementations around, but what strikes me odd is, that most of them only use the role storage features - which is IMO only 40% of the functionality provided.

A really powerful feature of AzMan is to map roles to operations in your application, e.g. you could have a operation "DeleteCustomer" and do an access check11 if the current user is allowed to delete that customer (of course this boils down to checking if the user is in a specific role that is allowed to execute that operation), but that is another layer of abstraction, and you don't have to hard-code role names in your code.


So i came up with the following usage pattern:

You replace your current principal with my AzManPrincipal - base it on some identity (more on that later) and point to your AzMan store and application name:

Thread.CurrentPrincipal = new AzManPrincipal(WindowsIdentity.GetCurrent(), @"msxml://c:\etc\source\1.1\AzManPrincipal\TestStore.xml", "TestApplication");

after that you can of course call IsInRole on that principal

[Test]
public void IsBoss()
{
  bool member = Thread.CurrentPrincipal.IsInRole("Boss");
  Assert.AreEqual(true, member);
}

but you can also ask if the current user is allowed to execute an operation, like (and this uses the AzManOpConst tool i posted earlier):

[Test]
public void TestOperation1()
{
  bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess(Operations.GiveRaise);
  Assert.AreEqual(true, allowed);
}

but the thing i find most compelling is to tie your code to an AzMan operation by using attributes, like this:

[Test]
[Operation(Operations.GiveRaise)]
public void TestOperation1Attribute()
{
  bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess();
  Assert.AreEqual(true, allowed);
}

HasAccess() returns a boolean, another option is to use CheckAccess() which will throw a SecurityException if necessary, like this

[Test]
[ExpectedException(typeof(SecurityException))]
[Operation(Operations.EnterCafeteria)]
public void CheckOperation2Attribute()
{
  ((AzManPrincipal) Thread.CurrentPrincipal).CheckAccess();
}

When we set up the Principal I used the current WindowsIdentity. I also implemented support for FormsIdentity (this will pickup the .Name property in the format Domain\Username to initialize the context) as well as a AzManCustomSidIdentity (to use with Custom SIDs).

So - what is missing?

  • I like to have a AzManPrincipalPermission to use declaratively as well as imperatively
  • A lot of testing

This stuff is not finished yet - but i wanted to share the programming model with you - do you like that, does that make sense?? Any comments??

Feedback is welcome.

 


Work in Progress
Tuesday, May 03, 2005 7:41:35 PM UTC  #   

AzMan Operations Helper Tool

I am currently working on some AzMan related tools/sample code (e.g. an IPrincipal implementation with some cool extra goodies) - as a side effect i wrote a little tool which parses an AzMan store and creates a class with consts that map to your AzMan operations, like:

public class Operations
{
    public const int opGiveRaise = 1;
    public const int opLeaveEarly = 2;
    public const int opEnterCafeteria = 3;
    public const int opRant = 4;
}

just point the tool to the store and the application.

AzManCreateOpConsts msxml://c:\store.xml TestApplication

There is more stuff coming up...

AzManCreateOpConsts.zip (27.88 KB)

 


Work in Progress
Monday, April 04, 2005 10:22:41 PM UTC  #   

The Future of AzMan?

I wrote a lot about Authorization Manager in the past, and i really believe that this piece of technology is extremely useful to virtualize your authorization decisions in complex applications.

Everytime I demo AzMan to customers or students, they really like the feature set - but some questions come up every time - why isn't this tool more popular? Does it have a future? If we base our applications completely on AzMan, what will happen when MSFT decides to deprecate it in favour of some other funky new technology??

I didn't have answers for them - but yesterday i finally made it to watch the ADFS episode on the .NET Show - they demo'd AzMan and the new federation services - seems that these technologies will go hand in hand in the future, and there will be some interesting new features in AzMan that make me believe that there is indeed a future, which is good.

The new version of AzMan will be shipped in Server 2003 R2 and includes

  • Support for SAML Tokens and Assertions (or Statements)
  • Support for ADAM Principles

OK - so now i want to see a managed implementation, GUI support for custom SIDs and a final word if the AuthorizationStoreRoleProvider will make it in the final ASP.NET 2.0 bits...

Go watch the show - this is extremely cool stuff....

 


For Your Favourites | Work in Progress
Tuesday, March 22, 2005 9:07:44 AM UTC  #   

WinDev : Designing Application Managed Authorization

as promised - the slides and source code for my talk about authorization

slides Authz.pdf (220,7 KB)

.NET IIdentity/IPrincipal Roles.zip (16,76 KB)

AzMan AzMan.zip (83,66 KB)

For a more detailed explanation of the AzMan source code - check out the accompanying articles on my blog (just search for AzMan).

thanks

 


Conferences
Saturday, October 30, 2004 7:02:26 AM UTC  #   

AzMan Addendum

Remember SAFEARRAY and VARIANT ??? The AzMan API exposes some of its info in exactly these data types.

e.g. if you want to get a list of members of an application group you grab the Members property of the IAzApplicationGroup object.
Members is a VARIANT datatype which wraps a SAFEARRAY which in turn wraps the members of the application group.

Took me some time to figure out how to handle that in C#. so i thought i share the code with you...

public string[] GetApplicationGroupMembers(string ApplicationGroup)
{
 
foreach (IAzApplicationGroup appGroup in app.ApplicationGroups)
  {
   
if (appGroup.Name == ApplicationGroup)
    {
      System.Array memberArray = (System.Array)appGroup.Members;
     
string[] members = new string[memberArray.GetLength(0)];
     
     
for (int i = 0; i < memberArray.Length; i++)
        members[i] = Convert.ToString(memberArray.GetValue(i));

     
return members;
    }
  } 
 
 
throw new Exception("Application Group not found");
}


Work in Progress
Tuesday, May 18, 2004 3:07:51 AM UTC  #   

AzMan and Custom SIDs - Part 3

in this last part i'll show you the code to do access checks against an AzMan store with custom SIDs.

first, you authenticate the username/password against the database and get the SID in return.

public string Authenticate(string Username, string Password)
{
 
string salt = getSalt(Username);
 
byte[] saltBytes = Convert.FromBase64String(salt);

  string
passwordHash = generateHash(Password, saltBytes, 64);
  string sid = "";

  if (checkPassword(Username, passwordHash, ref sid))
   
return sid;

  return null;
}

after that you can open the AzMan store and create a client context with the returned SID.

IAzClientContext context = app.InitializeClientContextFromStringSid(sid, 1, null);

Note the second parameter. the 1 turns of checking of the SIDs against the Windows User Store. The constant is called AZ_CLIENT_CONTEXT_SKIP_GROUP and its value is set to 1 in azroles.h

you can then pass this client context to the access checks functions of AzMan. the AccessCheck API is quite ugly to use. the AzMan COM Component is made to be used from all COM enabled languages including scripting. so you often have to deal with VARIANTS and that kind of stuff...

public bool accessCheck(IAzClientContext ctx, int operationID)
{
  const int NO_ERROR = 0;
  object[] operations = { operationID };
  object[] scopes = { "" };
  object[] results = (object[])    
  ctx.AccessCheck("Audit Text", scopes, operations, null, null, null, null, null);
  int result = (int)results[0];
  if (NO_ERROR == result)
    return true;
  else
    return false;
}

so, this is a very basic example. the AzMan API has a lot more possibilities. check the documentation and the links i posted before.


Work in Progress
Tuesday, May 11, 2004 2:06:17 PM UTC  #   

AzMan and Custom SIDs - Part 2

Custom SIDs can be added to roles or to application groups.

You will have to do that programmatically because the MMC snapin only gives you the usual User/Group picker for local/domain accounts.

My aproach is to completely configure the AzMan store Operations/Tasks/Roles and Application Groups with the snapin and then add the SIDs to Application Groups through code.

How to open and close AzMan stores and applications (all eror checking omitted for brevity :)

public void OpenApplication(string StorePath, string ApplicationName)
{
  if (storeOpen == true)
    CloseApplication();
            
  store = new AzAuthorizationStoreClass();
  store.Initialize(2, StorePath, null);
  app = store.OpenApplication(ApplicationName, null);
}

public void CloseApplication()
{
  release(app);
  release(store);
}

void release(object o) 
{
   if (null != o)
   {
     while (0 != System.Runtime.InteropServices.Marshal.ReleaseComObject(o))
     continue;
   }
}


How to add and remove the SIDs to/from application groups:

public void AddSidToGroup (string Sid, string ApplicationGroup)
{
  IAzApplicationGroup appGroup = getApplicationGroup(ApplicationGroup);
  if (appGroup == null)
    throw new Exception("Application Group not found");

  appGroup.AddMember(Sid, null);
  appGroup.Submit(0, null);
}

public void RemoveSidFromGroup(string Sid, string ApplicationGroup)
{
  IAzApplicationGroup appGroup = getApplicationGroup(ApplicationGroup);
  if (appGroup == null)
    throw new Exception("Application Group not found");

   appGroup.DeleteMember(Sid, null);
   appGroup.Submit(0, null);
}

private IAzApplicationGroup getApplicationGroup(string ApplicationGroup)
{
   foreach (IAzApplicationGroup appGroup in app.ApplicationGroups)
     if (appGroup.Name == ApplicationGroup)
       return appGroup;

   return null;
}

Part 3 will show how to use that store from the application to do access checks and some management.


Work in Progress
Tuesday, May 04, 2004 5:39:21 AM UTC  #   

AzMan and Custom SIDs - Part 1

Ok – here’s the scenario:

If you have an application which stores the principals in a sql database and you have an AzMan store against which you want to run access checks. How can you combine these?

First of all you have to map your principals to Custom SIDs.

When creating custom SIDs you must establish a SID design for your application. For example, you might have S-1-9-AppInstanceGUID-UserRID, where 9 is the resource manager subauthority, AppInstanceGUID is your Application ID and UserRID is a unique number for the user in the scope of the application instance.

e.g. S-1-9-1-1 for the first app and the first user.

Database Design
The table that stores the principals and the SIDs has the following schema:

Username varchar(50) NOT NULL, Primary Key
ID int NOT NULL Identity
PasswordHash varchar(50) NOT NULL
Salt varchar(200) NOT NULL
Sid varchar(50) NOT NULL

The ID column will help to generate unique user RIDs.

The stored procedure to insert new users and generate a SID:

CREATE PROCEDURE dbo.AddUser
(
  @Username varchar(50),
  @PasswordHash varchar(200),
  @Salt varchar(200),
  @AppID varchar(50)
)
AS

INSERT INTO utSid
  (Username, Salt, PasswordHash, Sid)
  VALUES (@Username, @Salt, @PasswordHash, @AppID)

  update utSid set Sid = @AppID + '-' + Convert(varchar,@@Identity) where ID = @@Identity
 
  select @AppID + '-' + Convert(varchar,@@Identity)

RETURN


Maybe not the most elegant t-sql – but it works. Another option could be to use a column expression to form the SID value....

Passwords, Hashes and Salts

Obviously we don’t want to store the cleartext passwords of our users. We use a salted hash instead. The password hash is formed through : hash(salt, password) by using PKCS#5 which is exposed in the .net framework in the PasswordDeriveBytes class. The salt is a random number generated by RNGCryptoServiceProvider (a cryptographically strong random number generator).

private byte[] generateSalt(int length)
{
  byte[] salt = new byte[length];
  new RNGCryptoServiceProvider().GetBytes(salt);

  return salt;
}

private string generateHash(string password, byte[] salt, int iterations)
{
  PasswordDeriveBytes p = new PasswordDeriveBytes(password, salt, "SHA1", iterations);
  return Convert.ToBase64String(p.GetBytes(16));
}

in part 2 i will show how to interact with the AzMan store.


Work in Progress
Monday, May 03, 2004 9:03:39 PM UTC  #   

AzMan and non-Windows Accounts

One question at the AzMan talk was about how to use AzMan with non-Windows accounts, e.g. with applications that roll their own user management (like Web Applications, SQL Server type user stores) or alternate authentication protocols like RSA SecureID.

What’s pretty cool about AzMan is that you don’t have to necessarily map your roles to windows accounts.

You can stick three different identity types into the AzMan access check functions.

1. Tokens
2. Usernames
3. SIDs

Number 1 clearly maps to Windows Accounts, number 2 maps to Windows Usernames (DOMAIN\USER Format) or results of LDAP queries.

Number 3 can be a SID of a Windows User account or just any SID you store in the AzMan policy store. SIDs don’t get verified against AD or the SAM when adding them to the store or doing access checks.

This feature is very powerful as you can design your own SID structure and map these to your application managed user accounts and – voila – you can use the powerful authorization API within your applications.

When having to integrate other authentication protocols, the new protocol transition feature of Kerberos in Windows 2003 server comes in handy. An application or a gateway could request (after authenticating the user) an S4USelf ticket. This ticket contains a Token which then can be used to feed AzMan.

I’ve written a proof of concept program for the Custom SID scenario. I will post some code in the next days.

more on S4U Kerberos Extensions here.


Work in Progress
Sunday, May 02, 2004 8:13:29 PM UTC  #   

IIR Windows Forum - Microsoft Authorization Manager

I gave a talk about Microsoft Authorization Manager at the IIR Windows Forum in Frankfurt. I was pretty suprised about how many people came to this session (even some more than to the iis 6 security talk directly before ;)

There were also some good questions about intregrating other directory services than ad, combining azMan with other authentication systems like SecureID, mobile scenarios and so on.

the slides and a demo azMan Store can be downloaded (german) here.
An excellent article about AzMan by Keith Brown can be found here.
Technet info about Azman : here.

more to come....


Work in Progress
Sunday, May 02, 2004 1:42:33 PM UTC  #   

AzManBulkImport Update

Joe sent me a new version of his AzMan bulk importer - in the .zip is a changes document. enjoy!

AzManBulkImport123.zip (6.25 KB)

 


Tools
Tuesday, November 14, 2006 2:43:38 PM UTC  #   

New AzMan Whitepaper

Very detailed read:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetserv/html/AzManApps.asp

On a related note, I can recommend Keith's roadmap article for the big picture:

http://msdn.microsoft.com/security/identityaccess/default.aspx?pull=/library/en-us/dnnetserv/html/DotNetIdM.asp

 


Work in Progress
Friday, August 25, 2006 7:04:04 AM UTC  #   

Update for AzMan Bulk Importer

via Joe Langley:

UPDATED 7/24/2006:
Bug fixed where top level application groups were not copied
Option added so that you can have a patch mode (patch only one application in a store...helpful if you have more than one application in a store)
 
UPDATED 7/10/2006:
Bug fixed where nested roles and nested tasks were not copied

AzManBulkImport12.zip (5.55 KB)

 


Tools
Monday, July 24, 2006 6:06:20 PM UTC  #   

Source Code for AzMan Bulk Importer

Joe finally got permission from his employer to realease the source code for the excellent AzMan Export/Import tool.

Essential if you are doing AzMan development.

AzManBulkImport1.zip (5.17 KB)

 


Tools
Monday, June 26, 2006 7:12:53 AM UTC  #   

Creating an Enum for AzMan Operations

Some time ago I posted a little tool that spits out a constants for operations found in an AzMan store.

Joe Langley extended the code a bit and now generates enums. Furthermore it creates a file and you can specify the namespace. You can download his version here.

 


Tools
Saturday, May 27, 2006 8:17:27 AM UTC  #   

AzMan Bulk Importer / Converter

Joe Langley, a guy I speak to from time to time about AzMAn and other security related stuff sent me a very neat utility to import / convert AzMan stores between different formats (XML to AD and vice versa). This allows to painlessly start with local XML stores and import them into AD at some later point.

This tool was written as part of his day job, so unfortunately he is not allowed to release the source code...

AzManBulkImport.zip (11.48 KB)

 


Tools
Monday, January 09, 2006 8:12:23 PM UTC  #   

Why AspNetTokenRoleProvider?

ASP.NET 2.0 ships with three role providers - one for SQL Server, one for AzMan and one for Windows tokens...

The Windows token provider is special - it only works with Windows authentication whereas all the other providers seem to be more targeted at Forms Authentication (the AzMan provider supports both).

Why do I need a role provider for Windows accounts? You don't have to take care of getting roles for Windows users as they come packaged in the token that gets procuced during authentication in IIS.

Well - the WindowsTokenRole provider can do some optimizations to Windows authentication

  • Instead of a WindowsPrincipal you get a RolePrincipal which features a method called GetRoles() that returns all roles as a string array. This is more straightforward than using the code I showed here. You still have access to the underlying WindowsIdentity (Context.User.Identity) and can create a WindowsPrincipal if you have to.
  • RoleManager can cache the roles. The first time you call IsInRole, RolePrincipal will fetch all roles from the token (which requires round trips to the DC to translate the SIDs to "human-readable" names. These names can get cached in the roles cookie (.aspxroles). This saves the roundtrip to the DC on subsequent requests.

So this is really just an (optional) optimization for Windows authentication based web apps. If you want to use role caching make sure to set reasonable timeouts (e.g. 30mins) - otherwise group membership changes for the user will have a high latency in your application.

 


Work in Progress
Sunday, December 04, 2005 7:07:38 AM UTC  #   

Context.User vs. Thread.CurrentPrincipal

The whole .NET authentication/authorization infrastructure is centered around two interfaces: IIdentity (taking care of who the user is - authentication) and IPrincipal (coupling roles with the Identity - used for authorization). The designated place to store that information is Thread.CurrentPrincipal.

Afterwards you do role checks by calling Thread.CurrentPrincipal.IsInRole - or use PrincipalPermission.Demand or [PrincipalPermissionAttribute] (which does nothing else than calling IsInRole on Thread.CurrentPrincipal under the covers). So far so good.

ASP.NET encourages you to use the "convenience" Context.User / Page.User which also point to an IPrincipal implementation and call IsInRole from there. But because PrincipalPermission relies on Thread.CurrentPrincipal and you maybe want to port a library used in desktop applications (where the Thread.CurrentPrincipal style is used) - ASP.NET has to populate Thread.CurrentPrincipal too - and synchronize it with Context.User.

When you want to plug into Forms Authentication in ASP.NET 1.1, you typically handled the AuthenticateRequest event in the HTTP pipeline. There you fetched the roles for the authenticated users, created an IPrincipal implementation and set Context.User to this new principal. Directly after AuthenticateRequest a (mostly) undocumented event fires called "DefaultAuthentication" and a module called DefaultAuthenticationModule subscribes to this event. This module has only one job, to copy Context.User to Thread.CurrentPrincipal so both values are in-sync.

In ASP.NET 2.0 there is the new PostAuthenticateRequest event and I like to think about the relationship between these two events in this way: AuthenticateRequest is used to create the IIdentity (identity information) and PostAuthenticateRequest is used to couple roles to that identity (authorization). The RoleManagerModule which has the job to couple roles from the provider backed store to the authenticated identity subscribes to exactly this event.

There is one gotcha though - ASP.NET does not take care of syncing Context.User and Thread.CurrentPrincipal after PostAuthenticateRequest - which is a bug IMO. So if you follow the pattern you know from 1.1 and set Context.User in PostAuthenticateRequest, Context.User and Thread.CurrentPrincipal will have different values. You may write really complex ASP.NET application whithout ever noticing that, but recently I plugged a custom IPrincipal implementation for AzMan into an ASP.NET 2.0 application and saw strange errors until I found out what the problem was. I set Context.User in PostAuthenticateRequest and my implementation contains an  [AzManPrincipalPermission] which relies on Thread.CurrentPrincipal - but this was set to the wrong value because I relied on ASP.NET to sync to Context.User - which is not the case.

I wonder why the DefaultAuthentication event fires before PostAuthenticateRequest - maybe to guarantee that Thread.CurrentPrincipal and Context.User are correctly populated when the even fires. But why doesn't it also fire then after PostAuthenticateRequest to sync again??

So you basically have 2 choices:

1. Put the code in AuthenticateRequest and set Context.User. There are some implications:

  • Make sure your module runs after the built-in authentication modules
  • You run before RolesManager
  • If you call code from AuthenticateRequest (or another module handles the event after you) that relies on Thread.CurrentPrincipal you have to set it anyway.

2. Put the code in PostAuthenticateRequest (which seems to be the designated place) and set Context.User = Thread.CurrentPrincipal = myPrincipal;

RoleManager also fires a GetRoles event where you can override the role fetching, but if this event is handled (and you set the EventArgs.RolesPopulated property to true) all RoleManager logic will be bypassed (including the step that syncs Context.User and Thread.CurrentPrincipal - aargh).

Proposed solution: Always set Thread.CurrentPrincipal and see those implementation details leak through or Microsoft has to sync both values after PostAuthenticateRequest.

This implementation detail was nicely hidden in 1.1 - why do i have to think about that in 2.0 ??

any thoughts?

 


Work in Progress
Wednesday, November 23, 2005 8:25:43 AM UTC  #   

Authorization Manager and Vista

I just spotted that AzMan under Vista (build 5219) now support three types of authorization stores. Active Directory/ADAM, XML and ...tada.. SQL Server.

 


Work in Progress
Sunday, September 18, 2005 9:10:59 PM UTC  #   

Authorization Manager Table of Contents

just a summary of AzMan related content on this blog (will be updated when new stuff comes in)

Some off-site links:

 


For Your Favourites
Monday, May 09, 2005 5:24:14 AM UTC  #   

Back from the Indigo SDR

Last week I attended the Indigo SDR in Munich. First of all it was fun to hang out with my fellow DM buddies Marcus and Marvin, and of course Aaron, who was our instructor for the 3 days.

I will not be too over-enthusiastic, but what i've seen so far is a nice programming model, which seems to make sense (after thinking about it) and will hopefully reduce a lot of the complexities that many devs face today (e.g. choosing which technology over the other or painfully try to combine several technology stacks).

A lot of effort has been put into the bridging of the XML/Objects impedance mismatch, and time will tell if we can build XML messaging based systems in the future without touching (or maybe even knowing) angle brackets.

Here comes the obligatory security part :)

  • Seems that all binding (besides WSI-BP) have security enabled by default - which is good
  • I suggested to force even WSI-BP to work only over SSL by default (and that we have to manually disable that). The other attendees didn't like the idea :)
  • I really like that there is now an easy mechanism for services to provide a certificate with which a client can encrypt UsernameTokens (config setting, no coding)
  • Indigo config files will get tremendously complex, and complexity is the natural enemy of security. We really need good tools that check config files for plausability. In addition i want something like the WSE Policy Advisor and big red lights if something with the security config is wrong. As a side note - i just assume the Indigo configs are compatible with the .NET 2.0 ProtectedConfiguration providers (but haven't tried, yet).
  • What's really annoying is, that there is no built-in validation of the incoming messages against schema. While this is a general problem, everybody knows that input validation is maybe the most crucial part in today's application security. Please, Microsoft, include a validator - this does not have to be the standard behaviour - but it would be so nice to just flip a switch and have validation (and support for XSD Patterns and other restrictions).
  • I was happy to see that the authorization demos were centered around AzMan.
  • System.Security.Authorization seems to be an interesting new namespace. Pierre wrote about it already.

Will Indigo put instructors and consultants out of business (quoting dbox) ? Surely not. I expect a lot of people to use the straightforward programming interface right out of the box - but problems will arise later in the project (meet LOLA) - we will see if we can solve these problems then by reconfiguring and rebinding, without changing the code in the function.

The three days were a really nice overview, and i will definitely dive into the security APIs as soon as they look a little more stabilized. Good work!

 


Work in Progress
Sunday, May 08, 2005 6:41:08 PM UTC  #   

Another way of integrating AzMan

I am currently playing around with a custom IPrincipal implementation that uses AzMan as a backing store. There are other implementations around, but what strikes me odd is, that most of them only use the role storage features - which is IMO only 40% of the functionality provided.

A really powerful feature of AzMan is to map roles to operations in your application, e.g. you could have a operation "DeleteCustomer" and do an access check11 if the current user is allowed to delete that customer (of course this boils down to checking if the user is in a specific role that is allowed to execute that operation), but that is another layer of abstraction, and you don't have to hard-code role names in your code.


So i came up with the following usage pattern:

You replace your current principal with my AzManPrincipal - base it on some identity (more on that later) and point to your AzMan store and application name:

Thread.CurrentPrincipal = new AzManPrincipal(WindowsIdentity.GetCurrent(), @"msxml://c:\etc\source\1.1\AzManPrincipal\TestStore.xml", "TestApplication");

after that you can of course call IsInRole on that principal

[Test]
public void IsBoss()
{
  bool member = Thread.CurrentPrincipal.IsInRole("Boss");
  Assert.AreEqual(true, member);
}

but you can also ask if the current user is allowed to execute an operation, like (and this uses the AzManOpConst tool i posted earlier):

[Test]
public void TestOperation1()
{
  bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess(Operations.GiveRaise);
  Assert.AreEqual(true, allowed);
}

but the thing i find most compelling is to tie your code to an AzMan operation by using attributes, like this:

[Test]
[Operation(Operations.GiveRaise)]
public void TestOperation1Attribute()
{
  bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess();
  Assert.AreEqual(true, allowed);
}

HasAccess() returns a boolean, another option is to use CheckAccess() which will throw a SecurityException if necessary, like this

[Test]
[ExpectedException(typeof(SecurityException))]
[Operation(Operations.EnterCafeteria)]
public void CheckOperation2Attribute()
{
  ((AzManPrincipal) Thread.CurrentPrincipal).CheckAccess();
}

When we set up the Principal I used the current WindowsIdentity. I also implemented support for FormsIdentity (this will pickup the .Name property in the format Domain\Username to initialize the context) as well as a AzManCustomSidIdentity (to use with Custom SIDs).

So - what is missing?

  • I like to have a AzManPrincipalPermission to use declaratively as well as imperatively
  • A lot of testing

This stuff is not finished yet - but i wanted to share the programming model with you - do you like that, does that make sense?? Any comments??

Feedback is welcome.

 


Work in Progress
Tuesday, May 03, 2005 7:41:35 PM UTC  #   

AzMan Operations Helper Tool

I am currently working on some AzMan related tools/sample code (e.g. an IPrincipal implementation with some cool extra goodies) - as a side effect i wrote a little tool which parses an AzMan store and creates a class with consts that map to your AzMan operations, like:

public class Operations
{
    public const int opGiveRaise = 1;
    public const int opLeaveEarly = 2;
    public const int opEnterCafeteria = 3;
    public const int opRant = 4;
}

just point the tool to the store and the application.

AzManCreateOpConsts msxml://c:\store.xml TestApplication

There is more stuff coming up...

AzManCreateOpConsts.zip (27.88 KB)

 


Work in Progress
Monday, April 04, 2005 10:22:41 PM UTC  #   

The Future of AzMan?

I wrote a lot about Authorization Manager in the past, and i really believe that this piece of technology is extremely useful to virtualize your authorization decisions in complex applications.

Everytime I demo AzMan to customers or students, they really like the feature set - but some questions come up every time - why isn't this tool more popular? Does it have a future? If we base our applications completely on AzMan, what will happen when MSFT decides to deprecate it in favour of some other funky new technology??

I didn't have answers for them - but yesterday i finally made it to watch the ADFS episode on the .NET Show - they demo'd AzMan and the new federation services - seems that these technologies will go hand in hand in the future, and there will be some interesting new features in AzMan that make me believe that there is indeed a future, which is good.

The new version of AzMan will be shipped in Server 2003 R2 and includes

  • Support for SAML Tokens and Assertions (or Statements)
  • Support for ADAM Principles

OK - so now i want to see a managed implementation, GUI support for custom SIDs and a final word if the AuthorizationStoreRoleProvider will make it in the final ASP.NET 2.0 bits...

Go watch the show - this is extremely cool stuff....

 


For Your Favourites | Work in Progress
Tuesday, March 22, 2005 9:07:44 AM UTC  #   

WinDev : Designing Application Managed Authorization

as promised - the slides and source code for my talk about authorization

slides Authz.pdf (220,7 KB)

.NET IIdentity/IPrincipal Roles.zip (16,76 KB)

AzMan AzMan.zip (83,66 KB)

For a more detailed explanation of the AzMan source code - check out the accompanying articles on my blog (just search for AzMan).

thanks

 


Conferences
Saturday, October 30, 2004 7:02:26 AM UTC  #   

AzMan Addendum

Remember SAFEARRAY and VARIANT ??? The AzMan API exposes some of its info in exactly these data types.

e.g. if you want to get a list of members of an application group you grab the Members property of the IAzApplicationGroup object.
Members is a VARIANT datatype which wraps a SAFEARRAY which in turn wraps the members of the application group.

Took me some time to figure out how to handle that in C#. so i thought i share the code with you...

public string[] GetApplicationGroupMembers(string ApplicationGroup)
{
 
foreach (IAzApplicationGroup appGroup in app.ApplicationGroups)
  {
   
if (appGroup.Name == ApplicationGroup)
    {
      System.Array memberArray = (System.Array)appGroup.Members;
     
string[] members = new string[memberArray.GetLength(0)];
     
     
for (int i = 0; i < memberArray.Length; i++)
        members[i] = Convert.ToString(memberArray.GetValue(i));

     
return members;
    }
  } 
 
 
throw new Exception("Application Group not found");
}


Work in Progress
Tuesday, May 18, 2004 3:07:51 AM UTC  #   

AzMan and Custom SIDs - Part 3

in this last part i'll show you the code to do access checks against an AzMan store with custom SIDs.

first, you authenticate the username/password against the database and get the SID in return.

public string Authenticate(string Username, string Password)
{
 
string salt = getSalt(Username);
 
byte[] saltBytes = Convert.FromBase64String(salt);

  string
passwordHash = generateHash(Password, saltBytes, 64);
  string sid = "";

  if (checkPassword(Username, passwordHash, ref sid))
   
return sid;

  return null;
}

after that you can open the AzMan store and create a client context with the returned SID.

IAzClientContext context = app.InitializeClientContextFromStringSid(sid, 1, null);

Note the second parameter. the 1 turns of checking of the SIDs against the Windows User Store. The constant is called AZ_CLIENT_CONTEXT_SKIP_GROUP and its value is set to 1 in azroles.h

you can then pass this client context to the access checks functions of AzMan. the AccessCheck API is quite ugly to use. the AzMan COM Component is made to be used from all COM enabled languages including scripting. so you often have to deal with VARIANTS and that kind of stuff...

public bool accessCheck(IAzClientContext ctx, int operationID)
{
  const int NO_ERROR = 0;
  object[] operations = { operationID };
  object[] scopes = { "" };
  object[] results = (object[])    
  ctx.AccessCheck("Audit Text", scopes, operations, null, null, null, null, null);
  int result = (int)results[0];
  if (NO_ERROR == result)
    return true;
  else
    return false;
}

so, this is a very basic example. the AzMan API has a lot more possibilities. check the documentation and the links i posted before.


Work in Progress
Tuesday, May 11, 2004 2:06:17 PM UTC  #   

AzMan and Custom SIDs - Part 2

Custom SIDs can be added to roles or to application groups.

You will have to do that programmatically because the MMC snapin only gives you the usual User/Group picker for local/domain accounts.

My aproach is to completely configure the AzMan store Operations/Tasks/Roles and Application Groups with the snapin and then add the SIDs to Application Groups through code.

How to open and close AzMan stores and applications (all eror checking omitted for brevity :)

public void OpenApplication(string StorePath, string ApplicationName)
{
  if (storeOpen == true)
    CloseApplication();
            
  store = new AzAuthorizationStoreClass();
  store.Initialize(2, StorePath, null);
  app = store.OpenApplication(ApplicationName, null);
}

public void CloseApplication()
{
  release(app);
  release(store);
}

void release(object o) 
{
   if (null != o)
   {
     while (0 != System.Runtime.InteropServices.Marshal.ReleaseComObject(o))
     continue;
   }
}


How to add and remove the SIDs to/from application groups:

public void AddSidToGroup (string Sid, string ApplicationGroup)
{
  IAzApplicationGroup appGroup = getApplicationGroup(ApplicationGroup);
  if (appGroup == null)
    throw new Exception("Application Group not found");

  appGroup.AddMember(Sid, null);
  appGroup.Submit(0, null);
}

public void RemoveSidFromGroup(string Sid, string ApplicationGroup)
{
  IAzApplicationGroup appGroup = getApplicationGroup(ApplicationGroup);
  if (appGroup == null)
    throw new Exception("Application Group not found");

   appGroup.DeleteMember(Sid, null);
   appGroup.Submit(0, null);
}

private IAzApplicationGroup getApplicationGroup(string ApplicationGroup)
{
   foreach (IAzApplicationGroup appGroup in app.ApplicationGroups)
     if (appGroup.Name == ApplicationGroup)
       return appGroup;

   return null;
}

Part 3 will show how to use that store from the application to do access checks and some management.


Work in Progress
Tuesday, May 04, 2004 5:39:21 AM UTC  #   

AzMan and Custom SIDs - Part 1

Ok – here’s the scenario:

If you have an application which stores the principals in a sql database and you have an AzMan store against which you want to run access checks. How can you combine these?

First of all you have to map your principals to Custom SIDs.

When creating custom SIDs you must establish a SID design for your application. For example, you might have S-1-9-AppInstanceGUID-UserRID, where 9 is the resource manager subauthority, AppInstanceGUID is your Application ID and UserRID is a unique number for the user in the scope of the application instance.

e.g. S-1-9-1-1 for the first app and the first user.

Database Design
The table that stores the principals and the SIDs has the following schema:

Username varchar(50) NOT NULL, Primary Key
ID int NOT NULL Identity
PasswordHash varchar(50) NOT NULL
Salt varchar(200) NOT NULL
Sid varchar(50) NOT NULL

The ID column will help to generate unique user RIDs.

The stored procedure to insert new users and generate a SID:

CREATE PROCEDURE dbo.AddUser
(
  @Username varchar(50),
  @PasswordHash varchar(200),
  @Salt varchar(200),
  @AppID varchar(50)
)
AS

INSERT INTO utSid
  (Username, Salt, PasswordHash, Sid)
  VALUES (@Username, @Salt, @PasswordHash, @AppID)

  update utSid set Sid = @AppID + '-' + Convert(varchar,@@Identity) where ID = @@Identity
 
  select @AppID + '-' + Convert(varchar,@@Identity)

RETURN


Maybe not the most elegant t-sql – but it works. Another option could be to use a column expression to form the SID value....

Passwords, Hashes and Salts

Obviously we don’t want to store the cleartext passwords of our users. We use a salted hash instead. The password hash is formed through : hash(salt, password) by using PKCS#5 which is exposed in the .net framework in the PasswordDeriveBytes class. The salt is a random number generated by RNGCryptoServiceProvider (a cryptographically strong random number generator).

private byte[] generateSalt(int length)
{
  byte[] salt = new byte[length];
  new RNGCryptoServiceProvider().GetBytes(salt);

  return salt;
}

private string generateHash(string password, byte[] salt, int iterations)
{
  PasswordDeriveBytes p = new PasswordDeriveBytes(password, salt, "SHA1", iterations);
  return Convert.ToBase64String(p.GetBytes(16));
}

in part 2 i will show how to interact with the AzMan store.


Work in Progress
Monday, May 03, 2004 9:03:39 PM UTC  #   

AzMan and non-Windows Accounts

One question at the AzMan talk was about how to use AzMan with non-Windows accounts, e.g. with applications that roll their own user management (like Web Applications, SQL Server type user stores) or alternate authentication protocols like RSA SecureID.

What’s pretty cool about AzMan is that you don’t have to necessarily map your roles to windows accounts.

You can stick three different identity types into the AzMan access check functions.

1. Tokens
2. Usernames
3. SIDs

Number 1 clearly maps to Windows Accounts, number 2 maps to Windows Usernames (DOMAIN\USER Format) or results of LDAP queries.

Number 3 can be a SID of a Windows User account or just any SID you store in the AzMan policy store. SIDs don’t get verified against AD or the SAM when adding them to the store or doing access checks.

This feature is very powerful as you can design your own SID structure and map these to your application managed user accounts and – voila – you can use the powerful authorization API within your applications.

When having to integrate other authentication protocols, the new protocol transition feature of Kerberos in Windows 2003 server comes in handy. An application or a gateway could request (after authenticating the user) an S4USelf ticket. This ticket contains a Token which then can be used to feed AzMan.

I’ve written a proof of concept program for the Custom SID scenario. I will post some code in the next days.

more on S4U Kerberos Extensions here.


Work in Progress
Sunday, May 02, 2004 8:13:29 PM UTC  #   

IIR Windows Forum - Microsoft Authorization Manager

I gave a talk about Microsoft Authorization Manager at the IIR Windows Forum in Frankfurt. I was pretty suprised about how many people came to this session (even some more than to the iis 6 security talk directly before ;)

There were also some good questions about intregrating other directory services than ad, combining azMan with other authentication systems like SecureID, mobile scenarios and so on.

the slides and a demo azMan Store can be downloaded (german) here.
An excellent article about AzMan by Keith Brown can be found here.
Technet info about Azman : here.

more to come....


Work in Progress
Sunday, May 02, 2004 1:42:33 PM UTC  #   

AzManBulkImport Update

Joe sent me a new version of his AzMan bulk importer - in the .zip is a changes document. enjoy!

AzManBulkImport123.zip (6.25 KB)

 


Tools
Tuesday, November 14, 2006 2:43:38 PM UTC  #   

New AzMan Whitepaper

Very detailed read:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetserv/html/AzManApps.asp

On a related note, I can recommend Keith's roadmap article for the big picture:

http://msdn.microsoft.com/security/identityaccess/default.aspx?pull=/library/en-us/dnnetserv/html/DotNetIdM.asp

 


Work in Progress
Friday, August 25, 2006 7:04:04 AM UTC  #   

Update for AzMan Bulk Importer

via Joe Langley:

UPDATED 7/24/2006:
Bug fixed where top level application groups were not copied
Option added so that you can have a patch mode (patch only one application in a store...helpful if you have more than one application in a store)
 
UPDATED 7/10/2006:
Bug fixed where nested roles and nested tasks were not copied

AzManBulkImport12.zip (5.55 KB)

 


Tools
Monday, July 24, 2006 6:06:20 PM UTC  #   

Source Code for AzMan Bulk Importer

Joe finally got permission from his employer to realease the source code for the excellent AzMan Export/Import tool.

Essential if you are doing AzMan development.

AzManBulkImport1.zip (5.17 KB)

 


Tools
Monday, June 26, 2006 7:12:53 AM UTC  #   

Creating an Enum for AzMan Operations

Some time ago I posted a little tool that spits out a constants for operations found in an AzMan store.

Joe Langley extended the code a bit and now generates enums. Furthermore it creates a file and you can specify the namespace. You can download his version here.

 


Tools
Saturday, May 27, 2006 8:17:27 AM UTC  #   

AzMan Bulk Importer / Converter

Joe Langley, a guy I speak to from time to time about AzMAn and other security related stuff sent me a very neat utility to import / convert AzMan stores between different formats (XML to AD and vice versa). This allows to painlessly start with local XML stores and import them into AD at some later point.

This tool was written as part of his day job, so unfortunately he is not allowed to release the source code...

AzManBulkImport.zip (11.48 KB)

 


Tools
Monday, January 09, 2006 8:12:23 PM UTC  #   

Why AspNetTokenRoleProvider?

ASP.NET 2.0 ships with three role providers - one for SQL Server, one for AzMan and one for Windows tokens...

The Windows token provider is special - it only works with Windows authentication whereas all the other providers seem to be more targeted at Forms Authentication (the AzMan provider supports both).

Why do I need a role provider for Windows accounts? You don't have to take care of getting roles for Windows users as they come packaged in the token that gets procuced during authentication in IIS.

Well - the WindowsTokenRole provider can do some optimizations to Windows authentication

  • Instead of a WindowsPrincipal you get a RolePrincipal which features a method called GetRoles() that returns all roles as a string array. This is more straightforward than using the code I showed here. You still have access to the underlying WindowsIdentity (Context.User.Identity) and can create a WindowsPrincipal if you have to.
  • RoleManager can cache the roles. The first time you call IsInRole, RolePrincipal will fetch all roles from the token (which requires round trips to the DC to translate the SIDs to "human-readable" names. These names can get cached in the roles cookie (.aspxroles). This saves the roundtrip to the DC on subsequent requests.

So this is really just an (optional) optimization for Windows authentication based web apps. If you want to use role caching make sure to set reasonable timeouts (e.g. 30mins) - otherwise group membership changes for the user will have a high latency in your application.

 


Work in Progress
Sunday, December 04, 2005 7:07:38 AM UTC  #   

Context.User vs. Thread.CurrentPrincipal

The whole .NET authentication/authorization infrastructure is centered around two interfaces: IIdentity (taking care of who the user is - authentication) and IPrincipal (coupling roles with the Identity - used for authorization). The designated place to store that information is Thread.CurrentPrincipal.

Afterwards you do role checks by calling Thread.CurrentPrincipal.IsInRole - or use PrincipalPermission.Demand or [PrincipalPermissionAttribute] (which does nothing else than calling IsInRole on Thread.CurrentPrincipal under the covers). So far so good.

ASP.NET encourages you to use the "convenience" Context.User / Page.User which also point to an IPrincipal implementation and call IsInRole from there. But because PrincipalPermission relies on Thread.CurrentPrincipal and you maybe want to port a library used in desktop applications (where the Thread.CurrentPrincipal style is used) - ASP.NET has to populate Thread.CurrentPrincipal too - and synchronize it with Context.User.

When you want to plug into Forms Authentication in ASP.NET 1.1, you typically handled the AuthenticateRequest event in the HTTP pipeline. There you fetched the roles for the authenticated users, created an IPrincipal implementation and set Context.User to this new principal. Directly after AuthenticateRequest a (mostly) undocumented event fires called "DefaultAuthentication" and a module called DefaultAuthenticationModule subscribes to this event. This module has only one job, to copy Context.User to Thread.CurrentPrincipal so both values are in-sync.

In ASP.NET 2.0 there is the new PostAuthenticateRequest event and I like to think about the relationship between these two events in this way: AuthenticateRequest is used to create the IIdentity (identity information) and PostAuthenticateRequest is used to couple roles to that identity (authorization). The RoleManagerModule which has the job to couple roles from the provider backed store to the authenticated identity subscribes to exactly this event.

There is one gotcha though - ASP.NET does not take care of syncing Context.User and Thread.CurrentPrincipal after PostAuthenticateRequest - which is a bug IMO. So if you follow the pattern you know from 1.1 and set Context.User in PostAuthenticateRequest, Context.User and Thread.CurrentPrincipal will have different values. You may write really complex ASP.NET application whithout ever noticing that, but recently I plugged a custom IPrincipal implementation for AzMan into an ASP.NET 2.0 application and saw strange errors until I found out what the problem was. I set Context.User in PostAuthenticateRequest and my implementation contains an  [AzManPrincipalPermission] which relies on Thread.CurrentPrincipal - but this was set to the wrong value because I relied on ASP.NET to sync to Context.User - which is not the case.

I wonder why the DefaultAuthentication event fires before PostAuthenticateRequest - maybe to guarantee that Thread.CurrentPrincipal and Context.User are correctly populated when the even fires. But why doesn't it also fire then after PostAuthenticateRequest to sync again??

So you basically have 2 choices:

1. Put the code in AuthenticateRequest and set Context.User. There are some implications:

  • Make sure your module runs after the built-in authentication modules
  • You run before RolesManager
  • If you call code from AuthenticateRequest (or another module handles the event after you) that relies on Thread.CurrentPrincipal you have to set it anyway.

2. Put the code in PostAuthenticateRequest (which seems to be the designated place) and set Context.User = Thread.CurrentPrincipal = myPrincipal;

RoleManager also fires a GetRoles event where you can override the role fetching, but if this event is handled (and you set the EventArgs.RolesPopulated property to true) all RoleManager logic will be bypassed (including the step that syncs Context.User and Thread.CurrentPrincipal - aargh).

Proposed solution: Always set Thread.CurrentPrincipal and see those implementation details leak through or Microsoft has to sync both values after PostAuthenticateRequest.

This implementation detail was nicely hidden in 1.1 - why do i have to think about that in 2.0 ??

any thoughts?

 


Work in Progress
Wednesday, November 23, 2005 8:25:43 AM UTC  #   

Authorization Manager and Vista

I just spotted that AzMan under Vista (build 5219) now support three types of authorization stores. Active Directory/ADAM, XML and ...tada.. SQL Server.

 


Work in Progress
Sunday, September 18, 2005 9:10:59 PM UTC  #   

Authorization Manager Table of Contents

just a summary of AzMan related content on this blog (will be updated when new stuff comes in)

Some off-site links:

 


For Your Favourites
Monday, May 09, 2005 5:24:14 AM UTC  #   

Back from the Indigo SDR

Last week I attended the Indigo SDR in Munich. First of all it was fun to hang out with my fellow DM buddies Marcus and Marvin, and of course Aaron, who was our instructor for the 3 days.

I will not be too over-enthusiastic, but what i've seen so far is a nice programming model, which seems to make sense (after thinking about it) and will hopefully reduce a lot of the complexities that many devs face today (e.g. choosing which technology over the other or painfully try to combine several technology stacks).

A lot of effort has been put into the bridging of the XML/Objects impedance mismatch, and time will tell if we can build XML messaging based systems in the future without touching (or maybe even knowing) angle brackets.

Here comes the obligatory security part :)

  • Seems that all binding (besides WSI-BP) have security enabled by default - which is good
  • I suggested to force even WSI-BP to work only over SSL by default (and that we have to manually disable that). The other attendees didn't like the idea :)
  • I really like that there is now an easy mechanism for services to provide a certificate with which a client can encrypt UsernameTokens (config setting, no coding)
  • Indigo config files will get tremendously complex, and complexity is the natural enemy of security. We really need good tools that check config files for plausability. In addition i want something like the WSE Policy Advisor and big red lights if something with the security config is wrong. As a side note - i just assume the Indigo configs are compatible with the .NET 2.0 ProtectedConfiguration providers (but haven't tried, yet).
  • What's really annoying is, that there is no built-in validation of the incoming messages against schema. While this is a general problem, everybody knows that input validation is maybe the most crucial part in today's application security. Please, Microsoft, include a validator - this does not have to be the standard behaviour - but it would be so nice to just flip a switch and have validation (and support for XSD Patterns and other restrictions).
  • I was happy to see that the authorization demos were centered around AzMan.
  • System.Security.Authorization seems to be an interesting new namespace. Pierre wrote about it already.

Will Indigo put instructors and consultants out of business (quoting dbox) ? Surely not. I expect a lot of people to use the straightforward programming interface right out of the box - but problems will arise later in the project (meet LOLA) - we will see if we can solve these problems then by reconfiguring and rebinding, without changing the code in the function.

The three days were a really nice overview, and i will definitely dive into the security APIs as soon as they look a little more stabilized. Good work!

 


Work in Progress
Sunday, May 08, 2005 6:41:08 PM UTC  #   

Another way of integrating AzMan

I am currently playing around with a custom IPrincipal implementation that uses AzMan as a backing store. There are other implementations around, but what strikes me odd is, that most of them only use the role storage features - which is IMO only 40% of the functionality provided.

A really powerful feature of AzMan is to map roles to operations in your application, e.g. you could have a operation "DeleteCustomer" and do an access check11 if the current user is allowed to delete that customer (of course this boils down to checking if the user is in a specific role that is allowed to execute that operation), but that is another layer of abstraction, and you don't have to hard-code role names in your code.


So i came up with the following usage pattern:

You replace your current principal with my AzManPrincipal - base it on some identity (more on that later) and point to your AzMan store and application name:

Thread.CurrentPrincipal = new AzManPrincipal(WindowsIdentity.GetCurrent(), @"msxml://c:\etc\source\1.1\AzManPrincipal\TestStore.xml", "TestApplication");

after that you can of course call IsInRole on that principal

[Test]
public void IsBoss()
{
  bool member = Thread.CurrentPrincipal.IsInRole("Boss");
  Assert.AreEqual(true, member);
}

but you can also ask if the current user is allowed to execute an operation, like (and this uses the AzManOpConst tool i posted earlier):

[Test]
public void TestOperation1()
{
  bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess(Operations.GiveRaise);
  Assert.AreEqual(true, allowed);
}

but the thing i find most compelling is to tie your code to an AzMan operation by using attributes, like this:

[Test]
[Operation(Operations.GiveRaise)]
public void TestOperation1Attribute()
{
  bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess();
  Assert.AreEqual(true, allowed);
}

HasAccess() returns a boolean, another option is to use CheckAccess() which will throw a SecurityException if necessary, like this

[Test]
[ExpectedException(typeof(SecurityException))]
[Operation(Operations.EnterCafeteria)]
public void CheckOperation2Attribute()
{
  ((AzManPrincipal) Thread.CurrentPrincipal).CheckAccess();
}

When we set up the Principal I used the current WindowsIdentity. I also implemented support for FormsIdentity (this will pickup the .Name property in the format Domain\Username to initialize the context) as well as a AzManCustomSidIdentity (to use with Custom SIDs).

So - what is missing?

  • I like to have a AzManPrincipalPermission to use declaratively as well as imperatively
  • A lot of testing

This stuff is not finished yet - but i wanted to share the programming model with you - do you like that, does that make sense?? Any comments??

Feedback is welcome.

 


Work in Progress
Tuesday, May 03, 2005 7:41:35 PM UTC  #   

AzMan Operations Helper Tool

I am currently working on some AzMan related tools/sample code (e.g. an IPrincipal implementation with some cool extra goodies) - as a side effect i wrote a little tool which parses an AzMan store and creates a class with consts that map to your AzMan operations, like:

public class Operations
{
    public const int opGiveRaise = 1;
    public const int opLeaveEarly = 2;
    public const int opEnterCafeteria = 3;
    public const int opRant = 4;
}

just point the tool to the store and the application.

AzManCreateOpConsts msxml://c:\store.xml TestApplication

There is more stuff coming up...

AzManCreateOpConsts.zip (27.88 KB)

 


Work in Progress
Monday, April 04, 2005 10:22:41 PM UTC  #   

The Future of AzMan?

I wrote a lot about Authorization Manager in the past, and i really believe that this piece of technology is extremely useful to virtualize your authorization decisions in complex applications.

Everytime I demo AzMan to customers or students, they really like the feature set - but some questions come up every time - why isn't this tool more popular? Does it have a future? If we base our applications completely on AzMan, what will happen when MSFT decides to deprecate it in favour of some other funky new technology??

I didn't have answers for them - but yesterday i finally made it to watch the ADFS episode on the .NET Show - they demo'd AzMan and the new federation services - seems that these technologies will go hand in hand in the future, and there will be some interesting new features in AzMan that make me believe that there is indeed a future, which is good.

The new version of AzMan will be shipped in Server 2003 R2 and includes

  • Support for SAML Tokens and Assertions (or Statements)
  • Support for ADAM Principles

OK - so now i want to see a managed implementation, GUI support for custom SIDs and a final word if the AuthorizationStoreRoleProvider will make it in the final ASP.NET 2.0 bits...

Go watch the show - this is extremely cool stuff....

 


For Your Favourites | Work in Progress
Tuesday, March 22, 2005 9:07:44 AM UTC  #   

WinDev : Designing Application Managed Authorization

as promised - the slides and source code for my talk about authorization

slides Authz.pdf (220,7 KB)

.NET IIdentity/IPrincipal Roles.zip (16,76 KB)

AzMan AzMan.zip (83,66 KB)

For a more detailed explanation of the AzMan source code - check out the accompanying articles on my blog (just search for AzMan).

thanks

 


Conferences
Saturday, October 30, 2004 7:02:26 AM UTC  #   

AzMan Addendum

Remember SAFEARRAY and VARIANT ??? The AzMan API exposes some of its info in exactly these data types.

e.g. if you want to get a list of members of an application group you grab the Members property of the IAzApplicationGroup object.
Members is a VARIANT datatype which wraps a SAFEARRAY which in turn wraps the members of the application group.

Took me some time to figure out how to handle that in C#. so i thought i share the code with you...

public string[] GetApplicationGroupMembers(string ApplicationGroup)
{
 
foreach (IAzApplicationGroup appGroup in app.ApplicationGroups)
  {
   
if (appGroup.Name == ApplicationGroup)
    {
      System.Array memberArray = (System.Array)appGroup.Members;
     
string[] members = new string[memberArray.GetLength(0)];
     
     
for (int i = 0; i < memberArray.Length; i++)
        members[i] = Convert.ToString(memberArray.GetValue(i));

     
return members;
    }
  } 
 
 
throw new Exception("Application Group not found");
}


Work in Progress
Tuesday, May 18, 2004 3:07:51 AM UTC  #   

AzMan and Custom SIDs - Part 3

in this last part i'll show you the code to do access checks against an AzMan store with custom SIDs.

first, you authenticate the username/password against the database and get the SID in return.

public string Authenticate(string Username, string Password)
{
 
string salt = getSalt(Username);
 
byte[] saltBytes = Convert.FromBase64String(salt);

  string
passwordHash = generateHash(Password, saltBytes, 64);
  string sid = "";

  if (checkPassword(Username, passwordHash, ref sid))
   
return sid;

  return null;
}

after that you can open the AzMan store and create a client context with the returned SID.

IAzClientContext context = app.InitializeClientContextFromStringSid(sid, 1, null);

Note the second parameter. the 1 turns of checking of the SIDs against the Windows User Store. The constant is called AZ_CLIENT_CONTEXT_SKIP_GROUP and its value is set to 1 in azroles.h

you can then pass this client context to the access checks functions of AzMan. the AccessCheck API is quite ugly to use. the AzMan COM Component is made to be used from all COM enabled languages including scripting. so you often have to deal with VARIANTS and that kind of stuff...

public bool accessCheck(IAzClientContext ctx, int operationID)
{
  const int NO_ERROR = 0;
  object[] operations = { operationID };
  object[] scopes = { "" };
  object[] results = (object[])    
  ctx.AccessCheck("Audit Text", scopes, operations, null, null, null, null, null);
  int result = (int)results[0];
  if (NO_ERROR == result)
    return true;
  else
    return false;
}

so, this is a very basic example. the AzMan API has a lot more possibilities. check the documentation and the links i posted before.


Work in Progress
Tuesday, May 11, 2004 2:06:17 PM UTC  #   

AzMan and Custom SIDs - Part 2

Custom SIDs can be added to roles or to application groups.

You will have to do that programmatically because the MMC snapin only gives you the usual User/Group picker for local/domain accounts.

My aproach is to completely configure the AzMan store Operations/Tasks/Roles and Application Groups with the snapin and then add the SIDs to Application Groups through code.

How to open and close AzMan stores and applications (all eror checking omitted for brevity :)

public void OpenApplication(string StorePath, string ApplicationName)
{
  if (storeOpen == true)
    CloseApplication();
            
  store = new AzAuthorizationStoreClass();
  store.Initialize(2, StorePath, null);
  app = store.OpenApplication(ApplicationName, null);
}

public void CloseApplication()
{
  release(app);
  release(store);
}

void release(object o) 
{
   if (null != o)
   {
     while (0 != System.Runtime.InteropServices.Marshal.ReleaseComObject(o))
     continue;
   }
}


How to add and remove the SIDs to/from application groups:

public void AddSidToGroup (string Sid, string ApplicationGroup)
{
  IAzApplicationGroup appGroup = getApplicationGroup(ApplicationGroup);
  if (appGroup == null)
    throw new Exception("Application Group not found");

  appGroup.AddMember(Sid, null);
  appGroup.Submit(0, null);
}

public void RemoveSidFromGroup(string Sid, string ApplicationGroup)
{
  IAzApplicationGroup appGroup = getApplicationGroup(ApplicationGroup);
  if (appGroup == null)
    throw new Exception("Application Group not found");

   appGroup.DeleteMember(Sid, null);
   appGroup.Submit(0, null);
}

private IAzApplicationGroup getApplicationGroup(string ApplicationGroup)
{
   foreach (IAzApplicationGroup appGroup in app.ApplicationGroups)
     if (appGroup.Name == ApplicationGroup)
       return appGroup;

   return null;
}

Part 3 will show how to use that store from the application to do access checks and some management.


Work in Progress
Tuesday, May 04, 2004 5:39:21 AM UTC  #   

AzMan and Custom SIDs - Part 1

Ok – here’s the scenario:

If you have an application which stores the principals in a sql database and you have an AzMan store against which you want to run access checks. How can you combine these?

First of all you have to map your principals to Custom SIDs.

When creating custom SIDs you must establish a SID design for your application. For example, you might have S-1-9-AppInstanceGUID-UserRID, where 9 is the resource manager subauthority, AppInstanceGUID is your Application ID and UserRID is a unique number for the user in the scope of the application instance.

e.g. S-1-9-1-1 for the first app and the first user.

Database Design
The table that stores the principals and the SIDs has the following schema:

Username varchar(50) NOT NULL, Primary Key
ID int NOT NULL Identity
PasswordHash varchar(50) NOT NULL
Salt varchar(200) NOT NULL
Sid varchar(50) NOT NULL

The ID column will help to generate unique user RIDs.

The stored procedure to insert new users and generate a SID:

CREATE PROCEDURE dbo.AddUser
(
  @Username varchar(50),
  @PasswordHash varchar(200),
  @Salt varchar(200),
  @AppID varchar(50)
)
AS

INSERT INTO utSid
  (Username, Salt, PasswordHash, Sid)
  VALUES (@Username, @Salt, @PasswordHash, @AppID)

  update utSid set Sid = @AppID + '-' + Convert(varchar,@@Identity) where ID = @@Identity
 
  select @AppID + '-' + Convert(varchar,@@Identity)

RETURN


Maybe not the most elegant t-sql – but it works. Another option could be to use a column expression to form the SID value....

Passwords, Hashes and Salts

Obviously we don’t want to store the cleartext passwords of our users. We use a salted hash instead. The password hash is formed through : hash(salt, password) by using PKCS#5 which is exposed in the .net framework in the PasswordDeriveBytes class. The salt is a random number generated by RNGCryptoServiceProvider (a cryptographically strong random number generator).

private byte[] generateSalt(int length)
{
  byte[] salt = new byte[length];
  new RNGCryptoServiceProvider().GetBytes(salt);

  return salt;
}

private string generateHash(string password, byte[] salt, int iterations)
{
  PasswordDeriveBytes p = new PasswordDeriveBytes(password, salt, "SHA1", iterations);
  return Convert.ToBase64String(p.GetBytes(16));
}

in part 2 i will show how to interact with the AzMan store.


Work in Progress
Monday, May 03, 2004 9:03:39 PM UTC  #   

AzMan and non-Windows Accounts

One question at the AzMan talk was about how to use AzMan with non-Windows accounts, e.g. with applications that roll their own user management (like Web Applications, SQL Server type user stores) or alternate authentication protocols like RSA SecureID.

What’s pretty cool about AzMan is that you don’t have to necessarily map your roles to windows accounts.

You can stick three different identity types into the AzMan access check functions.

1. Tokens
2. Usernames
3. SIDs

Number 1 clearly maps to Windows Accounts, number 2 maps to Windows Usernames (DOMAIN\USER Format) or results of LDAP queries.

Number 3 can be a SID of a Windows User account or just any SID you store in the AzMan policy store. SIDs don’t get verified against AD or the SAM when adding them to the store or doing access checks.

This feature is very powerful as you can design your own SID structure and map these to your application managed user accounts and – voila – you can use the powerful authorization API within your applications.

When having to integrate other authentication protocols, the new protocol transition feature of Kerberos in Windows 2003 server comes in handy. An application or a gateway could request (after authenticating the user) an S4USelf ticket. This ticket contains a Token which then can be used to feed AzMan.

I’ve written a proof of concept program for the Custom SID scenario. I will post some code in the next days.

more on S4U Kerberos Extensions here.


Work in Progress
Sunday, May 02, 2004 8:13:29 PM UTC  #   

IIR Windows Forum - Microsoft Authorization Manager

I gave a talk about Microsoft Authorization Manager at the IIR Windows Forum in Frankfurt. I was pretty suprised about how many people came to this session (even some more than to the iis 6 security talk directly before ;)

There were also some good questions about intregrating other directory services than ad, combining azMan with other authentication systems like SecureID, mobile scenarios and so on.

the slides and a demo azMan Store can be downloaded (german) here.
An excellent article about AzMan by Keith Brown can be found here.
Technet info about Azman : here.

more to come....


Work in Progress
Sunday, May 02, 2004 1:42:33 PM UTC  #