Access to Action Methods depending on Roles in ASP.NET MVC [duplicate] - c#

This question already has answers here:
ASP.NET MVC3 Role and Permission Management -> With Runtime Permission Assignment
(4 answers)
Closed 9 years ago.
I know it is possible to annotate action methods to control access depending on roles like [Authorize(Roles = "Publisher")] but how can I achieve the same result if the access control information comes from database and can be changed anytime.
For example: Create action method can be accessed by Publisher but cannot be tomorrow because Admin disallowed Publisher to Create. This information will come from database and I have to somehow put appropriate annotation in runtime.
I hope I was able to convey my question properly. Any suggestion is appreciated.

Create action method can be accessed by Publisher but cannot be
tomorrow because Admin disallowed Publisher to Create. This
information will come from database and I have to somehow put
appropriate annotation in runtime.
I wouldn't solve the problem the way you mentioned. Changing Authorize attribute from "Publisher" to something else at runtime is not a good solution. Instead what you can do is to manage users in Publisher Role (for example remove/add users to that role at runtime). What I mean is, let Publisher Role have access to Create Action, but on the SQL side, you manage users who come under publisher role. In that way, there is no need for you to change Authorize attribute at runtime.
To maintain your roles in a SQL Database and use them, you can go for Custom Role Provider.

Related

securing an mvc application using subdomains

I have an mvc application that I allow businesses to log in using
https://storea.mydomain.com https://storeb.mydomain.com etc etc
Each of the businesses has users created and I have a table that matches business ID to EmployeeId. I am trying to lock the application down so an authenticated user of businessA cant access information from BusinessB.
Where is the best place for me to be checking the user is allowed to access the subdomain? Do I override the OnActionExecuted action checking what the subdomain is then look at a session value to see if they match, if different log them out.
Or this there a more elegant way to do this?
Suggestions and advise on best practices would be great! thank you
A custom Authorize attribute seems a good place to perform this. You could override the AuthorizeCore method where you will have access to the HttpContext and you will be able to perform the custom authorization logic based on the subdomain.
As I understand it, your MVC application uses a single database to store the information for all the businesses you have. This is why you'd be worried about Bussines A accesing Bussines B information.
So for me, your database is the place to check which information can access each user depending on the business they belong to.
I think you don't even need to use subdomains for this.
In cases like these I use the repository pattern and in every query/data access you ensure you pass in a where clause that contains the business id.
ex:
select * from orders where orderid=#orderId and companyID=#companyId
It is very important to do this on the query as you want data rules in place to prevent improper querying. Doing this on an Authorize attribute for example doesn't guarantee someone hasn't tampered with data to load another company's information.
In addition I have the http://mvcsecurity.codeplex.com/ extensions to help secure ids stored on pages to help prevent tampering.

block Invoking class method based on user role asp.net mvc 3

I'm creating my first ASP.NET MVC 3 app and I have a problem with creating class instance based on user role.
I have a Class called Account and it contains information about user accounts and few methods which allow me to manipulate(update) user account information. For example ChangeNickName, AddToGroup, RemoveFromGroup, Ban and so on.
As you can see problem with these methods is that I dont want to allow anyone to use AddToGroup or Ban method but only user with specified role (i'm using ASP.NET default role implementation system)
So I wonder is there a way I could add attribute [Authorize(Roles = "Admin")] to my AddTogroupMethod just like I use it on Controller methods
I know that with proper implementation of controllers I dont need something like this but I want to make sure that I dont allow anyone to make instance of class (or use specified methods by accident) if user is not part of specified role.
So for example if I by accident add access to AddToGroup method in user controller I would still be able to prevent them from exploiting bug because of attribute attached to this method
If I can't solve this problem with attributes is there a way to make VS to block me from debugging application if I make a call to AddToGroup method from xy class
If you have any ides how to make this working I'm open to suggestions
Than in advance
You should probably use the AuthorizeAttribute, however you can check the role of a current user in code using Roles.UserIsInRole.
There's a little info on this in MVC here (the assembly seems to have changed between 3.5/4.0):
asp.net mvc -> Roles.IsUserInRole(username,role)

ASP.NET MVC3 - Most Appropriate Way to Store IsAdmin information

In my ASP.NET MVC 3 application i have two types of users - regular users and admin users. Obviously the latter have greater privileges than the former. I have a page level authorization implementation in place, but for screen level items (show this button if admin, etc.) I would like to know what is the most appropriate solution to make a boolean IsAdmin flag available on all screens. I can think of a bunch of different methods cookies/session variables/httpcontext, but I'm wondering what is used with success in production. Any guidance is appreciated
Thanks in advance
JP
http://msdn.microsoft.com/en-us/library/system.web.httpcontext.user.aspx
HttpContext.User is of type IPrincipal, which has one method IsInRole. If you are using FormsAuthentication you'll get this for free. HttpContext.User will be available directly from any view
The ViewBag seems an easy fit.
ViewBag.UserIsAdmin = somevalue;
That's available to every view and is meant to be used for View data that isn't part of the model.
The only downside is that you need to populate it every request on views that need it, but you can actually do that in a Base controller's Initialization method if it's a global thing.
As for how to store it between requests, not cookies. Those are easily forgable. You can use a session to store it between requests, or you can simply repopulate it every request if it's a fast request (and you can't use sessions) in your Base controller.
Do not use Session, because you have to check whether it is timeout or not. It's hard to code in many places (my experience).
You can use Form Authentication that leveraged by ASP.NET membership. Then you can safely use HttpContext.User.Identity to check user privilege

Changing the membership providers ApplicationName during runtime. How?

I have a bit of a unique situation here. I'm making a web application that is going to have
the ability to login with different web applications credentials. For example you can login/register with my site or you can login/register with your YouTube account. I'm not using OpenID because I need to have access to YouTube's data in this case.
I'm using ASP.NET MVC 3 EF4 with custom Membership, role, profile providers.
The problem is user names can't be unique because someone with a YouTube user name could have the same user name as someone that registered with my site. So I got around with by specifying a user type in my user table. This is pretty much a composite key (user id and user type).
I have a custom authorize attribute that is checking for the role that the user is in but now I need to implement a custom IPrincipal because I need to pass a user type. Only problem is where do I store that? the session?
Originally I thought this is what the Application table was for, and I had momentary success with that but read there is threading issues, and I was getting session faults all over the place it wasn't that great :(
I'm wondering what the best way to do with is because I can't use the overridden methods in the providers because I have to add a UserType parameter to some of the methods, but then this breaks the functionality of the provider.
EDIT:
I basically need to have the ability to change the ApplicationName at runtime pro-grammatically. I tried doing this, the only problem was when I stopped my development server but left my browser open then ran my dev server again it wouldnt keep the application name.
EDIT:
I've changed my application to use OAuth, I never found a good solution.
I basically need to have the ability
to change the ApplicationName at
runtime pro-grammatically. I tried
doing this, the only problem was when
I stopped my development server but
left my browser open then ran my dev
server again it wouldnt keep the
application name.
If you need to change the ApplicationName, this means you need to select a provider at runtime.
The only way to do this is to NOT use the singleton "Membership" as it uses the provider defined in web.config.
Instead each time you need your provider use :
MembershipProvider userProvider = Membership.Providers[UserProviderName];
Just set UserProviderName the way you want. I would go with a custom global authorization or preAction filter which detect the provider from some cookie or other session variable and put the provider in the HttpContextBase.Items collection which lives for one and only one request.
The best answer to this problem is answered on stackoverflow here: Membership provider with different ApplicationName in area
Here's the code they used:
Membership.Providers["MyOtherProvider"].ValidateUser(username, pwd);
Ryan,
Hmmm... can you work-around the problem by prepending the issuing-authority (local or YouTube) to the username field itself... Example usernames: "LOCAL/corlettk", "YOUTUBE/corlettk"???
Ok, you'll need a custom Authenticator in order to split the complex-string, and flick-pass the login-request to appropriate underlying Authenticator... but once that's done, (I guess) you're all set to deal EASILY with the much bigger problem (from your perspective) of Authorisation.
I percieve that you're a smart guy... have you considered-and-dismissed this approach allready?
Cheers. Keith.
PS: Yes, I'm a hacker... but I have bad habit of hacking stuff up that WORKS... so they've given-up trying to educate me.

umbraco authentication

I have an existing community backend and I like to use Umbraco for my presentation layer. How can I implement login/logout with .Net forms authentication? (I don't want to use the Member functionality). I have different type of users that get's access to different type of pages. How can I control this? User control?
Umbraco uses the ASP.NET member / role provider model for it's membership system, and it's a pretty straightforward step to swap the default one out for your own implementation. I've done this in the past where I wanted to authenticate members against an Active Directory store but I can't imagine it being much more difficult to authenticate against a custom database.
The benefit from this is you get full integration with the Umbraco membership system, and by using a custom role provider, editors will be able to restrict pages using the built in page-editing facilities as opposed to you having to hook in your own security controls.
You should be able to create a simple membership provider by extending the UmbracoMembershipProvider class and overriding the ValidateUser method. I haven't done this myself, but I know of others who have.
To authenticate against a custom role provider, you'll need to create a class derived from RoleProvider. The methods you'll be interested in overriding are - IsUserInRole, FindUsersInRole, GetAllRoles and GetRolesForUser.
Here's a link to a Scott Guthrie blog post which has more information on the provider API than you'll ever need to know, including the source code for the default providers.
I've used two approaches on my umbraco sites. Both approaches include user controls for login and logout that are responsible for authenticating a user with a custom solution and clearing credentials respectively. I also add, for both approaches, an umbracoMembersOnly attribute to any document types that I want to protect.
In the first approach, I had each individual template check to see whether or not the user was restricted from access. To abstract this, I created a siteuser class with an isMember or isLoggedIn method that was available site-wide and could be called from either an XSLT or User Control macro. The benefit to this approach is that I could tailor custom messages on each template rather than merely providing the same access denied page.
The second approach - which is the one I favor now - if to create a Permissions macro that is responsible for checking the user's right to access any page (i.e. checks for an umbracoMembersOnly attribute and, if true, checks for a session variable). This macro gets included in the master template, and so executes on every template. If the user doesn't have permission to access the current page, I redirect to the same page but with an ?alttemplate=RestrictedPage or similar appended to the query string. (Make sure that your Permissions macro checks for an alttemplate=RestrictedPage in the query string, or you'll end up in an infinite loop of redirects.)
You can checkout http://osMemberControls.codeplex.com

Categories

Resources