The Problem
If you’ve written much ASP.NET code since 2005, you’ve probably used the built-in role provider, or rolled your own, and written code that checks whether the current user belongs to a particular role. For instance, for an article site like ASPAlliance.com, you might choose to show an Edit link to editors with some code like this:
|
|
Of course, it might also be true that authors should be able to edit their own articles, too.
|
|
Oh, but we don’t want authors to be able to edit content once it’s been published, only while it’s still in draft or submitted status.
|
|
Now of course, this link goes to some page like EditArticle.aspx, and that page is going to also need to ensure that only authorized users can access it. Otherwise, even though the Edit link might not be visible to unauthorized users on the article page, a clever user might construct the link on their own and still gain access to the edit page. So in your Page_Load or similar you would end up doing another big ugly if check to see if the current user is authorized to edit the article. And at this point the code is extremely ugly and already starting to duplicate itself in your system - it’s starting to smell. The Don’t Repeat Yourself principle bears following, and you can combat repetition in your logic with abstraction.
The Solution
Represent the notion of access to a particular operation as a Privilege. For example, in this case we want to be able to say whether the current user is authorized to edit a particular article. That’s all that’s involved here. So we need an abstraction that allows us to refer to a user, an article, and a place to store the logic to say whether or not the operation is authorized. Something like this:
|
|
Now within our page, if we want to determine whether the user is authorized to edit the article, we simply create a new privilege object and check its AuthorizedToEdit() method. This could easily be made into an extension method on User, Article, or both, if desired for convenience.
|
|
Conclusion
You can read more about this approach and download sample code from my related blog post on this subject, Favor Privileges over Role Checks. You can follow me on BlueSky or subscribe to my blog feed to be notified about additional articles and discussions on related topics.
Originally published on ASPAlliance.com