How can I make every controller except the account controller in my WebAPI application require a user to be authenticated - asp.net

I realize that I can decorate each controller with [Authorize].
However is there a way that I can do this globally so that it's the default and then have the Account controller set as anonymous only ?

Create a BaseController which all other controllers inherit from. Have this class then inherit from Controller, like so
SomeController : BaseController
Then in BaseController
BaseController : Controller
Add an authorize attribute to the base controller. All controllers inheriting from BaseController will now require authorization. Controllers which don't, wont. So, your account controller will only inherit from Controller, not BaseController as you don't want this authorized.
There are other advantages of having a base controller. You can override OnAction executed to log application usage for instance.
I would create a second base controller called BaseUnsecuredController which your account controller can inherit from which won't have an authorize attrubute. Then have an abstract base controller class which contains the implementations of common actions you wish to share between the base controllers, like logging and error handling.
Hope this helps.

Use a basecontroller, from which each controller inherits. Then set the [Authorize] attribute on the base controller.

Apply the filter globally like this.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Existing code
config.Filters.Add(new System.Web.Http.AuthorizeAttribute());
}
}
Then, apply [AllowAnonymous] on the AccountController or specific action methods.
[AllowAnonymous]
public class AccountController : WebApiController {}

You can add the AuthorizeAttribute globally by changing your FilterConfig to add it to all requests:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//Other filters
filters.Add(new AuthorizeAttribute());
}
After that you can add the [OverrideAuthorization] attribute to your controller.
If you have any AuthenticationFilter set globally it won't be reseted. If you want to reset both you also need to use the [OverrideAuthentication] attribute.

Related

How to register custom IExceptionFilter implementation with AutoFac

ASP.NET MVC 5
Custom Global Error Handler
How to register a custom global exception attribute with AutoFac IoC Container?
public class ExceptionLoggingFilter : FilterAttribute, IExceptionFilter
{
private IRepo _repo;
public ExceptionLoggingFilter(IRepo repo)
{
this._repo = repo;
}
}
Follow the pattern outlined for other action filter types as noted in the documentation. There are extension methods for all the filter types.
builder.RegisterFilterProvider();
builder.RegisterType<ExceptionLoggingFilter>()
.AsExceptionFilterFor<MyController>();
Alternatively, use attributes with property injection and just register the filter provider.

asp.net help page does not show right routes

I am using attribute routes to route actions in controllers, but asp.net generate wrong Help Page
[HttpGet]
[Route("getAll")]
[AllowAnonymous]
public IHttpActionResult GetCategories(){...}
But the result is
Set up your config to use attribute routing.
public static class WebApiConfig
{
public static void Configure(HttpConfiguration configuration)
{
//the following config sets up your routing mechanism to use attributes
configuration.MapHttpAttributeRoutes();
}
}

How can I override ChildActionOnly attribute set on controller class for a particular method?

I have ChildActionOnly set on the class of a controller called 'NavController'. I'd like one of the methods to be exposed and not be restricted by the ChildActionOnly attribute. How can I do that?
Here's a glimpse of the controller:
[ChildActionOnly]
public class NavController : Controller
{
[NotChildActionOnly] //does something like this exist natively in asp.net Mvc?
public ActionResult GetSomething()
{
return View()
}
}
If the 'NotChildActionOnly' attribute doesn't exist natively then I'll go down the path of writing a custom action filter such as 'OverridableChildActionOnly(enable/disable)' but I wanted to make sure I wasn't reinventing the wheel.

ASP.NET ActionFilters and inheritance

All my controllers inherit from a BaseController that has an ActionFilter attribute:
[AnalyticsData]
public class BaseController : Controller {}
public class AccountController : BaseController {}
Some of my Actions in my controllers reuse the AnalyticsData ActionFilter:
public class AccountController : BaseController
{
[AnalyticsData(Page="AccountProfile")]
public ActionResult Profile()
{
// return View
}
}
I notice that the AnalyticsData ActionFilter only runs once. This is a good thing and I only want it to run once, but I'm wondering how that happens. If I set my breakpoint inside the OnActionExecuting:
public class AnalyticsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// break point set here
}
}
...it only gets hit once when AccountController serves it Profile view.
How do ActionFilters and/or Attributes work that [AnalyticsData(Page="AccountProfile")] on the Action overrides/replaces [AnalyticsData] on BaseController?
The short answer is that the ASP.NET MVC framework code that retrievs the list of filters for each action removes duplicates (action filters of the same type) in such a way that it prefers actionfilters defined on the action method over ones defined on the controller (or its base class). In MVC 2 this logic is performed in a few internal methods in the ActionDescriptor class

Parent Controller Class in ASP.NET MVC 2

I've been working on a rather large web application that requires a specific id param in the url for every page visited (for example, /controller/action/id?AccountId=23235325). This id has to be verified every time someone visits a page.
I want to reduce code replication as much as possible, and was wondering if there is a way to use an init method or constructor in a controller that inherits the MVC controller, and then have that controller extended by the others.
I'm using ASP.NET MVC 2.
Yes this is possible using either a base controller class that all your controllers inherit or by creating a custom attribute that you decorate your controller with.
Base controller:
public class BaseController : Controller
{
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
// verify logic here
}
}
Your controllers:
public class AccountController : BaseController
{
// the Initialize() function will get called for every request
// thus running the verify logic
}
Custom Authorization Attribute:
public class AuthorizeAccountNumberAttribute : AuthorizationAttribute
{
protected override AuthorizationResult IsAuthorized(System.Security.Principal.IPrincipal principal, AuthorizationContext authorizationContext)
{
// verify logic here
}
}
On your controller(s):
[AuthorizeAccountNumber]
public class AccountController : Controller
{
// the IsAuthorized() function in the AuthorizeAccountNumber will
// get called for every request and thus the verify logic
}
You can combine both approaches to have another custom base controller class which is decorated with the [AuthorizeAccountNumber] which your controllers that require verification inherit from.

Resources