Log All Requests for User Per Webpage - c#

I want to build an "audit trail" for all requests incoming to the server, however it needs to be specific per user, per web page.
For instance I imagine something like this:
On initial view render I would store (cookie/ page variable/ something else) a unique Id saying the user browsed to /myapp.com/dashboard/1234. - maybe in the layout.cshtml.
Then the app fires off X number of GET/ POST requests to the server each having that same unique Id initially tied to the view rendered.
This allows me then to tie back all requests for a page and add up the server execution time.
I tried using path specific cookies but this won't work I realized since a user can have many tabs open with the same url. Also the user works in many areas of the app at once. They can have anywhere from 1 to 10+ tabs open. Each of these should have it's own unique Id and "audit trail" of all calls taking place on that page.
This is an existing app so modifying each of the GET/ POST to pass in the unique Id is out of scope. Just hoping I am missing something that might take care of this.
Thank you!

If I'm understanding you correctly, you have a single page load, and then additional requests made either for images and other resources or AJAX requests that you want tied to and tracked along with that initial page load.
The chief problem you're going to have here is that, based on the way HTTP works, each request is handled as its own thing and not considered as part of a greater whole. The web browser makes it all look seamless, but all the web server is doing is just responding to a bunch of (as far as it knows) unrelated requests for various different things. To track them all as one unit, you would either need to attach some unique id to the request itself (for a GET, that would be either as part of the URI path or query string) or lean on Session to introduce state between the requests. However, session state really only works in this scenario when all requests can be tied to a single initial request. Once the user starts working with multiple different pages at once, there's no reasonable to discern which request belongs to what, and you're back in the same boat.
In other words, your only real option is to send something along with the request, which would mean doing something like:
<link rel="stylesheet" type="text/css" href="/path/to/file.css?origin=#Request.RawUrl" />
Then, you could have an action filter that looks for origin in the query string of any request, and ties it to the logging for that particular page.
For what it's worth, it should be noted that by default, IIS will handle all requests for static resources directly, without involving ASP.NET. If you do want to track requests for static resources, you would have to pass them all through ASP.NET, which will be kind of a pain. If you only want to track AJAX requests, that's much simpler and shouldn't require anything special for the most part.
All that said, if the only purpose of this is to track page load time, there's far better and easier ways to do that. You can install Glimpse. You can use your browser's developer console. You can use something like Google Analytics. All of these are far preferable to the path you're going down here, for page load statistics.

Write an ActionFilter to do this. There are many examples of this
http://rion.io/2013/04/15/creating-advanced-audit-trails-using-actionfilters-in-asp-net-mvc/
http://blog.ploeh.dk/2014/06/13/passive-attributes/
I personally like Mark Seemann's example more since it clearly defines a nice separation of concerns for the attribute and the filter.

Related

Is it possible to reroute a user based off of parameters sent to a Controller?

I'm pretty inexperienced when it comes to working with IIS, so I apologize if the question is a bit confusing.
In the application, I have a Controller with a method called 'Login' that takes in a string parameter. The parameter identifies the organization the user is trying to authenticate against.
For example:
http://mysite1.com/Login/12345
Visiting this link brings the user to a login page for the organization that is associated with '12345' for their access key.
Is there any way to redirect users that are logging in under '12345' to another server? We have a few beta users that are willing to participate, but the database schemas for both servers are different, so it's important that the beta users are not hitting the wrong site.
After the user logs in, the access key is no longer in the URL, so I can't do matches against it.
I'd like for the user to see the following URL:
http://mysite1.com/Login/12345
http://mysite1.com/Products/
http://mysite1.com/Admin/
While in reality they're on a different server:
http://mysite2.com/Products/
http://mysite2.com/Admin/
I have to emphasize that I really do need the URL to stay 'mysite1' for the user, when in reality they'll be on 'mysite2'. Please let me know if this is possible or not, or if there's a better solution for it.
Sorry if this is a confusing scenario or if there's some information that I'm missing. I'll make edits if necessary.
Virtually anything is possible, but this approach seems really painful.
IIS can perform URL rewriting but it's going to be doing this before it hits the authentication layer so it will not be possible to differentiate users at that level.
It seems like the best option will be to write a custom URL rewriter provider. Looks like this post is attempting to solve it that way.
It really seems better to either redirect to a different server (which I know you're saying you can't do) or merge the multiple versions of functionality into a single app (with different controls/backend models, etc.)
This link may help in understanding a little bit about how the flow works in an ASP.NET MVC app.

MVC Get Vs Post

While going through MVC concepts, i have read that it is not a good practice to have code inside 'GET' action which changes state of server objects( DB updates etc.,).
'Caching of return data' has been given as a reason for this.
Could someone please explain this?
Thanks in advance!
This is by HTTP standard. The GET verb is one that should be idempotent and safe.
9.1.1 Safe Methods
Implementors should be aware that the software represents the user in
their interactions over the Internet, and should be careful to allow
the user to be aware of any actions they might take which may have an
unexpected significance to themselves or others.
In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action
other than retrieval. These methods ought to be considered "safe".
This allows user agents to represent other methods, such as POST, PUT
and DELETE, in a special way, so that the user is made aware of the
fact that a possibly unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects, so
therefore cannot be held accountable for them.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Browsers can cache GET requests, generally on static data, like images or scripts. But you can also allow browsers to cache GET requests to controller actions as well, using [OutputCache] or other similar ways, so if caching is turned on for a GET controller action, it's possible that clicking on a link leading to /Home/Index doesn't actually run the Index method on the server, but rather allows the browser to serve up the page from its own cache.
With this line of thinking, you can safely turn on caching on GET actions in which the data you're serving up doesn't change (or doesn't change often), with the knowledge that your server action won't fire every time.
POSTs won't be cached by the browser, so any POST is guaranteed to make it to the server.
Ignore caching for a moment. Another way of thinking about this is that search engines will store HTTP GET links during their indexing/crawling process, therefore they will show up in search results.
Suppose if your /Home/Index is implemented as GET but it lets say deletes a row in your Database, every time this link shows up on a search engine and somebody clicks it, you will have a delete row, and soon you have a lot deleted rows.
The HTTP spec states that GET and HEAD are expected to be idempotent, ie. they should not change server state.
One practical aspect of this, is that search robots will issue GET against any link to your site they know of. If such a GET changes user data it was not meant to change, you are in trouble.
Being idempotent has the added benefit that clients could be able to cache the result of a GET (use HTTP headers to control this).

Dynamic Page Rendering in ASPX

I'm very new to C# and .NET and I find myself faced with a problem and I'm not sure in which direction I need to head.
My company works with a third party subscription fulfillment system for many functions, including billing and renewals. This system has the capability of automatically sending an email when certain events are triggered. For example, each subscription goes through, what we call, a renewal series. This series consists of several efforts spread accross the life of the subscription.
When a subscription qualifies for a certain effort of this series, we can have an event generated that will cause the system to send a HTTP POST request to a given URI with an XML payload. The endpoint (an .aspx page) receives the request, processes it, and returns a response with, in this case, HTML code. That HTML is then emailed out by the fulfillment system.
I have a basic web application created with a few of these .aspx pages up and running. Each page has a corresponding .cs code behind file.
Here's where my question really starts. In our fulfillment system, we can only define one endpoint per combination of event and product. So, no matter which effort a subscription is qualifying for at the time, the event itself is the same. What is different, though, is the XML of the HTTP POST request. It's in that XML that I can tell for which effort the request has been generated. The reason that is important is because the HTML of the corresponding email is different for each effort. To phrase it a slightly different way, the HTML that should be rendered is different, top to bottom, for effort 1 than effort 2. Effort 2 is different than effort 3, and so on.
So, what I'm trying to figure out is how to "direct the traffic". Since all of these requests will come to a single endpoint, I need to dynamically return the correct HTML for the corresponding effort.
In a different .aspx page in this same app, there is some content that needs to be generated dynamically depending on the contents of the request. In that case, I used two PlaceHolder controls, one for each possible set of text. Then, in the code behind, set their Visible property to true or false as needed.
I dismissed the idea of doing that in this case early on since there are five or six HTML templates and stuffing all of them into one page would be messy and hard to maintain.
This is where I'm at the point that I don't know what to do next. I have a feeling that a User Control or Custom Control is going to be the way to go? But, is plain old redirection a better option? Or none of the above?
The solution you dismissed is very close to the correct one. However, there is something you can do to simplify it and make maintenance easier.
What we want to do here is build a custom control or a user control for each effort. This will let you maintain the code for the efforts separately, without mixing everything together in one place. Then your entire endpoint *.aspx page consists of a single placeholder control. When processing a request, your Page_Load method will parse your xml and figure out what kind of effort you need. It will then create a new instance of the proper control, add it to the placeholder, and pass the rest of the data to the control to finish processing.
Because there is some commonality among all the controls here (the ability to receive an xml message), you may first want to also create one base control for the individual effort controls to inherit.
From what I understand, you'd like to have a single endpoint but still be able to "route" requests internally. This is easily possible.
You could for example transfer requests internally, using Server.Transfer. This way you can have your 5 or 6 different HTML templates and then route incoming requests to a correct template depending on the content of the request.
enter link description here
Here we give An Example here to creating a new .aspx page at run time. We also give the option to give page name. The user can give as he/she like. Like Google blogging we make new page at runtime.The new page is not in the website, this page create needs to be created at runtime and needs to be dynamic.

What should a merchant site worry about when implementing a payment gateway?

I have to implement a payment gateway for a website I am maintaining, and I haven't done anything like this before. Previously to implement payment processing, the site would build a transaction and send it directly to the payment processor and await a result. Since the site handled the gathering of credit card information, building of the transaction, and the requests/responses, there wasn't much I had to worry about that the previous developer hadn't already covered.
Now that I'm implementing a payment gateway, is there anything I should be checking or verifying?
The way this processor works is, I build a form that has the order id, amount, currency, etc. in hidden fields. That form is posted to the gateway, which will handle the processing, and then post a form back to our server where we can update the shopping cart and complete the order.
The only thing I can think of is a user modifying the form fields before we post them to the gateway. Such as adding a $100 item and changing
<input name="amount" value="100.00" type="hidden">
to
<input name="amount" value="0.01" type="hidden">
So when I receive the post I have to verify that the amount paid for was equal to the amount owed. Is there anything else I am missing? The implementation documentation doesn't even mention a scenario similar to the above, so I'm a little worried I'm missing other things and leaving the site open to further exploits.
I think you'd be better off creating a dedicated web service to handle this '3rd party' conduit architecture you have going on here, your basically playing the middle-man and an HTML form just feels like unnecessary overhead to me, unless it's required to be done that specific way, I'd move to a web service.
That being said, treat it like any client application, don't trust whatever they give you, validate and cleanse the information as necessary before performing the operation.
I would also recommend building or integrating support for logging into your middle ware system, so should a problem arise, you have some way of capturing issues and tracking them for the future, bug fixes, support calls, etc.
It's probably obvious but make sure to validate your order #'s, a user could put anything in there they wanted, again, validate and cleanse the data and log the truly weird situations.
First, I have to agree with Capital G. It would be so much easier to just make a server to server connection than to try and handle form submission through the client browser.
One thing to check: after submitting to the gateway, does the client then initiate the post back to your server, or does the gateway server handle it? If the client initiates it, what prevents them from POSTing to you that the order is complete without ever having gone to the gateway? It sounds like you might need to make a webservice request to the gateway to verify the payment actually went through before accepting the client POST that claims it did.
Could you add a digest to the communication? If you had a shared secret with the gateway you could validate the integrity of information shared even if it passed through the client by including a digest both ways.
Make sense?
Carl
First, I don't think you're implementing a payment gateway. It sounds like you're just using one. If this is wrong, just ignore the rest of this answer, and I'll delete it when I can :)
Using a Payment Gateway from a Simple HTTP Form
Google Checkout -- as one example -- allows you to use an "unsigned cart" like the one you describe. The other option is to post via the web service interface, and do correct error checking etc.. When you submit an order with an HTML form, Google Checkout warns you, the merchant, that the "cart is unsigned" (later in the admin screen). This means that the information in the cart -- especially prices -- is not to be trusted. The fact that the end-user put in their credit card basically vouches for the fact that the transaction is okay with him/her. So you just have to check that the numbers used to arrive at the final totals -- or amount owed, or whatever your business is -- check out. So what you're doing is fine on a low-level.
The reason you should use a web-service submit to the service -- and secure signing of the cart, etc. -- is... What do you do if the numbers are wrong? Call the end-user up and explain the situation? So that's a bit tricky, because you cannot assume fraud. There are many strange reasons for which the cart would be altered without the user actually wanting to scam you.

Is it possible to "autopopulate" fields in IE?

the company I work for want to use a "hosted payment form" to charge our customers. A question came up on how we can populate the "payment form" automatically with information from one of our other system. We have no control over the hosed payment form, and we have to use IE. Is this possible at all? And if so, how can this be done?
If something is unclear, please let me know...
Assuming that you are essentially embedding the contents of a remote form in a frame/iframe, the you should be able to use some javascript to set values for the fields - field.value = "xxxx".
That solution of course depends on the form remaining the same - any changes to the remote form will require you to update your script.
If you are "handing off" to a remote site (redirect) that post's back to your site when payment is complete, then unless the remote site offers an API / a way of passing request parameters through, then you are going to be out of luck,
Unless your payment gateway allows you to pass through data in a set API (which lots do!), you'd need to take control (and responsibility) for your payment form.
I say responsibility because you would have to prove to your merchant account provider that everything is secure. This will probably incur some security testing fees too.
So check with your merchant gateway first. Lots of systems have the means to accept data from your site and their tech support will be able to give you a straight answer immediately. Otherwise you'd have to switch it over so you process all the data yourself which, just for making things easier, isn't worth it IMO.

Categories