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.
Related
I use asp.net WebAPI to provide the service.But I found to explore the id of the entity(Resources identity ) is not a good idea.
eg. if you pass your UserProfile ID to get user's profile. because the id is auto incremented in DB, if someone iterates the Ids to get the others' profile, it will make the users' profiles to leak.(maybe you suggest to use GUID, But int type id has better performance)
So I want to encrypt the IDs with time in WebAPI filters. Is there a good demo for this?
Update: don't confused by User demo. If you have products. first you get the products list,then you will get product detail by product id . How to proect product id.
You shouldn't hide the id's but you can control it with roles. Return resource with different amount of properties based on who's requesting.
If it's anonymous call, maybe don't return anything or return only data which is public and can be seen by anyone any way.
If it's logged in user, maybe he can see more data about other users.
If it's admin who is requesting that information, he can see even more data.
If the user is requesting information about himself, even more data.
Now maybe it would be better to have different endpoints for different level of access so that it's easier to define and document your api, for example for user to get his own information, it would be /user/me.
I'm designing a site using ASPx and IIS, where clients can sign up and then offer services to their clients. For example:
if you go to http://www.mywebsite.com you can sign up for your mywebsite.com account as a business owner. When you sign up, you are given a Site ID (Example: AA1234).
http://www.mywebsite.com/AA1234
What I want to do is always include the Site ID in every url (Inbound and Outbound). The Site ID is stored in a session variable based on the initial incoming request.
Does anyone know of a good way to do this - or a different design that works better than this?
Thanks
Your question is nebulous at best. However...
Wouldn't this be what cookies are used for?
In particular, if your user is authenticated (this is generally achieved in asp.net with an auth cookie), then at the server, you would have tools at your disposal that allow you to recognize the user and provide a different experience according to whatever criteria you choose. Most likely, these details might be stored in a database.
Found the answer in this topic: http://www.tek-tips.com/viewthread.cfm?qid=1149673
The last response from BoulderBum is exactly what I needed.
Using the HTTP module I will take the /AA1234/ URL and point it to /Company/.
On the way out, I replace all instances of /Company/ with the site id again
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
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.
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