Reputation: 886
I want to make the [MyAuthorize(Role="R1")]
attribute so that
"R1"
can be made configurable instead of hardcoding on Controller / Action
.
The usual approach of creating a [MyAuthorize(Role="R1")]
seems to be
public class MyAuthorizeAttribute : AuthorizeAttribute
{
private readonly string[] _allowedRoles;
public MyAuthorizeAttribute(params string[] roles)
{
this._allowedRoles = roles;
}
protected override bool OnAuthorization(AuthorizationContext
authorizationContext)
{
bool authorize = false;
// Compare current user's Roles with "R1" to figure out if the
// Action / Controller can be executed
return authorize;
}
}
But what if Roles like "R1"
are subject to change at any time ?
i.e., being "R1"
one day and being called "AssistantManager"
another day.
The application will have to be re-coded to handle this.
I thought of creating a custom [OnAuthorize]
attribute that reads
(Action/Controller, Role) as key value pairs
from the web.config
.
Eg:--
<add key="Controller1" value="Role1" />
<add key="Action2" value="Role2" />
and in the attribute..
protected override bool OnAuthorization(AuthorizationContext
authorizationContext)
{
bool authorize = false;
// 1. Read all key values
// 2. determine Action / Controller the user is trying to go
// 3. Compare user's roles with those for Action / Controller
return authorize;
}
I am aware of the limitations of <location .... />
in MVC
as per https://stackoverflow.com/a/11765196/807246
and I'm not suggesting that, even though I'm reading from web.config
But what if we read (..and store in session??) all the authorization related configuration when the application first loads up?
Any changes like "R1" -> "AssistantManager"
;; "R2" -> "Manager"
should just require a restart of the application, instead of having to make code changes in the controller / action.
I want to know if this is a valid approach or if there are security risks, even with this, and any better alternatives.
Upvotes: 0
Views: 786
Reputation: 48314
Ad 1. You read the setting using the configuration API, e.g. if this is the regular MVC you have ConfigurationManager.AppSettings
to peek into app settings section of the web.config
Ad 2. You don't determine anything or rather, you seem to misunderstood the linked post. What you do is you put the Authorize
over the controller (action) you want to secure and the OnAuthorization
is fired when the controller / action is executed. If you really want, you can peek into the authorization context passed as the argument, the controller and action are available in the route data.
Ad 3. This is the easiest part, the currently logged user (or an anonymous user if the user is not yet authenticated) is passed in the authorizationContext.HttpContext.User
property as the IPrincipal
so you can even call its IsInRole
method.
But what if we read (..and store in session??) all the authorization related configuration when the application first loads up
You really don't have to. Even if you read it from the configuration upon every request, the configuration is already preloaded upon every restart of the application, you don't really slow anything down much then with ConfigurationManager.AppSettings
.
Any changes like "R1" -> "AssistantManager" ;; "R2" -> "Manager" should just require a restart of the application, instead of having to make code changes in the controller / action.
If you store it in the configuration file and modifying it triggers the restart of the app pool, you don't make any changes in the code.
I want to know if this is a valid approach or if there are security risks, even with this, and any better alternatives.
There are risks, someone who can access your app server can possibly reconfigure your app. Note however, that such someone could do any other harm as well, e.g. decompile, modify, recompile and reupload your app. Or even replace it with something completely else.
As for alternatives, it's completely impossible to come up with anything better if the criteria of what's better are vague. If something is possibly better we'd have to know what better stands for.
In other, simple words, this looks fine.
Upvotes: 1