patterncsharpMinor
Feature-based authorization
Viewed 0 times
authorizationbasedfeature
Problem
Feature-based authorization
It seems to me that if you rely on roles to authorize a web application it makes it very difficult to render UI or code based on a set of features. This means that each role would have be checked against for each feature.
This seems very rigid. It is for this reason that I started to think of the application in terms of features. Roles can have features and Members can have features. Next the features have to be authorized based on the Member's current feature-set.
Members have roles
ASP.NET/MVC provides a framework to manage roles using SQL server (aspnet_regsql). We are using this out of the box and things are working fine so far.
Roles have features
In order to have more granular authorization we are attaching features to roles in a many to many reference table for features and aspnet_roles and Feature to aspnet_users tables in the same fashion.
Wrap everything in a feature when authorization is needed
Everything that needs to authorized is wrapped in a feature. Although, my heart would like to believe in a more concise method I can't fathom this would be possible.
Wrap on the server
Conditional statement for code that is only available to this feature:
Wrap on the client
Same as above but markup is wrapped up for the
Class to check authorization
The account service is called to authorize the feature for the previous conditional statements.
```
public static class Feature
{
public static Boolean Authorized(Features featur
It seems to me that if you rely on roles to authorize a web application it makes it very difficult to render UI or code based on a set of features. This means that each role would have be checked against for each feature.
if(User.IsInRole("SomeRole") || User.IsInRole("OtherRole")) { // Do something } // C#
@if(User.IsInRole("SomeRole") || User.IsInRole("OtherRole")) { // Do something } // RazorThis seems very rigid. It is for this reason that I started to think of the application in terms of features. Roles can have features and Members can have features. Next the features have to be authorized based on the Member's current feature-set.
if(SomeFeature) { // Do Something } // In C#
@if(SomeFeature) { Show Something } // In RazorMembers have roles
ASP.NET/MVC provides a framework to manage roles using SQL server (aspnet_regsql). We are using this out of the box and things are working fine so far.
Roles have features
In order to have more granular authorization we are attaching features to roles in a many to many reference table for features and aspnet_roles and Feature to aspnet_users tables in the same fashion.
Wrap everything in a feature when authorization is needed
Everything that needs to authorized is wrapped in a feature. Although, my heart would like to believe in a more concise method I can't fathom this would be possible.
Wrap on the server
Conditional statement for code that is only available to this feature:
if(Feature.Authorized(Features.SomeFeature))
{
// Code in here that processes the feature ...
}Wrap on the client
Same as above but markup is wrapped up for the
Feature:@if(Feature.Authorized(Features.SomeFeature))
{
Markup if feature exists.
});Class to check authorization
The account service is called to authorize the feature for the previous conditional statements.
```
public static class Feature
{
public static Boolean Authorized(Features featur
Solution
Couple of items that might need a re-look:
-
The now deprecated AzMan has very similar concepts. The conceptual equivalent for the 'Feature' in your application is an 'Operation' in AzMan. I'd suggest taking a look at it to understand how an application can use role based access to get the granularity that is desired.
-
A Custom Role Provider can help you achieve the same effect. You could call the
-
The advantage of using a Role Provider is that it is supported in the framework, already has a plugin model, it has a defined place in the Callback Lifecycle and can be swapped out without touching any other parts of the system.
-
Using the IOC resolver directly in usually not done as it leads to additional dependencies in Unit Testing and is not easily mockable and it also adds a hard dependency on the particular IOC framework. One alternative would be to make an extension method that can then source the dependency from the extended object (such as
-
The now deprecated AzMan has very similar concepts. The conceptual equivalent for the 'Feature' in your application is an 'Operation' in AzMan. I'd suggest taking a look at it to understand how an application can use role based access to get the granularity that is desired.
-
A Custom Role Provider can help you achieve the same effect. You could call the
User.IsInRole() method, but pass in the Feature name. In your custom role provider, you can perform the above specified IsAuthorized() logic. That allows you to support a role hierarchy where Roles in the traditional sense are made up of Operations (or Features). If a user is granted a role, it means he can also authorized for all the underlying operations (features). Ex: an 'Admin' Role who can perform 'UserAddition', 'UserModification' and 'UserArchival' features. All you'd need is an additional table in your database which stores the hierarchy and a lookup to generate the grand feature capability list. -
The advantage of using a Role Provider is that it is supported in the framework, already has a plugin model, it has a defined place in the Callback Lifecycle and can be swapped out without touching any other parts of the system.
-
Using the IOC resolver directly in usually not done as it leads to additional dependencies in Unit Testing and is not easily mockable and it also adds a hard dependency on the particular IOC framework. One alternative would be to make an extension method that can then source the dependency from the extended object (such as
Page.User).Context
StackExchange Code Review Q#54118, answer score: 3
Revisions (0)
No revisions yet.