Restart remote IIS site in another site - c#

I have more than one site on iis. Some sites working on another machine also but they are using same database.
Sites have caching mechanism. One of the site using for making customization about sites. Customization are saved on DB.
I want to reset caching for sites which are effected from customization. I can found two thecnique for this.
I want to asking for another solution.
Technic 1: adding restart endpoint for sites in web.config file and calling them when change made by user.
Technic 2: using db events for catching changes (in asp.net application may be I can't get changes because of sites dying after idle time)

Both of the techniques listed in your question have drawbacks. Technique 1 restarts the entire server, which is over-kill. Technique2 has the drawback you list, and is relatively complex to implement.
The approach I use is to provide a controller action that invalidates caches. That action requires authentication, and can be accessed either via an administrative web page on the server (single instance server), or can be invoked by accessing the URL of the controller action and providing appropriate credentials (server farm, invoke e.g. https://ServerNameOrIp/Admin/InvalidateCache once for each server/IP in the farm).

Related

Web Site Security - 1 main site, 1 secondary site hosted within the main site

Scenario:
ASP.NET 5 / Razor Pages / C#
We have one main site, with very good security. In the background, all passwords are encrypted. Also, a log is made of all logon usernames, from which IP addresses, at whatever time accessed.
We have a second site that is hosted within the main site visually on the front end via iframes mostly, but not on the server. They won't live together in the same web app.
Problem:
I need to ensure that the secondary site access is secure, whilst relying on the fact that the user already logged on successfully via the main website. I don't want the user to need to logon twice to two systems, rather I want the single logon to fluidly allow access to the secondary site.
I have a method I am using now. It works, but I really want to delve in and see if I can improve this given I'm not heavy on experience in terms of website security. I'm sure there is a better way.
Options?
From a security point of view, using iframes, the two site are independent.
So you need to guarantee that the security process is issued on both sides.
You have several possibilities, but the best, I think, is to revalidate the user in the "iframed" website.
You can use a token, generated from the main website and stored in a backend DB, and pass it to the iframe URL.
The endpoint of the iframe has to read the token, call a backend API to validate it and allow the access.
The main problem you have is to refresh the token after a reasonable time, in order to ensure the validity during the use of the "iframed" website.

Making relative urls in asp.net webform custom classes without Request

I have some kind of a job scheduling implemented which calls a function ProcessJob. Now inside this method I need to generate url to one of my pages i.e DoanloadPage.aspx?some_params. That url is sent to user via email and when user clicks that link, it will take to the page.
The problem here is that I am not generating url in a web request method or I don't have access to the Request object. URL need to be generated in a custom class which is threaded i.e not in a web request.
So I can't go with these solutions:
HostingEnvironment.MapPath("test.aspx");
VirtualPathUtility.ToAbsolute("123.aspx");
HttpContext.Current.Request.Url.Authority;
None of these works because I think they all rely on current request or session somehow. So how do I generate urls for my app inside my code so I can use them anyway I want.
If your method cannot use HttpContext.Current.Request.Url, for example in case it's a background scheduled task, then you can use either of the following options:
In case that your code is hosted in the same ASP.NET application, you can pass the site domain name of the site to your class, in the first request. To do so, you need to handle Application_BeginRequest event and get the domain from HttpContext.Current.Request.Url and then pass it to your class, or store it in an application scope storage. You can find an implementation in this post or the original article.
Note: The code is available in SO, so I don't repeat the code
here.
If your code is not hosted in the same ASP.NET application or if for any reason you don't want to rely on Application_BeginRequest, as another option you can store the site domain name in a setting (like appsettigs in app.condig or web.config if it's web app) and use it in your code.
You can do something like this. Dns.GetHostName will return the name of the computer that is hosting the site. You can use that to check if the site is on a development server.
string domain = "www.productionurl/123.aspx";
if (Dns.GetHostName() == "Development")
{
domain = "www.developmenturl/123.aspx";
}
The Dns.GetHostName() is not the only way to check. You could also use the HostingEnvironment.ApplicationPhysicalPath. You can check that also and see if the path is that of the development server.
My answer is: don't do this. You're building a distributed system, albeit a simple one, and generally speaking it is problematic to introduce coupling between services in a distributed system. So even though it is possible to seed your domain using Application_BeginRequest, you are then tying the behavior of your batch job to your web site. With this arrangement you risk propagating errors and you make deployment of your system more complicated.
A better way to look at this problem is to realize that the core desire is to synchronize the binding of your production site with the URL that is used in your batch job. In many cases an entry in the app.config of your batch would be the best solution, there really isn't any need to introduce code unless you know that your URL will be changing frequently or you will need to scale to many different arbitrary URLs. If you have a need to support changing the URL programmatically, I recommend you look at setting up a distributed configuration system like Consul and read the current URLs from your deployment system for both the IIS binding and the app.config file for your batch. So even in this advanced scenario, there's no direct interaction between your batch and your web site.

How to handle sticky sessions issue?

I am running into this strange issue where few users of my app plug out their laptops from dock and move to WIFI network while using the application, Now after changing the network when they click on any navigation in the application it takes them back to the login page mentioning the session has expired.
Background: The server where the application is hosted have the load balancer which dynamically routes the incomming request, hence when user goes of from one network to another the old session maintained by the web browser stays open but load blancer identifies it as a fresh request and hence allocate to next available server which requires a login, now if user is fortunate to be routed on the same web server where he was before then all works fine otherwise he is redirected to new web browser.
Please help me resolving the rare scenario issue.
Thanks in advance.
Vishal
This issue depends mostly on your load balancer and the persistence of stickiness.
Some balancers handle the sticky persistence internally, so they have a table between client IP and route. Your case sounds like that.
Now, if you shift the persistence from the internal table to a cookie (or URL appendix), you can tackle the case. By using a cookie, the client will send the cookie on every request and the load balancer can check, whether the requested route is still valid and then serve the request. There is a non-IIS example for Apache (http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html#stickyness_implementation), how they approach stickiness, but the feasibility depends on your balancer.
Since you have load balancing in-place then it is just a questions of whether to store the sessions in Jsession or Cookie, to avoid this issue I suggest your configuration the server to use Cookies. As by default Tomcat 7 (and I believe Tomcat 8) are configured to use Jsession

Retain session when calling from a different website

I have two website consider it as website1 and website2.
In website2 there is a login page .When a user click on the login button it will call a HTTPhandler in website1 to authenticate user.On successful authentication user information will be stored in a Session variable from handler.
Then it will redirect to a page page1.aspx in website1.But the previously set session is not available in the page1.aspx .What will be the issue?
I checked the session id in first request(when calling handler in website 1 from webiste 2) and Second request( redirecting to the page1.aspx from the handler) the session id is different.
How can i retain the session data?
You need to store session data in another process shared to both web site.
You can do it intwo different ways:
Configure an SQL server
Configure SessionState service, a Windows service used to share informations.
In both cases you have to change both web.config files to support the new session mode.
I.e. to use SQL:
Prepare a database (from command prompt):
cd \Windows\Microsoft.NET\Framework\v4.0.30319
aspnet_regsql.exe -ssadd -E -S localhost\sqlexpress
Modify web config as following:
<sessionState mode="SQLServer"
sqlConnectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Test" allowCustomSqlDatabase="true"/>
You don't need to change your code.
Correct me if I an wrong, AFAIK different domains cannot share a single session. One way to handle this is to carry the data to the other site through cookie [encrypt the values for security], then copy this cookie value to the session in the other site receiving it and destroy the cookie.
And if the sites are in different servers you need to handle the "sticky session" so that servers share the session.
This situation sounds kind of similar to one I have experienced and worked on before, where one web application acts as the login page while another is the actual app where all your work is done. I can describe what I did in the hope that you find it useful.
Like you I had one web app which had the login page (so in your example this would be website2). When the login form submitted I then redirect to a fake Login.aspx page in website1 - this is where we differ I think as I'm not sure of your specific reason for using a HttpHandler.
In my case the website2 Login.aspx page is actually just the way into the web application; it has no markup, just code-behind which will authenticate the user, perform setup (e.g. set session variables) and then redirect to another page such as Homepage.aspx. This particular scenario has worked for me, so maybe your problem revolves around the use of a HttpHandler though I would not be able to tell you why.
In order to retain the same session date across two different servers running ASP.NET web applications you must configure your session state to be managed out of process. This means the actual session state data variables will be stored outside of worker process and in another process that is able to make the session data available to other machines.
To achieve this you can configure your application to use SQL Server to store session state and make it available to multiple servers in your farm. The TechNet article Configure a SQL Server to Maintain Session State (IIS 7) provides details on hor this is done in IIS 7.
If you are using IIS 6 then the steps to configure are somewhat different and I can provide further details on this if needed.
In order for this to work you do need to ensure that both servers are running applications within the same domain, e.g. myapp.com, otherwise the ASP.Net session cookie will not be passed between the two servers. ASP.Net uses the cookie to lookup the session state stored in SQL Server and will therefore not find any matching session if the cookie is not passed on requests between the two servers.
i think IRequiresSessionState will not help because context is different.
once we had the same problem but that was passing asp session varibles to .net. How ever you can do it here also.
on both website create a page setsession.aspx
now if you are on page say web1/page5.aspx and want to go to web2/page3.aspx
you redirect to web1/setsession.aspx?togo1=web2/page3.aspx
in both setsession.aspx logic in to extract sessiondata and place them in querystring
so the web1/setsession will redirect to web2/setsession.aspx?sess1=value1&sess2=value2&togo=page3.aspx
web2/setsession.aspx will check for togo querystring and if found will extract all querystring name and value will set them in session and will then redirect to togo value.
you need to differentiate togo1 and togo carefully.
Session sharing between websites is going to require hand-coding. You could hack the asp.net framework to get this working, but I feel that this is not a clean way of achieving what you set out.
If user authentication is all you are doing from website, is it possible to use alternative? Single Sign On mechanisms will help you out here.
Something like SAMLSSO could help you in this case.
You have two websites which are hosted on different servers, it means you have two different processes running on separate machines, so sessions will be definitely different. Same session can't be shared across processes because by default asp.net support in-memory session.
Here you would need to think about storing sessions information which can be shared between two processes (i.e. out of process). Ideal way to store sessions information in databases. For this you can consider Stefano Altieri code sample above.
I don't think you really want to share session information between two websites at all. From what I can gather from comments, what you're really trying to do is have a user authenticate in one website (give you a username and password which are validated) and then have that "logged in" state transferred to another website which doesn't handle authentication for itself.
What you are describing is the Delegated Authentication model.
In this model, your application hands-off authentication to other systems which it trusts to provide information about users.
There are two well-known protocols which provide this mechanism:
OpenID
This is intended to facilitate users logging in with their own identity providers (Google, Facebook, Microsoft Account). It's a very good choice if you're running a public-facing website, as most users will already have an account they can log in with.
WS-Federation
This is intended to facilitate users logging in with identity providers which are managed by known trusted parties, such as partner organisations.
From version 4.5, the .NET Framework has built-in support for WS-Federation via the Windows Identity Foundation component (and is also available for earlier versions as a separate download). This automates the task of delegating your authentication to an Identity Provider.
It also provides components for you to write your own Identity Provider, should you want to create your own, but you shouldn't have to; you can find various existing implementations to perform this job for you.
The problem you're trying to solve is a very difficult one, especially trying to make it secure enough to be reliable. The good news is that smarter people than you or I have spent years working out very clever ways of doing this. You should use what they have done and not try to cobble together something out of Session state.
In the long-run it's best to let the smarter men do the hard work for you.

how to handle http requests from a browser using c#

I have a windows application developed in c#.Net which is used as a website blocker for a network.I have done this by modifying the hosts file.It works fine when urls are blocked like "www.yahoo.com".Now my requirement is I have to block the urls based on the keywords.i.e when the user just types "yahoo" in the browser,I should verify the keyword and block a corresponding website.Now how can I track the website typed by the user in the browser and block or allow the user to particular site based on the url.I should not allow the user to view the page if the keyword is present.How to do this?Can some one help me to do this?
There's plenty of code samples out there that will act as proxies (eg. http://code.cheesydesign.com/?p=393) however I would strongly suggest following the advice of the comments you've been given and go with an existing application.
Building a proxy that will not interfere with the complicated web apps of today is not trivial. You also need to be careful about blocking based on keywords - web apps I've worked on have failed in spectacular ways due to proxies doing this, and rejecting requests for important javascript files (often due to minification or compression) rendering our app useless.
Also consider that your proxy won't be able to check SSL traffic (which is increasing all the time) without serving up your own certs acting as a man-in-the-middle.

Categories