public class CustomAuthorizeAttribute : AuthorizationFilterAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return true;// if my current user is authorised
}
}
Above is my CustomAuthorizeAttribute Class
and
[CustomAuthorize] // both [CustomAuthorize] and [CustomAuthorizeAttribute ] I tried
public class ProfileController : ApiController
{
//My Code..
}
When I'm calling
http://localhost:1142/api/Profile
It is not firing CustomAuthorizeAttribute
More over My FilterConfig class is look like below
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizeAttribute());
}
}
Please help if I miss something.
Looks like you are using an MVC filter instead of a Web API filter. It can be detected in the sample because it uses HttpContextBase. Instead use the filter from the System.Web.Http.Filters namespace.
You need to override OnAuthorization or OnAuthorizationAsync on the Web API filter.
You don't need to register a global filter and decorate your controller with it. Registering it will make it run for all controllers.
Web API filter code:
https://github.com/aspnetwebstack/aspnetwebstack/blob/master/src/System.Web.Http/Filters/AuthorizationFilterAttribute.cs
YOur custom attribute should inherit from System.Web.Http.Filters.AuthorizationFilterAttribute
and it should look like this
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
public class CustomAuthorizeAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
public override bool AllowMultiple
{
get { return false; }
}
public override void OnAuthorization(HttpActionContext actionContext)
{
//Perform your logic here
base.OnAuthorization(actionContext);
}
}
Try with this.
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
return true;
}
}
To add onto the other answers that have you inherit from System.Web.Http.Filters.AuthorizationFilterAttribute, I put this into my OnAuthorization method to make sure the user was logged in:
if (!actionContext.RequestContext.Principal.Identity.IsAuthenticated)
{
// or whatever sort you want to do to end the execution of the request
throw new HttpException(403, "Forbidden");
}
Related
I am struggeling with this peace of code:
public class MultiDatabaseAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
}
I want to execute the OnActionExecuting on certain ActionResults in my API. This is a method in my API:
[MultiDatabase]
public Website Get(int id)
{
return _websites.Get(id);
}
It does not work. Whatever I try, the method attribute is not called. According to the website http://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/ this should work.
According to this question I had to add the attribute to the Global.asax. Did not help too.
Who can help me?
Thanks
You are inheriting your attribute from the wrong base class. MVC and WebAPI have different objects (at least until ASP.Net Core has since merged them into one). Make sure you have the correct import in your attribute:
using System.Web.Http.Filters;
Or use the full namespace:
public class MultiDatabaseAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
}
}
Our application has the notion of a PermissionAttribute. This attribute is defined in a base layer of our application and our commands and queries are decorated with that attribute. Since this attribute is defined in base layer we can't (and don't want to) to let it inherit from FilterAttribute or implement System.Web.Mvc.IActionFilter on it.
Still we would like to apply this attribute to controller actions as follows:
[Permission(Permissions.Administration.ManageUsers)]
public ActionResult Index()
{
return this.View();
}
Based on this attribute the proper security checks should be applied. I've been browsing through the MVC code base to find the proper hooks to customize MVCs behavior to allow adding these security checks based on this custom attribute. I though about creating a custom ControllerActionInvoker that returned a custom ReflectedControllerDescriptor from its GetControllerDescriptor method, which would return FilterAttribute that would be created based on the existence of the PermissionAttribute, but it feels like a lot of work, and I'm not sure this is the correct path to walk.
What would be am efficient and pleasant way to customize the MVC pipeline so that we can handle this non-MVC related attribute?
I would do it this way. First create your own implementation of the AuthorizeAttribtues like this:
public class PermissionAuthoriseAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Leaving the implementation of this to you, but you check if your
//PermissionAttribute is assigned and call it's methods.
if(...)
return true;
//You may want to check this first, depending on your requirements
return base.AuthorizeCore(httpContext);
}
}
Then apply this across your project by adding this line to the FilterConfig.cs file:
filters.Add(new PermissionAuthoriseAttribute());
I ended up doing the following:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new PermissionAuthorizationFilter(
() => Global.Container.GetInstance<IUserPermissionChecker>()), 0);
filters.Add(new HandleErrorAttribute());
}
}
public sealed class PermissionAuthorizationFilter : IAuthorizationFilter
{
private readonly Func<IUserPermissionChecker> userPermissionCheckerFactory;
public PermissionAuthorizationFilter(
Func<IUserPermissionChecker> userPermissionCheckerFactory) {
this.userPermissionCheckerFactory = userPermissionCheckerFactory;
}
public void OnAuthorization(AuthorizationContext filterContext) {
var attribute = filterContext.ActionDescriptor
.GetCustomAttributes(typeof(PermissionAttribute), true)
.OfType<PermissionAttribute>()
.SingleOrDefault();
if (attribute != null) {
VerifyPermission(filterContext, attribute.PermissionId);
}
}
private static void VerifyPermission(AuthorizationContext filterContext,
Guid permissionId) {
var permissionChecker = userPermissionCheckerFactory.Invoke();
if (!permissionChecker.HasPermission(permissionId))
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
I want to call controller method in Global.asax. Code is given below.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
//here we can subscribe user to a role via Roles.AddUserToRole()
}
}
This event is in global.asax. I want to call controller method which return user permissions from database. How this is possible to call controller method here after that I will save user permissions in session and my controller constructor? Code is given below.
public class AccountController : Controller
{
private readonly ISecurityService securityService;
public AccountController(ISecurityService securityService)
{
this.securityService = securityService;
}
}
Please guide me.
You could handle this using a custom AuthorizeAttribute. This allows you to place an attribute on the top of any controllers / methods which you require authentication to be successful in order to call. This lets you override AuthorizeCore which you can then use to do any custom authorization you want to perform. You can also save any other information to session from this method.
For example:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// do your own athorization stuff here
}
}
Then you can decorate you controllers that require the use of this authorization either with your attribute:
[CustomAuthorize]
public class AccountController : Controller
{
}
Or using a base controller:
[CustomAuthorize]
public class BaseAuthController : Controller
{
}
public class AccountController : BaseAuthController
{
}
i Resolve this issue by my self i call service method in global.asax by resolving dependency issue below is the solution of the above problem.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
IUnityContainer container = GetUnityContainer();
ISecurityService securityService = container.Resolve<SecurityService>();
var list = securityService.GetUserRolesandPermissions("1");
}
}
Thank you every one.
This thing is killing me. Basically what I have is the custom ActionFilter (Class which Inherits from ActionFilterAttribute and implements IActionFilter). it looks like this
public class ValidationFilterAttribute : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
// do some stuff here
}
}
this is what FilterConfig looks like
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new ValidationFilterAttribute());
}
}
But whenever I start the project there is an exception saying following
The given filter instance must implement one or more of the following filter interfaces: IAuthorizationFilter, IActionFilter, IResultFilter, IExceptionFilter.
But obviously the ValidationFilterAttribute implements one of those interfaces. Am I missing something very basic here? I can't figure out what is wrong.
Prefix your base class with System.Web.Mvc, I have a "hunch" you may be using System.Web.Http.Filters.ActionFilterAttribute instead.
So then you would have to override
OnActionExecuting(ActionExecutingContext filterContext)
And things will be OK.
And as you can see, ActionFilterAttribute implements IActionFilter already, so you don't need to specify it.
As far as I know, you don't need the IActionFilter declaration.
ActionFilterAttribute already implements IActionFilter
But I don't know if this is the cause of the error message. Could you try removing it?
Check this also: http://forums.asp.net/t/1835666.aspx
[Serializable] public class RedirectingAction : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context) { base.OnActionExecuting(context);
}
after that use this attributes in your controller like below
[RedirectingAction]
public class HomeController : BaseController { }
custom action filter example by www.jkittraining.com
www.jkittraining.com/course/asp-net-mvc-training/
I have a custom AuthorizeAttribute like this
public class DevMode : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (myConditionToAuthorize)
{
// how to allow [Authorize] ?
}
}
}
The problem is that it is used along with [Authorize] tag like this:
[Authorize, DevMode]
public class UserController : ApiController { ... }
I need to allow [Authorize] == true inside [DevMode]
Or it is better to put them all together inside a unique authorize class? But then I dont know tho to check Authorize data.
Or it is better to put them all together inside a unique authorize class?
Oh yes, that would indeed be better. You could simply derive from the AuthorizeAttribute and call the base method:
public class DevModeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var authorize = base.IsAuthorized(actionContext);
if (!authorized)
{
// the user is not authorized, no need to go any further
return false;
}
// now apply your custom authorization logic here and return true or false
...
}
}
and then:
[DevMode]
public class UserController : ApiController { ... }
I used this to add a custom IsAdmin (based on claims) using this method
public class IsAdminAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
IPrincipal principal = actionContext.RequestContext.Principal;
return principal.IsAdmin();
}
}
it kind of answers my own last comment so hope it helps someone else please note the .IsAdmin is an extension method on the IPrincipal that checks claims.