I'm implementing claims based security in my .net 4.5 application. Lots of hoops to jump through, but it is basically working.
The only part I don't like is that I can't create my own attributes. ClaimsPrincipalPermissionAttribute is sealed. Why?
I'm always marking throughout my application such as:
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Foo", Operation = "Bar")]
And since I want my resource and operation strings to not get misspelled and be easily refactorable, I have created classes so I can do this:
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = Resources.Foo, Operation = Operations.Foo.Bar)]
(Note that since different resources may have different operations, the operations themselves are subclassed by resource.)
This all works fine and dandy, but it's a hell of a lot to type or copy/paste every time. I'd rather do something like:
[DemandPermission(Resources.Foo, Operations.Foo.Bar)]
I could create this attribute, but I would need to inherit from ClaimsPrincipalPermissionAttribute, which I can't because it's sealed. :(
Is there some other way to approach this? Perhaps I don't need to inherit, but can I register my own attribute type somehow so it works in all the same places?
ClaimsPrincipalPermissionAttribute is sealed. Why?
Eric Lippert talked about the commonness of sealed in Framework types, and since we are talking about code security, this bit is very important:
Every time you implement a method which takes an instance of an unsealed type, you MUST write that method to be robust in the face of potentially hostile instances of that type. You cannot rely upon any invariants which you know to be true of YOUR implementations, because some hostile web page might subclass your implementation, override the virtual methods to do stuff that messes up your logic, and passes it in. Every time I seal a class, I can write methods that use that class with the confidence that I know what that class does.
This is even more important in this case, ClaimsPrincipalPermissionAttribute
is checked via IClaimsPrincipal
an interface. So by making ClaimsPrincipalPermissionAttribute
sealed, they allow any implementer of IClaimsPrincipal
to not have to worry about hostile implementations. This is quite a savings, given this is all security related.