I have a custom Principal/Identity for my ASP.NET MVC4 web app. I have also created a AuthorizeAttribute to instantiate my custom principal, assigning it to httpContext.User in controllers where I require Authentication.
This works great for controller/actions that have been decorated with my AuthorizeAttribute, however, for controllers that don't require authentication (but still use it if it is there), I would like to get my CustomPrincipal (and preferably through HttpContext.User).
In these non-decorated controller/actions, HttpContext.User is set, but with a GenericPrincipal rather than with my CustomPrincipal. Where would the best place to 'override' the default setting of a HttpContext.User to the GenericPrincipal?
As well, if this is done in every request that has an auth cookie, how would I then avoid doing the work twice in the case of a AuthorizeAttribute decorated controller (which would then just become one that mandated authentication).
Just to be clear, my site allows anonymous users access, but on those pages, if one is authenticated (and a CustomPrincipal is realized), there are extra features provided.
I think some of the options are (not certain of my logic behind each one):
- use a session (and handle logic to create what i need here, forgetting about Principals)
- Application_AuthenticateRequest - seen comments around the web that this is old school
- Custom filters set on a base controller
- Create an AuthorizationAttribute on the base controller that lets everyone through and sets up the HttpContext.User as I want it
- IHttpModule - this seems like a descent way (and heading down this path unless others disagree).
Thoughts?
Overridding Principal in:
Instead of
In Global.asax.cs worked for me in an ASP web application
You could use a global action filter. Let's suppose that you have a custom principal:
then you could write a global authorization action filter (but which doesn't derive from the base
AuthorizeAttribute
to avoid global authentication, it just implements theIAuthorizationFilter
interface to ensure that it runs before any other filters):The global filter will be registered in
~/App_Start/FilterConfig.cs
so that it is guaranteed that it will apply to all actions:And now you could have a custom authorization attribute which will be applied only to certain controller actions that require authentication:
and then you could have 2 types of actions: