I have an ASP.NET MVC web app which is utilizing claims-based authorization via WIF and Thinktecture.IdentityModel
. However, rather than just intercepting the unauthorized request, I'd like to trim my navigation menus to only display the links accessible to the current user.
My initial thoughts are to accept a list of actions (ActionResult, ActionLink, route value dictionary, not quite sure yet) and execute my custom ClaimsAuthorizationManger.CheckAccess
routine. In order to do this, I need to generate an AuthorizationContext, however, I'm not sure if the framework utilities (or preferably abstractions) creating the context are accessible. Anyone know if this possible? Or, if I'm going about this all wrong, what do you suggest?
Thanks and happy holidays!
As indicated by Dominick Baier, I was able to create a nice solution using
Thinktecture.IdentityModel
. I've posted the code in a Gist. This specific functionality seems to be undocumented but I was able to piece together little bits and pieces from related blog posts and documentation. I'd appreciate any feedback as I'm sure there is some corner of IdentityModel or WIF that could alleviate come of my code. That said, this is working well as is. Let's start with an example usage:Razor
As depicted below, the
BuildNavigation
helper function will render a<ul>
containing all the navigation items for which the user is authorized to view. In case you're wondering about theMVC.{Area}.{Controller}.{Action}()
statements, those are T4MVC helpers. It is not necessary to use T4MVC. TheNavigationItem
provides an override accepting anActionResult
for convenience. In actuality, theNavigationItem
only consists of astring
to display and aRouteValueDictionary
(see the Gist).HTML Helper Extensions
In order to utilize the existing authorization utilities provided by Thinktecture.IdentityModel, you have to create a
RequestContext
. Notice we build theRouteData
from theRouteValueDictionary
and then create a newRequestContext
for the authorization helper. Once important side note: if you're making use of Areas in your MVC project, as I am, theAddNamespaceInfo
function is paramount. If you have duplicated controller names in separate areas, this is how the controller factory will know how to access the correct one. Otherwise, you'll receive an exception.Thinktecture.IdentityModel ClaimsAuthorizeAttribute Wrapper
Another stumbling block I encountered was the closed nature of the
ClaimsAuthorizeAttribute
. This is one area that I suspect may be eliminated by a deeper understanding of WIF. However, for the time, I've created a wrapper around theClaimsAuthorizeAttribute
which allows me to convert the attribute into claims.Claims Authorization Helper
Finally, here is the
ClaimsAuthorizationHelper
which is responsible for resolving the necessary controller and action method, retrieving the resource claims, and calling into theClaimsAuthorization
utility provided by Thinktecture IdentityModel.Other Code
There are some other helpers and classes which have been omitted for brevity. Please see the Gist for the full code.