I added custom authorize attribute to class to check if the logged in user is admin. But that is not working. Here is my code
[AdminAuthorization]
public class UsersController : Controller
{
public ActionResult Index()
{
return View();
}
}
public sealed class AdminAuthorizationAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if(!UserSessionHelper.Instance.IsValid && !UserSessionHelper.Instance.Data.IsAdmin)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
}
}
}
What am doing here in taking user data from session to check if the user is admin and if he is not admin then redirecting to access denied page. But this is not working. For every user the page is getting viewed.
Try this, As per my understanding you need to override OnAuthorization function.
Change you AdminAuthorizationAttribute class
public sealed class AdminAuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
//Called when a process requests authorization.
if (!UserSessionHelper.Instance.IsValid && !UserSessionHelper.Instance.Data.IsAdmin)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
return;
}
base.OnAuthorization(filterContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//Processes HTTP requests that fail authorization.
}
}
Related
I want to create an attribute based on the authorize attribute that instead of granting a role access to an IActionResult it denies access.
I want to decorate the ActionResult with something like [Deny(Role="role")] so that if the role tries to access this it is redirected back to the refering url.
I have tried to modify the code below but a lot of the methods used do not exist in .netcore 5.0:
public class DenyAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return !base.AuthorizeCore(httpContext);
}
}
Or
public class DenyByControllerActionAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var controller = httpContext.Request.RequestContext.RouteData.GetRequiredString("controller");
var action = httpContext.Request.RequestContext.RouteData.GetRequiredString("action");
var denyRole = string.Format("Deny{0}:{1}", controller, action);
return !httpContext.User.IsInRole(denyRole) && base.AuthorizeCore(httpContext);
}
}
How would go about creating something like the above code examples in .netcore 5.0 since the AuthorizeCore override no longer exist in .net 5.0?
In ASP.NET Core, you need implements Attribute and IAuthorizationFilter to custom authorize attribute:
public class DenyAttribute : Attribute, IAuthorizationFilter
{
public string? Roles { get; set; }
public void OnAuthorization(AuthorizationFilterContext context)
{
var originalUrl = context.HttpContext.Request.Headers["Referer"].ToString();
var userInRole = context.HttpContext.User.IsInRole(Roles);
if(userInRole)
{
context.Result = new RedirectResult(originalUrl);
}
}
}
Controller:
[Deny(Roles = "yourRole")]
public IActionResult Test()
{
return View();
}
I am creating an custom action filter in which I am trying to check if there is a key ‘Authorization’ in the request header or not. If it is there, whether it contains a value ‘Bearer’ or not.
I tried something like this::
public class CustomAuthFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string data;
var x=filterContext.HttpContext.Request.Headers.TryGetValue("Authorization",out data);
//what to do here
}
}
How do I do this?
To cover up your simple scenario you can do something like this:
public class CustomAuthFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
bool result = filterContext.HttpContext.Request.Headers.TryGetValue("Authorization", out var token);
if (!result)
{
filterContext.Result = new UnauthorizedObjectResult("Missing authorization header");
return;
}
if (!token.Contains("Bearer "))
{
filterContext.Result = new UnauthorizedObjectResult("Invalid bearer token");
return;
}
}
}
Is there an equivalent to Request.IsAuthenticated in ASP.NET 5 hidden somewhere or are we expected to loop through the user's identities and determine this ourselves?
If you just need to know if the User object is authenticated, this property should do the trick:
User.Identity.IsAuthenticated
If you need to prevent an action from being called by an unauthenticated user, the following attribute class works great.
public class BasicAuthAttribute : ActionFilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
var user = filterContext.HttpContext.User;
if (user == null || !user.Identity.IsAuthenticated)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
I use this in my base controller class as follows.
[BasicAuth]
public abstract class BaseAuthorizedController : Controller
You can also access the IsAuthenticated property from within your service layer by injecting an IHttpContextAccessor into it, like this:
public class MyService : IMyService {
private readonly IHttpContextAccessor httpContextAccesor;
public MyService(IHttpContextAccessor httpContextAccessor) {
this.httpContextAccessor = httpContextAccessor;
}
public void MyMethod() {
var isAuthenticated = this.httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
if (isAuthenticated) {
// Authenticated, do something!
}
}
}
Thanks for looking.
This is a trivial task when using a normal (not WebAPI) action filter as I can just alter the filterContext.Result property like so:
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary { { "controller", "Home" }, {"action", "Index" } });
Unfortunately, I have to use HttpActionContext for WebAPI, so I can not access filterContext.Result.
So what should I do in place of that? I have the filter set up and it does execute at the appropriate time, I just don't know how to make it prevent execution of the requested service endpoint and instead point to a different one.
Here is my controller:
[VerifyToken]
public class ProductController : ApiController
{
#region Public
public List<DAL.Product.CategoryModel> ProductCategories(GenericTokenModel req)
{
return HelperMethods.Cacheable(BLL.Product.GetProductCategories, "AllCategories");
}
public string Error() //This is the endpoint I would like to reach from the filter!
{
return "Not Authorized";
}
#endregion Public
#region Models
public class GenericTokenModel
{
public string Token { get; set; }
}
#endregion Models
}
Here is my filter:
using System.Web.Http.Controllers;
using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute;
namespace Web.Filters
{
public class VerifyTokenAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext filterContext)
{
dynamic test = filterContext.ActionArguments["req"];
if (test.Token != "foo")
{
//How do I redirect from here??
}
base.OnActionExecuting(filterContext);
}
}
}
Any help is appreciated.
The answer in my case was simply to change the Response property of the filterContext rather than to redirect to a different endpoint. This achieved the desired result.
Here is the revised filter:
public class VerifyTokenAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext filterContext)
{
dynamic test = filterContext.ActionArguments["req"];
if (test.Token != "foo")
{
filterContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
base.OnActionExecuting(filterContext);
}
}
I want to implement a redirect unauthorized user with a check in the proper attribute. To do this I create a class attribute with a constructor with no parameters.
[AttributeUsage(AttributeTargets.Method)]
public class LoggedAttribute:Attribute
{
public LoggedAttribute()
{
//TODO
}
}
Now assign this attribute to all methods of action that requires authorization.
[Logged]
public ViewResult SendMessage()
{
return View();
}
I have a User model with boolean flag IsLoggedIn. How can I check this flag in the class attribute to redirect the user to the authentication page in case of an emitted flag ?
In the case of using a custom authorization attribute like below:
public class AuthorizeUserAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
//anything else you'd like to do like log it
return false;
}
}
}
and then you can redirect them by the following override:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//disable the redirect
if(disabled)
{
//do something else
}else{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new
{
controller = "Account",
action = "Login"
})
);
}
}
UPDATE: and you use it like this:
[AuthorizeUser]
public ActionResult myAction()
{
return View();
}