I have created a class CustomAuthorizeAttribute:AuthorizeAttribute for authorization, but I am unable to authorize in the razor view like #if(User.IsInRole("some role"));, but what I want is #if(CustomAuthorizeAttribute(My Parameters)) for my authorization.
How to do that?
AuthorizeAttribute works by placing it on an action method, a controller, or as a global filter. It is not possible to use MVC filters inside of views (or at least not without a lot of work).
I suggest you ask a different question and narrow it to your requirements. There must be some reason why you are attempting this, but it is impossible to work out what you need to do (or if there is a much simpler approach) from your question.
Related
I use the AuthorizeAttribute and roles (Identity). I want to hide ActionLinks based on user roles. I found solutions with HtmlHelpers like this. But I really don't like those solutions because the view must know about the required roles. This means the roles are defined twice: in the controller and the view.
Does anyone know a better solution? Can I e.g. get the roles from the AuthorizeAttribute in the view or in the controller (maybe use ViewBag to transfer to view). I thougt about reflections, but this is bad when it comes to performance as the controller code is executed for every request.
The nicest solution would be without logic in the view anyway..
One possibility is to use MvcSiteMapProvider for your menu. It has a built-in security trimming feature that automatically hides links according to AuthorizeAttribute. If you don't like the built-in HTML helpers, you can customize the templates and/or build your own HTML helpers that hide links based on node accessibility.
Or, if you don't want to use a 3rd party library, you can reverse engineer the AuthorizeAttributeAclModule to make your own implementation.
Full Disclosure
I am a major contributor of MvcSiteMapProvider.
Let's say that I have an MVC view that has one set of features available to non authorized users, and an extended set of features that is available to authorized users. Currently, I have implemented this by marking up my view with
#if(User.IsInRole(...)) {...}
in several places in the view file. This wasn't a big deal when it was just 2 or 3 things that authenticated users could do beyond the non-authenticated functionality, but now I have this all over the place in a "dashboard" type of page. It seems to be getting kind of messy.
Is there a cleaner or more elegant way to implement this? I am using viewmodels. I am wondering if I should use different viewmodels/views based on role, but then using different viewmodels seems like it might be more difficult to maintain. I am not sure what the best practice is for this, and I am open to ideas.
Edit
One example of what I am doing: I have several lists/tables that allows managers to edit the record, so the code adds an extra
<td>
for the manager-allowed actions. Another use case: when the manager is signed in, an employee name is now an actionlink instead of just text.
What you could try is encapsulating each portion of the view that will be interchanged based on roles into partial views. This has worked well for me in the past, and is much cleaner when trying to troubleshoot code as opposed to seeing a bunch of #if statements in a single view.
Hmmm. I have this idea. You need list of dashboards enumerations where you have a property like RolesAllowedToAccess (string[])
On the view you can foreach by dashboards enumerations where RolesAllowedToAccess contains current user role.
After you can render partials for each of dashboards. Make sence?
I am writing an ASP.MVC application and I know you can use authorisation filters on the cotrollers to control access to the pages but I am wondering what is the best approach to do if you want to control access to protected data within partial views.
From what I have read ASP.MVC doesnt offer this level of granularity.
This seems easily enough by adding the user permissions to the model as an attribute and then using a simple factory to decide if the view should be rendered or a blank view be returned.
So far I have
RenderPartial(PartialFactory.IsAllowedToRender("partialName", Model.Security), Model)
and the Factory either returns the view requested or a blank partial view.
Has anyone tried this before or knows why no one does this (apart from the extra effort)
We have done similarly with extension methods for HtmlHelper.
RenderPartialIfExists and so on. No shame in doing this if its something you are going to need frequently.
Doing it without the extensions as you have works as well, but its not as clean to read. Also, consider adding your security information to HttpContext.Current.Items, that way you don't have to pass it into the models all the time, and anything that needs to take advantage of it, helpers, controllers, etc have easy access to it, and you only have to fetch it at the beginning of a request.
I'm building an application that among other things allows users to upload documents. I have the basic create/view actions working just fine, but i'd like to reuse this action in other places.
I want to know if anyone has a pointer for how to do this. There doesn't seem to be a very good way of doing this.
Here are a few ways i've considered:
Try to do a chain(). This doesn't work since chaining does a GET, and to upload you need a POST.
Break out the main business logic into the Grails "service", and make two actions that use the same code.
Use a JS modal window. I've been thinking a modal that contains an iframe to an "unskinned" version of the document upload. The trick here is to get the window to close when the upload is done.
Thanks
--Matthias
I don't care for the extending controller method. In fact, I avoid inheritance when possible. I'd rather put the common code in a service class and reuse it that way.
You can use a base controller class, and place the common functionality there. Then extend the base controller and call the method from other action methods.
I have been looking around but i don't see any spec for this, maybe i search a wrong keyword. But i'm here so i should ask something.. :)
I'm familiar with Authorize Attribute, but I think it only apply to Actions. What should i do if i want my whole application to authorize first before getting access to any actions?
It will be very pain to just repeat in every action to put [Authorize] tag on top of them.
Thank you very much
It is not quite correct that AuthorizeAttribute applies only to actions. It can also be applied to classes containing actions. If you have a base controller type for your application (which can be abstract, if you like), and every other controller is a subtype of that base type, then your entire application now requires authorization, with just a few characters of typing.
You should find a way to make AuthorizeAttribute work for you; this is the standard way of doing authentication in ASP.NET MVC.
No, you can mark your controller with AuthorizeAttribute like an action. Check out here.