IIS URL Rewrite based on logged in user - asp.net-mvc

I have a scenario whereby I want to route http requests from authenticated users to specific websites hidden behind a reverse proxy. The decision of which site to route too is based on the specific user. For example, user 'Mary' may be routed to site "b"; user 'John' may be routed to site "e".
I am hosting the sites on IIS and am using ARR as my reverse proxy. I'm trying to figure out the best way to use URL Rewrite to make the routing decision.
One idea I had was to build a custom URL Rewrite provider that decrypts the FormsAuthTicket (created by an ASP.NET MVC website) and makes the routing decision based on information in that cookie.
Can anyone provide some guidance on how I can solve this problem? Am I on the right path?

Related

domain specific ASP.NET MVC5 route with IIS rewrite

I have an MVC5 web application which maps to a domain www.example.com. I'm using basic {area}/{controller}/{action} based routing in my webapp and would need to map a subdomain to a specific route.
For example:
subdomain.example.com needs to always server content from http://example.com/area/controller/action
Ofcourse the route has to work with ASP.NET MVC5 routing and also all query parameters and "hashbang" data need to be retained so that:
http://subdomain.example.com#/somethinghere?var=value redirects content from http://example.com/area/controller/action#/somethinghere?var=value
So the question is: is this achievable with IIS routing/rewriting and if so, how? Another option would be to write custom MVC5 route which binds to a domain and I would love to see someone point me to a right direction with that, too.
This will not be possible, anything after the hash is client side only and the browser will not send it back to the server. As it is not send to the server there is no way to rewrite it.
As an alternative you can consider changing your routing to use pushstate instead of hashstate

ASP.NET MVC Routing - Do you keep ID's exposed in URL?

I have an ASP.NET MVC Application and the routing urls looks as follows:
foobar.com/users/8
foobar.com/users/90
foobar.com/exercise/details/5
foobar.com/exercise/details/400
So with this URL route, a user can manipulate the URL directly and change the ID's which are integers. What is the best practice of securing this so that users can't easily manipulate the URL ID's? How do enterprise applications handle this?
For a well designed system, users manipulating URLs should not be an issue. Even if you send the data in an HTTP Post body, users can still manipulate it using an intercepting proxy such as Burp.
Relying on secrecy of IDs (for example, choosing IDs randomly) is also not a solution. In pentester terminology, you will be vulnerable to direct object reference. The classical terminology for this flaw is violation of the complete mediation principle.
Instead of worrying about what users may do with URLs and content sent to your server, you should be securing the server from malicious inputs. The issue here is authorisation. I recommend you have a good, thorough read of Securing your ASP.NET MVC 4 App and the new AllowAnonymous Attribute and NerdDinner Step 9: Authentication and Authorization.
A lot of applications are designed to be URL hackable in that the user can change values. A lot of users like to manipulate the url to change page number, record, etc.
There is nothing wrong with this As long as you make sure its all secure. For instance your Details action should check the user can access record 5 before showing it.

Method for Sharing Forms Authentication Login between MVC.net and Web API Sites on the Same Domain

I am going to have an ASP.net MVC web site (example.com) and a Web API site (api.example.com) running on the same domain. What is the best and most secure way to use Forms Authentication to allow a user to log in to the MVC site, and have that login accepted by the [Authorize] filter in the API site? Additionally, there is the possibility that both sites will be hosted on multiple servers (each of which might have its own subdomain), so a solution that would allow for a single sign on approach to work among all of the servers in the cluster would be preferred.
Take a look at this link http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms this covers the answer in detail.
You will need to ensure all machines and separate applications on the site share a common (but unique to production) machine key to allow the authentication cookies to be trusted by all the machines/applications.
If you are simply using virtual directories under the same sub domain then simply harmonising the web.conig Forms Auth settings and machine keys should get you up and running very quickly.
If you want this to work between a second level domain then you need to change the "Domain" setting on the Form's Auth cookie. See the article for details.

Create another Logon page for external link

I want to create another logon page for external direct link(multiple projects need identity Logon page appearance.)
Is that possible to create another view for logon controller or I need to create another controller? I tried to create another controller, but I can not access at all.
Is there someone get some good ideas about that??
Cheers
If you are using same authentication mechanism, you can just pass external URL as parameter
http://yourwebsite/Account/LogOn?returnUrl=<external url>
and then redirect the page to the return URL after authentication.
It's a bad idea for your logon to return to an external link. don't do that. See Ch7 of the Wrox Professional ASP.NET MVC 3 book.
This is known as an open redirect attack. There's code in ASP.NET MVC 3 internet template for the Account Controller which prevents Open Redirect, but the risk of allowing it is that anybody can give out links to your site's login address with a malicious url in the return url query string. By allowing this Open Redirect, you make your site's visitors prone to social engineering. A hacker could send out links to your site to your users. They click, it looks like your site, address bar is right, the site appears secure, cert good and all. They logon, then they're redirected by your site to an external url. The external url may have any code running at all, and could make your users vulnerable to any number of attacks/ javascript attacks.
I know I mention MVC in particular, but the same holds true for any site.
If you need a logon page for another site, then you need to copy in the controller and views to that project, as well as setting up the config in that project (you can view your existing project for the appropriate settings).
Are your sites all related, with the same users and such? or are they separate disparate sites? If they are all related, can you put them in one project? That way you could just use the one membership provider and db, and different controllers/view folders for the different sections of your site?
Or are you in a domain where you can use Windows Auth and skip showing a logon page?
Or do you want to go with a single sign on application like ACS in Azure or STS server, or something. (look for good/modern book on WIF, which discusses ACS 2.0, if so)

ASP.NET MVC multi-site SSO using OpenID

I am putting a plan together for a series of sites that will share user account information among them. The idea is that once a user logs in using their OpenID, they can access any of the sites and it will know who they are.
What are the common patterns/best practices that i could employ to achieve this?
If all the sites share a common hostname in their URL then you can set an auth cookie (FormsAuthentication.SetAuthCookie) specifying the path of the cookie to be "/" so that all sites can see the user is logged in.
If the sites are not sharing a common host name, I think the only way to get a truly "once signed in, signed in everywhere [within your ring of web sites]" would be for all authentication to happen at just one site (perhaps one dedicated to authenticating the user) and for the other sites to redirect the user to that site for authentication and then that site would redirect back. In essence, that auth site becomes an identity provider, and almost exactly fills the role of an OpenID Provider (in fact DotNetOpenAuth could be used here for this exact purpose). Since it sounds like your goal is to let the user log in with their OpenID, your OpenID Provider on that one auth site could itself use OpenID to authenticate the user. Your own pure-delegation OpenID Provider could be written such that it always responds immediately to checkid_immediate requests as long as the Realm in the auth request is one of your trusted ring of sites. Thus you could effect single-sign-on across all your sites.
Please consider the following Patterns & Practices on Web Service Security from Microsoft:
Brokered Authentication - http://msdn.microsoft.com/en-us/library/aa480560.aspx
The main topic is - Web Service Security
Scenarios, Patterns, and Implementation Guidance for Web Services Enhancements (WSE) 3.0
http://msdn.microsoft.com/en-us/library/aa480545.aspx
Ultimately theres lots of ways you could do it. I achieved a simple single sign on by building a url with a token from one website pointing to another domain. The encoded & encrypted token contained details to submit back to the previous domain. Upon receiving an incoming request on the second domain, an underlying web service checks that the incoming request's token is valid with the previous domain using a shared private secret, known to both domains.

Resources