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:etcsource1.1AzManPrincipalTestStore.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 DomainUsername 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.
