I have an issue to do with roles in mvc 3 vb.net app..Say I have Admin, Developer, PowerAdmin roles.. if I want to restrict view options based on roles I have been using a if statement in the view to hide the link all together such as:
#If HttpContext.Current.User.IsInRole("Admin") And Request.IsAuthenticated Then
#<li>Administrative Tools</li>
End If
I am also decorating controller actions with authorize in places. The Problem is this say I have several actions that should only be available to say a user who is in all three roles or even 2 of the roles in any combination.. Would I simply nest the if statements in the view to hide those view items? What about controller functions.. Is it possible to decorate controller functions with something like
<Authorize(Roles:="Admin" + "PowerAdmin")>
and then have that function only accessible by someone with both roles????
simple write two separate lines :
<Authorize(Roles := "Admin")> _
<Authorize(Roles := "PowerAdmin")> _
Try googling on Enum; it's the perfect class for these kind of things.
Hope this will get you going on the right track.
Related
I have been reading and searching for a best practice for doing this.
I am "learning" about Web ASP .NET MVC and also Web Api 2.2.
I am in the point of Authentication and Authorization, I clearly understand the meanning and difference in one and another. My problem come with Authorization, I already know allow/deny access using Filter and use Roles.
But beside that I dont know where to implement the logic for authorize to some user to do some action, or to see some data, for example:
A user is Authenticated already and have the role Pilot
This user enter to a controller/action for example flight/getPassengers/1
Where getPassengers is an action to retreive all the passengers for the flight #1
Let's imagine that the current logged user on the role Pilot wants to view the list of that flight because He is allowed to, but he can't see the passengers of all flights, for example flight/passengers/3 the flight #3 is from another user Pilot.
Where is the best place to put this validation logic?
Inside the action: getPassengers? I don't think so, because if later in this controller (flight) we need validate if the same info belongs to the current user (pilot) we would have to repeat that piece of code (DRY)
So, maybe a Custom Filter?
I find an article (here) but I am not Sure if is in there and How gets implementated. I have an Implementation, something like this:
Public Class CustomFilter
Inherits ActionFilterAttribute
Implements IActionFilter
Public Overrides Sub OnActionExecuting(filterContext As ActionExecutingContext)
MyBase.OnActionExecuting(filterContext)
End Sub
Public Overrides Sub OnActionExecuted(filterContext As ActionExecutedContext)
MyBase.OnActionExecuted(filterContext)
End Sub
End Class
Is creating this type of Filters and after that using this on Controllers/Actions the correct way to achieve this?
Or how is this type of logic handled?
Thanks for your suggestions
You should implement a custom AuthorizeAttribute where you can encapsulate this logic. Just be careful in the way you implement them, try not to have several Authorize Filters. It could impact the perfomance of your application. Design a good one that can be used widely.
I need the ability to restrict what users can do in my application based on dynamic roles for CRUD.
For example the User/Index would need an authentication such as [ClaimsAuthorize("View", "User")] as oposed to [Authorise(Roles="Administrator")] so that I can check if the user has the security to view.
I have the user roles configured, but what the roles enable users to do is dynamic. An administrator can change the security levels with check boxes that will enable different security groups to do different things.
The main problem is doing this in Razor, I need something similar to #User.CanEditUsers, but I am not sure how I can go about doing this at all.
Any help would be greatly appreciated as I am having trouble finding the correct way to go about this.
Note that Authorizing users to see specific page elements differs from Authorizing for CRUD or other database operations, unless the elements point to operational Actions in Controller. Consider that you may have some elements that there's no need to be saw by a specific user, and don't have specific database operation. Till now we conclude that we need the following permissions :
Permission to See
Permission to Command
I believe that you can use Microsoft Role Provider for both parts. According to MSDN Documentation Considering that :
The Authorize attribute lets you indicate that authorization is
restricted to predefined roles or to individual users. This gives you
a high degree of control over who is authorized to view any page on
the site.
In The next step/question is how to do that?
I think 3 ways are available to meet our purpose:
Solution 1: Creating separate Views with specific page elements due to forwarding each user to related View. In this scenario we must
create separate controller actions too. we have to check user types
before each action like [Authorise(Roles="Administrator")]. We
forced to have static (Pre-defined) Roles and Accessibility. And in
one sentence Not a good solution because of redundancy and
instability.
Solution 2: Creating pages Dynamically simply by adding some if conditions for each access restricted element in One Page(for
example Edit Page). That is like employing #if
(User.IsInRole("Admin")) to authorize specific users and show
related page elements like buttons. In Controller side we can use
if conditions (not as FilterAttribute due to add dynamic
functionality based on generated/added new roles) and control valid
transactions against database. Although FilterAttributes add some great functionalists (like performance optimization). In one sentence A moderate solution.
Solution 3: Act like solution 2, just fix Controller problem by
creating our own custom FilterAttribute for authorization. That will
inherited from AuthorizeAttribute and overrides the OnAuthorize
method to do what you need only for Operations.
For Example :
public class TableAuthorizeAttribute : AuthorizeAttribute
{
public enum TableAction
{
Read,
Create,
Update,
Delete
}
public TableAction Action { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
//do custom authorizization using Action and getting TableEntryID
//from filterContext.HttpContext.Request.QueryString or
//filterContext.HttpContext.Request.Form
}
}
And its usage will be like this :
[TableAuthorize(Action=TableAuthorizeAttribute.TableAction.Update)]
Here is complete example about above concept. Here is complete example for creating dynamic AuthorizeAttribute for authorizing new roles added to application.
Solution 3 in one sentence A perfect but Complex Solution.
Note that by using FilterAttribute before Actions we have limited our application to static/predefined roles. No need to use another Data Structure or generate tables in Database.
You need to separate the concept of roles from groups in your design.
A role gives fixed permissions to perform certain actions in your application. A group is a set of users. What your administrator is really doing is to assign groups of users to different roles.
Your authorization code should be able to rely on fixed roles, e.g. an "ViewUserInfo" role. Then implement the administration interface so that when the admin enables a user to view userinfo, you add that user to the "ViewUserInfo" role.
The same goes with groups: If an entire user group is granted the right to view user info you should add that group to the "ViewUserInfo" role. To introduce the concept of groups and be able to add groups to roles you can't rely on the standard SimpleRoleProvider, so you probably have to implement your own role provider as well as a group provider.
In the end some workaround might be easier, but this is, in my opinion a cleaner architecture.
From the horse's mouth: "Role management helps you manage authorization, which enables you to specify the resources that users in your application are allowed to access. Role management lets you treat groups of users as a unit by assigning users to roles such as manager, sales, member, and so on." (ref: http://msdn.microsoft.com/en-us/library/5k850zwb%28v=vs.100%29.aspx)
Users can be in multiple roles, and you can leverage action filters to get fine-grained control of access to the various resources in your site:
[Authorize(Roles="Contributor, Designer, Reviewer")]
I think the "dynamic" aspect you are after revolves around Administrators being able to add and remove users on-demand from the roles which provide access to those resources, which is pretty typical.
The idea of constantly changing the permissions your roles grant would be a bad design choice.
I'm new to symfony2 & I'm writing an application that requires to have 2 different user types.
one is normal user & the other is the one which has same fields as user plus some other extra fields.
we design it with foreign key & one-to-one relationship.
Now I don't understand how to build two different registration forms with the functionality of FOSUserBundle.i mean i don't know how to override RegistrationController for this purpose
thanks for your answer :)
I would recommend using the PugxMultiUserBundle. I think that is exactly what you are after, I have been using it for one of my projects and it works like a charm!
You can use RollerworksMultiUserBundle:
https://github.com/rollerworks/RollerworksMultiUserBundle
We know that authorization's stuff is a cross cutting concern, and we do anything we could to avoid merge business logic in our views.
But I still not find an elegant way to filter UI components (e.g. widgets, form elements, tables, etc) using the current user roles without contaminate the view with business logic. same applies for model binding.
Example
Form: Product Creation
Fields:
Name
Price
Discount
Roles:
Role Administrator
Is allowed to see and modify the Name field
Is allowed to see and modify the Price field
Is allowed to see and modify the Discount
Role Administrator assistant
Is allowed to see and modify the Name
Is allowed to see and modify the Price
Fields shown in each role are different, also model binding needs to ignore the discount field for 'Administrator assistant' role.
How would you do it?
On way I could think to do this is create your own versions of the input extension methods. For example instead of TextBox you could create TextBoxRoles and define it like this:
public static MvcHtmlString TextBoxRoles(
this HtmlHelper htmlHelper,
string name,
string RolesEdit,
string RolesView
)
Then in code it would look like this:
<%= Html.TextBoxRoles("Price", "Administrator","Administrator,Assistant") %>
Then your implementation of TextBoxRoles would check the roles of the current user via User.IsInRole() to determine what should appear on the page.
Of course you would have to do this for every input extension method you use.
Since you already have both the current user and access to the authorization provider in your controllers this is an ideal responsibility for them. Using a naive implementation you might pass a collection of widgets to your view after you filtered which widgets the current user has access to. In the case of your form field, things might get hairy when you consider client side validation.
The binding part would be the most straight forward of all, having a custom binder for these special cases will do the trick specially well since it will have access to the controller context and you can grab the current user from there and bind the values according to your role definitions.
What about something like LinFu, an AOP framework? If it's crosscutting, then declare it is so and treat it as such.
I'm looking for some advice on storing views in a data-store (database, file, other) and display them based on routing data, all using ASP.NET MVC 2 and ASP.NET Routing.
For example, I'd like to be able to display different views based on the following route data:
/{country}/
/{country}/{area}
But in the same vein I'd like to display:
/{planet}/
/{planet}/{satellite}
All are based on strings, and the data isn't fixed. So based on the number of segments maybe, use that as the selection criteria into the data-store...additionally, I may not know the segments up front, so they'd all be dynamic.
I'm was hoping we could get a few different methods together here, as kind of a reference for all - I'm sure some methods won't suite everyone...
So, how would you do it?
Branislav Abadjimarinov suggested a Controller Factory which could be used to do the look-up and display the page dynamically. I like this idea, what do you think?
There is no way for MVC to understand from this url's which route to choose. You have to make the routes more specific. For example:
/planet/{planet}/{satelite}
/country/{country}/{area}
You also have the option to define your own controller factory. The controller factory decides which controller to instantiate based on the route. So you can put some custom logic in it like - check if the {planet} parameter exist and if yes instantiate Planet controller else instantiate Countries controller.
This Post could be really helpful for you.
Remember you always can add a new routing rule : )
Just like this