Passing ID from Browser Tab/Window/Page to Server (ASP.NET MVC) - asp.net-mvc

I create and safe a Browser Windows GUID in the sessionstorage on client side via javascript. So it stays alive until the tab is closed.
Now I want to pass this information on every request from this specific browser window to the server side so I can access it on any time without passing it with the model.
I use ASP.NET MVC. So there is no ViewState available if I'm right.
I thought about adding and accessing a custom field in the HTTP Header or something similar. I try to find something to accomblish that. So I need some ideas.
Thank you
(Sorry. English is not my first language)

Once you set the Cookies, it shall be pass with every HTTP request to the server. And in the Controller you can access Cookie via
HttpCookie cookie = HttpContext.Request.Cookies.Get("cookie_name");

Related

.net core app losing # location on redirect

I have a .net core 1.1 app which uses client side hash navigation on some pages. For example, http://www.mypage.com/foo#bar. The problem is that if the user is not logged in and /foo requires authentication, we use a returnUrl to send them back after they log in. The route should be /login?returnUrl=/foo#bar but the #bar portion is getting lost.
All of this used to work before we converted to .net core (several months back). Does anyone know how to get this to work in .net core? I've tried to step through the request and everything from the # on is lost. Even using Request.GetDisplayUrl() only shows the url up to before the #.
Does anyone know how to get this to work in .net core?
Can't be done with server side redirect. The hash value is never sent to the server so if you redirect the browser will just throw the hash value away.
You'll either have to write javascript to send the hash to the server via querystring/post-body or store the value in local-storage/cookie client side and add the value after redirect.

asp.net mvc and web farm

given the nature of the project, I need to store a simple object (with 3/4 properties) in TempData. It is a read once write once so that's fine but does need to be passed between a few core methods/actions.
question is: How can I make it work with webfarms? What things are needed to be configured to allow TempData to work with a webfarm?
using MVC 4 Razor.
thank you
By default, TempData is implemented using Sessions, so this would be a problem on a farm.
The easiest solution would be to use the CookieTempDataProvider
TempData is stored in the session. This means that the only reliable way to use it in a web farm would be to have a state server of some sort.
Changing the ApplicationId (MachineKey) on all the servers to make them match does nothing for session. That only means that each server can decode the cookies left by the others. Session lives on the individual web server in memory.
If you don't have sticky sessions on your load balancer, the request that populates TempData on server 1, will likely redirect to a server different than itself and TempData will not be populated (or not with the same data that was just put in on server 1).

Delphi, using idhttp to automate submit button

Assuming I have internet browsers like mozilla and iexplorer, so, I used mozilla and I have already logon to a website using my account username and password logged in, well idhttp can post(submit form, automated click) to the already opened account(without opening the web browser)? OR I will have to used again my username and password to post a submit?
I dont need a code, just asking for answer YES or NO, and if NO! what control in the INDY should I use in my approaced?
Sample: I want to automate a submit button for a click(my account is already logged-in)!
thanks
There is no simple YES/NO answer to your question. It depends on how authentication is handled by the web site/server.
By default, http is STATELESS: each call into the server knows nothing about the previous call. In that case, you will have to authenticate EACH TIME you hit the server.
But most modern sites implement some kind of authentication persistence: either by maintaining user session information on the server, or, as Arnaud Bouchez mentioned, sending back a cookie that keeps track of your authentication.
I once wrote a custom web application that sent back an encrypted authentication token with the first response, and it was the client's (it was a custom Windows client with an embedded socket implemented using idhttp, not a browser client) responsibility to send back that token for each subsequent request.
So, your answer is: Let the server handle it - you generally don't have much choice.
I suspect the authentication will be local to the browser, i.e. validated via a browser-specific cookie.
From the Delphi code, you would need to retrieve the cookie (it may be possible, e.g. from a SQLite3 file with FireFox, or as plain text in user profile with IE), then use Indy to query the web site, including the cookie content within the request headers.
But it will highly depend on how the authentication is done. For instance, does it use HTTP or HTTPS protocol? How is implemented the server side?
How about creating a custom browser with a function to auto submit after you login to the site?
I ever make a custom browser with an auto form submit function using TChromium and TBrowser.
It's easy. You just need to know how to control dom using javascript and also manipulating the page source.
Sorry for the simple answer

How to make WebAPI actions accessible only from my app?

A common use case for WebAPI would be to have shell views rendered by MVC controllers, which contain javascript that then hit your API to access data.
But let's say you have some expensive API operations and you don't want people remotely accessing those endpoints -- you only want your MVC views, delivered by your application, to access them. How could you go about protecting them?
In this case Request.IsLocal doesn't work, because javascript is invoking it from the client's browser on their machine. Even if it did work, you need to dig to get the real HttpContext in order to find this property -- and that solution wouldn't work in self-hosted WebAPI.
For API endpoints that require a valid IPrincipal, you could protect them with the [Authorize] attribute. But what about API endpoints that you want your app to be able to access for anonymous users?
I have tried a solution and will post it separately as an answer, because I'm not sure if it's the best (or even a good) approach.
If your MVC site uses authentication, you could enable forms authentication for your Web API methods. You could write a custom [Authorize] attribute that will check for the presence of a forms authentication cookie which will be sent from the AJAX call and if present construct the principal.
Another possible solution is to protect your API with tokens which is a more RESTful style. The idea here is that when a user authenticates on your MVC website you could generate and pass a token to the view which will be used when sending the AJAX request to the Web API which in turn will verify the validity of the token and its signature.
If on the other hand your site doesn't use authentication, then things will get very complicated because you have no way of knowing whether the request comes from a trusted client since you are using javascript to call your API methods.
Before you go harping about "what have you tried", here is what I have tried. It works. Just not sure if there is a better way.
Create an MVC action filter and add it as a global filter during Application_Start.
Create an Http (WebAPI) action filter and use it on actions that should reject remote requests.
The global MVC filter does this:
Looks for a specific cookie in the request. If the cookie is there, its value is decrypted. The decrypted value should be a string representation of a DateTime, so use DateTime.TryParse to get it out. If the value is correctly parsed to a DateTime, and that DateTime is less than a day old, STOP HERE and do nothing else.
If the cookie is not there, or cannot be decrypted / parsed, or is older than a day, write a new cookie to the browser. Use the current DateTime.UtcNow.ToString() as the value, encrypt it, and write it with HttpOnly = false.
The WebAPI filter does this:
Looks for a specific cookie in the request. If the cookie is there, decrypt its value and try to parse it out as a DateTime.
If the value is a valid DateTime and is less than 2 days old, STOP HERE and do nothing else.
Otherwise, throw a 403 Forbidden exception.
A couple of notes about my current implementation of this. First of all, I use AES encryption with a shared secret and a salt. The shared secret is stored as an appSetting in web.config. For the salt, I enabled anonymous identification and used Request.AnonymousID as the salt. I'm not entirely fond of the salt because it's tricker to get at in a WebAPI controller, but not impossible as long as it is not self-hosted.

MVC3 mixed forms and Windows authentication

I currently have an intranet site that is accessed by external customers. I therefore set this up using Forms Authentication. However the powers that be (my bosses) want all our domain users to not have to enter their username and password to access the site.
I've done a bit or reading and everything seems to point to setting up a WinLogin.aspx page that you alter to use WindowAuthenthication and then redirect from there.
I have a problem with this as I don't like the idea of putting an aspx form in my mvc application.
Can anyone tell me how to achieve mixed authentication using a strictly MVC Controller/Action setup without a second application?
NOTES: running MVC 3 on an IIS 7 box.
Forms Authentication is not related to the URL or physical structure of your files. What matters is that a URL should ultimately map to a physical (or virtual) resource on the server, and be processed, and be returned back to the user.
Thus, somewhere in between for each incoming call (each HTTP request, even those for CSS and JavaScript files), you have to see if the current user has enough permission to access it or not. If no, then you might redirect him to the login page.
If you want, you can have a URL like /user/windowslogin where user is the name of the controller, and windowslogin is the name of your action method. Then you can create a custom authentication attribute (something like [WindowsAuthentication]) on your windowslogin action, and in that attribute (which is an MVC filter in essence), you can see if the current request comes from within your domain, and if so, talk to Active Directory for authentication or stuff like that, and on case of successful authentication, create an authentication cookie using FormsAuthentication class, and the rest of the story.
However, I don't think this would be an easy task. Others might introduce better solutions.

Resources