Authorize one action in the controller, but without requiring a role

I have a Product Controller, the required role is "product_editor" to access most methods. There are several actions that do not require authorization, so [AllowAnonymous] works great. However, I have one action that I would like to require for them to be logged in, but they cannot be the product editor.

Is there an easy way to declare this for a single action?

you can see a couple of my attempts commented

[Authorize(Roles = "product_editor")] public class ProductController : Controller { #region Public Actions [AllowAnonymous] public ActionResult Search(string keyword... [AllowAnonymous] public ActionResult Details(string id... #endregion //[Authorize] //[Authorize(Roles="")] public ActionResult AuthorizedDownload(long id, string step) { SecureDownloadLink link = SecureDownloadLink.Load(id); if(link.belongsTo(HttpContext.Current.User.Identity.Name)) { //Allow download } else { //Return 404 Error } } } 

- Edit -

Found a working solution, but he would love an attribute-based solution, since the rest of my authentication is done in attributes, and the [AllowAnonymous] parameter is a bit misleading.

 [AllowAnonymous] public ActionResult AuthorizedDownload(long id, string step) { if (!User.Identity.IsAuthenticated) return RedirectToAction("Login", "Account", new { ReturnUrl = Request.Url.LocalPath }); .... } 
+4
source share
2 answers

I don't think there is an easy way to achieve this, except by explicitly pointing the Authorize attribute explicitly to each controller action:

 public class ProductController : Controller { #region Public Actions [AllowAnonymous] public ActionResult Search(string keyword... [AllowAnonymous] public ActionResult Details(string id... #endregion [Authorize] public ActionResult AuthorizedDownload(long id, string step) { SecureDownloadLink link = SecureDownloadLink.Load(id); if(link.belongsTo(HttpContext.Current.User.Identity.Name)) { //Allow download } else { //Return 404 Error } } [Authorize(Roles = "product_editor")] public ActionResult SomeOtherAction() { ... } } 

or if you have many actions, another possibility is to move the action, which is different in a separate controller.

+4
source

Authorization uses cascading rules, so you somewhat simplify it this way.

 [Authorize] public class ProductController : Controller { #region Public Actions [AllowAnonymous] public ActionResult Search(string keyword... [AllowAnonymous] public ActionResult Details(string id... #endregion public ActionResult AuthorizedDownload(long id, string step) { SecureDownloadLink link = SecureDownloadLink.Load(id); if(link.belongsTo(HttpContext.Current.User.Identity.Name)) { //Allow download } else { //Return 404 Error } } [Authorize(Roles = "product_editor")] public ActionResult SomeOtherAction() { ... } } 
0
source

Source: https://habr.com/ru/post/1490733/


All Articles