Accessing the file system from a WCF service hosted in IIS - c#

I have the need to read and write files on the server file system from within a WCF service hosted in IIS. This service is called via a Silverlight 4 application and RIA services. The file paths can be fixed to a known location on the server but we are having issues getting passed security issues and continue to get "Access Denied" errors. The application itself uses Forms Authentication and the web server is configured for anonymous access.
We haven't gotten passed this issue in our development environment and I'm assuming that in production we can specify a specific account in IIS to host the site under and then grant that account specific rights to the file system. In development using the VS 2010 development web server what are our options?
Our goal is to do something as simple as creating new files or deleting files from a known path on the server (i.e. "C:\Temp\") from within a method call to the WCF service. it's acceptable that it even be a temp folder underneath the virtual directory.

Your best option here: don't use the dev server for this; use IIS. Fighting tooling issues in something unrelated to what you are trying to do is a waste of time, so try to mimic your deployment environment as closely as possible.
You might also be able to use IISExpress for this, but since you know you already have nuances, I'd just go the whole-hog and use IIS. This also lets you hone the deployment process, which is a dev task.
Once setup, just create an app-pool and associate it with new account (not your account, unless it is going to be your account in production).

Related

Application Insight on premises without Internet Access

I've to develop a WPF application in an intranet environment with no internet access for security reason. I was wondering if it's possible to collect data locally (on a server) then to FTP them or even better to have the application insight alternative installed on a Server.
Has anyone faced a similar situation and have been able to solve it?
You could do something like that yourself if you really needed to. Instead of using the built in InMemoryChannel or ServerChannel classes to send telemetry, you'd create your own implementation to store them somewhere else. (or you could change the endpoint that the default channels point to to a web service inside the intranet.
you could then collect those files up and ftp them outside, and write another service to read those files and send the telemetry to app insights. Though it seems less like a good idea given the intranet with no internet for security reasons.
Or, better yet, you could simply write internal service to parse and store all that telemetry and show it on that web service inside the intranet and use appinsights only as an sdk and schema, and don't send any of your data outside your intranet at all.
More likely: upvote adding AI to azure stack, (https://feedback.azure.com/forums/357324-application-insights/suggestions/11683746-bring-application-insights-to-azure-stack) and then get an azure stack implementation inside your intranet? then you get all the other goodies of Azure from Azure stack as well.

Configure IIS as a load balancer for two kestrel servers (for the same website)

ASP.NET Core cannot be run directly in IIS as it requires Kestrel.
This means it is not possible to update a website at runtime like in traditional ASP.NET sites, since the kestrel server have to be shut down during the update.
I want to avoid downtime without adding additional web servers and a load balancer. Is it possible to configure the ASP.NET Core module in IIS to connect to two different Kestrel servers? So if one of them is shut down all requests will go to the other one?
(I was thinking something like having two different folders on disk: C:\inetpub\wwwroot\mysite_instance1 and C:\inetpub\wwwroot\mysite_instance2, thus shutting one down will enable updates of that instance)
If it is possible, are there any considerations we need to be aware of? For example, do the anti forgery token need to be configured in some way? (I do not use sessions.)
I would also be interested in a neat load balancer mechanism, but don't know any way to do it. Yet, you can perfectly switch the directory targeted by a web application from a directory C:\inetpub\wwwroot\mysite_instance1 to a directory C:\inetpub\wwwroot\mysite_instance2, update instance1 and switch it back, and it should do the job.
This is not currently supported due to the way in which IIS and the AspNetCoreModule works.
IIS passes an IHttpContext object to the AspNetCoreModule. The AspNetCoreModule uses the IHttpContext object to query the physical application path. The module then reads the web.config file found in the directory of the application. Once this has been done the module maintains a 1:1 relationship between the IIS application and the dotnet process.
I've raised this as a question and included some additional details on your behalf.

How to make file references to local disk work in Azure Web Site?

In my Azure Web Site I have in my AppSettings section in Web.Config some references to files on my disk. When deployed to Azure those references doesn't count any more. I know that you can overwrite AppSettings in Web.Config in the Azure environtment. But what is the file structure there?
A couple of examples from my web.config that I have to solve:
<add key="DataMapPath" value="d:\inetpub\MyWebApp\App_Data\map.xml"/>
<add key="CuteWebUI.AjaxUploader.TempDirectory" value="C:\Temp\WebApp\Attachments\UploaderTemp"/>
The first file tells our code to look for the map.xml-file in the App_Data-directory.
The last one tells our upload-controll where to upload files. I maybe should have used Azure Blob Storage here instead but that would need some major refactoring of our code.
Is there som best practices on this topic?
Our WebApp is running in production today, but I want to try out MS Azure. But I doesn't want to do to many code changes to make it work in Azure.
I have also read you can spin up an Virtual Machine (Windows Server) but that is overkill for my needs right now. We may go that way in the end, but for this testing-purpose it should be made simple.
Any suggestions on how this could be solved? Someone done this before? I guess someone has. Indeed.
If I do have read and write access to the file system for my Web Site I maybe could use this:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TheFolder");
This would be appropriate for both on-premise and Azure deployment. But then I have to do some changes in our code.
You have multiple options:
Option 1: Use the App Settings of your web app to set custom settings for your website.
Option 2: Create multiple versions of your web.config (Visual Studio supports this) and deploy different versions to Azure and your local machine
Option 3: Make your path's relative to the paths of Azure Web App's environment variables
There's a HOME environment variable in your Azure Web App that resolves to the equivalent of inetpub for your site. Your app data folder is located at %HOME%\site\wwwroot\AppData.
There's also a TEMP environment both on Azure Web Apps and on your local machine. You can make your second setting relative to the TEMP environment variable value.
Actually you won't have this kind of "control" using azure web sites. To keep your app as it is, use Azure Virtual Machines.

What are the limitations , if any , when hosting a WCF service on azure

I wrote a WCF service and I want to host it in azure. When I wrote the service , I didn't have in my mind that I am going to host it in azure.
Every application , even a WCF service , is using platform resources. When I say resource , I mean anything:
memory
CPU
File handle
Low level APIs (pinvoke)
Com objects.
sockets
.Net BCL API (Yep , I even consider this as a resource)
Databases
etc..etc.. (anything that is not the code i have written myself)
Hypothetical example : If the service , for example , logs to Drive 'H' , it may work on my computer(since I have drive 'H') , but it will probably won't work on the cloud. Same for Drive 'C' , or any drive letter , I don't even know how a file system is seen from the service perspective.
This is just one example.
Another hypothetical example : I can pinvoke from the service some winapi method in nt.dll , It will work on my computer. But i guess it won't work on the cloud.
My question is :
How can I know what kind of resources can be used on the cloud and how resources are used when writing to the cloud? What are the "rules" to follow? Also Is there any "Smart" Compiler that can ensure that my service is compatible with the cloud platform
I'll be glad to get any detailed explanation or a reference\book about this topic. I tried to find some info by googling but didn't find anything that cover it well enough.
Once i'll get the details i'll be able to make the nessecary porting to my service (if any needed at all).
The limitations depend on how you host your WCF Service:
Windows Azure Web Sites: This is a shared hosting model. If you deploy your WCF service in a web site you'll need to take that into account. This means you'll have limited access to disk, limited access to low level APIs, no way to use native libraries, ...
Windows Azure Web / Worker Roles (PAAS): Your application will be deployed in a Windows Server 2008 / 2012 VM. So if you want, you can leverage all functionalities you would use on a normal Virtual Machine (all "resources" you mention in your question). The only thing to keep in mind is that these virtual machines are non persisent (meaning all data you store on them could get lost) and that the load balancer is not sticky (could be an issue if you use WCF sessions). The fact that these machines are not persistent also means you cannot install a database server on them in a reliably way, but you can use an external database, like SQL Azure. The advantage of this solution is that the machines are maintained by the Fabric Controller, so you push your service package (the application) to Windows Azure, and the rest of the deployment is done for you.
Windows Azure Virtual Machines (IAAS): You get a machine like in Web / Worker Roles which allows you to use all "resources", but with even more control. The machines are persistent, meaning everything you store on them is persisted in Blob storage (if the machine crashes, you don't loose the data stored on the OS drive and data disks). This is the closest alternative to an on-premises deployment, but this also adds extra work. It will be up to you to manage deployments on all servers, to handle security updates, ... But in this case you could install your own database on a machine. Keep in mind that also here the load balancer is not sticky which could impact features like WCF session.
You can follow below mentioned Guidance for Using WCF in Windows Azure.
Deciding whether to run a WCF service in a web or worker role
WCF services can be hosted in either a web role or a worker role. Which type of role you decide to use depends on the type of WCF service you are writing
Running a WCF service in a web role
A WCF service that is set up for deployment to a Windows Azure web role uses the same setup and configuration as a WCF service hosted in IIS on on-premise servers.
Understanding WCF Security in Windows Azure
The security concerns for hosting a WCF service on Windows Azure is the same as those you encounter hosting the service in on-premise servers
Troubleshooting WCF in Windows Azure
You can troubleshoot performance issues for WCF services in Windows Azure using the same techniques that you use with WCF services hosted on-premise servers
For get more information check Guidance for Using WCF in Windows Azure Here
I hope this will help to you.

How to specify a port for the ASP.NET Configuration Site?

Is there any way to specify a permanent port for ASP.NET Configuration site (Web Site Administration Tool)?
I need to add a link to the ASP.NET Configuration site, but I can't due to the port changing each time it starts.
Its the port for ASP.NET Development server
http://msdn.microsoft.com/en-us/library/ms178109.aspx
I'm not sure that you can.
The Web Site Administration Tool isn't really meant to be "linked" to as such, it's a fairly powerful, unsecured application, that's only really meant to be run by a developer/admin.
The "Considerations" section of the documentation explain why:
The following sections provide some considerations for working with the Web Site Administration Tool.
Restarting the Application When Saving
Most changes to configuration settings that you make in the Web Site Administration Tool take effect immediately. This requires the Web site to which the change applies to be restarted. Because this will cause currently active sessions in the Web site to be lost, you should make configuration changes to a staged or development version of the Web site before publishing these changes to the production server.
Saving Your Settings
Most changes to configuration settings that you make in the Web Site Administration Tool take effect immediately. For settings for which the Web Site Administration Tool interface has a dedicated Save button, leaving the Web Site Administration Tool idle or allowing the Web Site Administration Tool to time out before you click Save will cause your configuration settings changes to be lost.
Time Out
As a security measure, the Web Site Administration Tool times out after a period of inactivity. Any settings that did not take effect immediately and were not saved will be lost. If the Web Site Administration Tool has timed out, close your browser, and then reopen the Web Site Administration Tool in a new window.
The Web Site Administration Tool manages only some of the configuration settings that are available to the Web site. Many other settings require direct modification of configuration files either manually, by using the MMC Snap-In for ASP.NET, or programmatically, by using the ASP.NET Configuration API.
From that you can see that this isn't something that's intended to be kept around.
That said, with a little bit of hacking around, you could probably shoot yourself in the foot achieve what you're after:
If you right click on the ASP.NET Development server task tray item for the admin tool, and select "Show Details", you can see that the virtual directory that the tool runs under is mapped to (something like):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\asp.netwebadminfiles\
If you were to create (and secure) a virtual directory on your application mapped to that path, you might well be able to get this all up and running as you want.
As pseudocoder points out in his comment below, while going down the Virtual Directory route does "work", there are some limitations to the tool that, coupled with the security issues mean that you probably wouldn't want to use it going forward.
If you were to stick with the Development Server option, the tool won't respond to non-local requests, and once you've deployed the site to a proper web server (IIS) for users to access the Admin site won't be running anyway.
It would probably be better if you could explain why you want to use this permanently so we can advise you on some better options - for example the Membership, Profile and Role providers both provide nice APIs for managing user details that can be easily built into a custom admin area.
Tricky one, however I think to get this working correctly, you're going to have to spend some time doing something, and it's probably better for you in the long run to spend that time doing the right thing rather than hacking in the wrong option.
The Development server can be started from a command line, using a commands along the lines of:
call "C:\Program Files\Microsoft Visual Studio 9.0\vc\vcvarsall.bat"
"C:\Program Files\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe" /port:3900 /path:"PATHSITE" /vpath:"PathSite"
The first line sets up the CMD instance to use the variables and path settings needed to run most of the Dev tooling
You'll want to change the path to the DevServer as appropriate for your environment (mine's in \10.0\ for example, and has a 2.0 and 4.0 version).
Armed with this information, you could do something along the lines of:
Add a link to your site to a page called /StartAdmin.aspx or similar.
In that page, you would then need to have the logic to:
Check through the running processes for the instance of the DevServer that was previously used to host the Admin site.
Close that process down.
Spool up another instance of the DevServer with a known port, pointing to the path for the WebAdmin Site.
Redirect the user to this new site.
All of which is possible, but it's not trivial, and you'll find you'll need to be doing odd things with the process your starting, and you'll need to be very careful you don't shut down the instance of the DevServer that's actually running your site by mistake.
However, this would probably take as long as it would to knock up a quick set of user admin screens, and you'd learn something more useful along the way*
* Which isn't to say that learning how to start and leave running a process isn't useful, it's more to say that I'm guessing its not what you're supposed to be learning at the moment, and you should probably be focusing on that ;)

Categories

Resources