Configure SignalR with AppCmd.exe on Azure web app - signalr

Can you give more details of how you ran AppCmd in Azure web app with SignalR as it requires admin rights? I don't think below will work for this reason.
protected void Application_Start()
try
{
var windowsDir = Environment.GetEnvironmentVariable("windir");
var command = System.IO.Path.Combine(windowsDir, #"System32\inetsrv\appcmd.exe set config / section:system.webserver / serverRuntime / appConcurrentRequestLimit:10000");
Process.Start(command);
}
catch (Exception ex)
{
Trace.WriteLine(ex.GetBaseException().Message);
}
}

Azure web app runs in sandbox. We have no permission to write system drive.
System drive access
Applications can read the system drive as controlled by ACLs on the drive. Applications cannot write to any location on the system drive, as implemented in the sandbox (i.e. even if ACLs allowed writing to a location on system drive, the sandbox would restrict it).
However if you choose Azure cloud service, we can use appcmd.exe in startup task. Of course, it will work like a charm if choose Azure VM as web server.

Related

Automatic Windows Authentication over IIS, ASP.NET 5 and Microsoft SQL Server

There is a lot of relevant Info, I hope I won't forget anything. We want an automatic Windowslogin into an intranet website in our domain.
For testing on a client I'm using a chrome browser that has the website whitelisted.
The Server runs IIS Version 10.0.19041 running a ASP.NET 5 website. It connects to a database MS SQL Server in the same domain.
The Connection String has the parameter Integrated Security=SSPI and works with Apps running locally on clients.
This is what is happening for now: Normally the website would ask for credentials, but since it's in the white list I assume it now uses the Windows credentials, how it's explained here https://stackoverflow.com/a/24875309/15631999
using (SqlConnection Verbindung = new SqlConnection(sqlConnectString))
{
Verbindung.Open();
the "Login failed for user" error is thrown, because it tries to connect with the active webserver user, not with the automatically logged in client. System.Security.Principal.WindowsIdentity.GetCurrent().Name returns the account identity in the AppPool.
What we did: (might not all be relevant ...)
We googled a lot the last couple of days to find out what to do. The general keywords seem to be Windows Authentication, maybe impersonation, NTLM.
So we added the Authentication to the ConfigureServices. Now it looks like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters();
services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.Ntlm);
services.AddSession();
services.AddAuthorization(options =>
{
options.AddPolicy("AuthorizationMode", (policy) =>
{
//unauthenticated
policy.RequireAssertion((e) => true);
});
});
//services.AddMvc();
services.AddHttpContextAccessor();
}
We also tried it with IISDefaults.AuthenticationScheme and without Authorization.
Configure Function snippet:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
SessionOptions s = new SessionOptions();
s.IdleTimeout = System.TimeSpan.FromMinutes(30);
s.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
s.Cookie.Name = ".acclaro.de.Session";
s.Cookie.IsEssential = true;
app.UseSession(s);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
(...)
In IIS/Sites/[Website]/Authentication we disabled Anonymous Authentication and enabled Windows Authentication. This means, I think, I don't have to edit the web.config.
We tried it both with Impersonation enabled and disabled. Basic Authentication seem to always ask for Username and PW. So this is not what we want.
We read that I have to change the order of the Providers. Putting Negotiate under NTLM, or downright deleting it doesn't change anything.
I also read that I have to add SPNs. So I executed setspn -a http/[url] [domain controller computer name] at our domain controller.
I don't know what I'm missing. Maybe I just haven't tried the right combination yet. If anyone can help, that would be appreciated. ( Also I hope impersonating other users won't produce problems, when I write in a local temp folder on the Server. I had some Access denied Exceptions in the past. )
If some relevant info is missing, please tell me.
It's a common misconception that Windows Authentication implies Impersonation. When a user authenticates to a server with Windows Integrated auth, the code on the server doesn't automatically start running as that user.
The normal configuration for an Enterprise web app is for IIS to user Windows Auth to authenticate the users, but to connect to SQL Server using the IIS App Pool Identity.
If you want the users to connect as themselves to SQL Server through the web application, that's called "Impersonation" and you need to enable and configure it. There's a SO question here that shows how to perform impersonation in your middleware. But additional confgiuration, like Kerberos Constrained Delegation configuration may be required.
The downsides of doing this are
It's extra work to configure, and you may need your network admins to help.
If users can connect directly to the database through the app, they can do it through other tools too. So security administration is harder, and riskier.
Users can't reuse connections, so you'll have lots of idle connections.

Error is only thrown when web app is deployed

My ASP.NET web app takes an image file and uploads it to Azure storage as a BLOB. It works fine when ran locally in both debug & release mode. The problem occurs when the app is deployed through its Azure web app. Unfortunately, because I cannot get the stack trace I can't quite figure out what's causing the issue but the only thing I can think of is the Azure storage is blocking it for security reasons, but it's set to allow calls from Azure services so I thought it would allow it.
Here's the function that the site calls to upload the image. This is the only function that's called from the action so it has to be throwing an exception here.
public async Task<bool> UploadFile(IFormFile file, string fileName, Vendor vendor)
{
string storageConnectionString = _config.GetConnectionString("Storage");
CloudStorageAccount storage = CloudStorageAccount.Parse(storageConnectionString);
CloudBlobClient blobClient = storage.CreateCloudBlobClient();
string nameFormatted = vendor.Name.Replace(" ", "").ToLower();
var container = blobClient.GetContainerReference(nameFormatted);
await container.CreateIfNotExistsAsync();
using (var stream = file.OpenReadStream())
{
var blobRef = container.GetBlockBlobReference(fileName);
await blobRef.UploadFromStreamAsync(stream);
}
return true;
}
And here's the error that is thrown when deployed.
Although I could not see any obvious issue in your code, actually you can remote debug your application on Azure WebApp by Visual Studio.
There are three offical blogs introduce how to remote debugging on Azure WebApp.
Introduction to Remote Debugging on Azure Web Sites
Remote debug your Azure App Service Web App
Troubleshoot an app in Azure App Service using Visual Studio
You just need to follow the figure below to enable the Debugging feature of your App Service on Azure portal, then you can follow the blogs above to do it.
Hope it helps.

Write permission for folder on a remote server

I'm hosting a web site at localhost and need to upload image file to another server named ImageServer with the FileUploadControl.
if (FileUploadControl.HasFile)
{
try
{
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(#"\\ImageServer\" + filename);
}
catch (Exception ex)
{
throw;
}
}
But i hit this permission error as soon as i try to submit an image.
Exception Details: System.UnauthorizedAccessException: Access to the path '\ImageServer\xxx.jpg' is denied.
ASP.NET is not authorized to access the requested resource. Consider
granting access rights to the resource to the ASP.NET request
identity. ASP.NET has a base process identity (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if
the application is not impersonating. If the application is
impersonating via , the identity will be
the anonymous user (typically IUSR_MACHINENAME) or the authenticated
request user. To grant ASP.NET access to a file, right-click the file
in Explorer, choose "Properties" and select the Security tab. Click
"Add" to add the appropriate user or group. Highlight the ASP.NET
account, and check the boxes for the desired access.
I looked into the folder security tab, and Network Service, IUSR, IIS AppPool\Image, and Everyone are granted full control. What else could be missing? I'm not sure what permission should i give to the image folder on ImageServer to let my localhost writing files to them.
P/S: Both server using IIS 7.5
Manually copy files to \\ImageServer\ via windows explorer works though
The main trick is to create a virtual dir which points at \\ImageServer\.
I found an article here. Although is about IIS 6 I think it won't be a problem to work on IIS 7 also.

How to run external exe under specific account from asp.net web service?

Bellow is my code from asp.net service which is trying to run some external exe. It works fine from my Visual Studio on win 7, but fails on my server (server 2008).
Myapp.exe reports back eror that account under which is runned doesn't have sufficiet priviliges.
List<ProcInfo> allProcesses = new List<ProcInfo>();
ProcessStartInfo pInfo = new ProcessStartInfo();
pInfo.FileName = binPath + #"\myApp.exe";
pInfo.WindowStyle = ProcessWindowStyle.Hidden;
pInfo.CreateNoWindow = true;
pInfo.UseShellExecute = false;
pInfo.RedirectStandardOutput = true;
string exitMsg = "";
int exitCode = 1;
try
{
using (Process proc = Process.Start(pInfo))
{
exitMsg = proc.StandardOutput.ReadToEnd();
proc.WaitForExit(1000);
exitCode = proc.ExitCode;
}
}
Resource pool on the server runs under account with sufficient priviliges and I also tried to use same account in code to start service with those same credentials and still nothing.
I have been told that account under which asp.net worker thread runs impose some additional limitations. So even if resource pool runs under appropriate account, you still won't have sufficient priviligies.
I also found something about using pInvoke and win32 api calls as the only way to run external code from asp.net service. But I don't have any win32 api knowlege nor did I found exples of this.
I would be very grateful for any tip/example how to run external exe under specified account from asp.net service.
If the account the worker process is runnning under lacks sufficient privelages then you have a few options.
You can either use impersonation in your code:
WindowsIdentity.Impersonate Method
Or configure IIS to run the application under a user account with the required privileges.
Here is an article which explains different methods of impersonation security:
Understanding ASP.NET Impersonation Security
If you do not feel confident implementing the user impersonation code yourself, here is a link to a codeproject article:
A small C# Class for impersonating a User

Webservices help

We have a web service running on the server. We want to use the service in local machine. Could some one kindly give all the steps to get the methods availble in the client.
We have created web methods in the server. And trying to access the same thing on the client. I can literally access those methods using the refernce variable of the server. but when I try to run it , it comes up with run time exception unable to connect to remote server.
I have added the web reference to my client class. What else I am missing. Do I need to do any kind of registration of service with client from command prompt.
I am assuming the client is unable to connect to server because the server is not running when I try to access the methods.
Any one with guidance will be helpful.
Thank you
Hari Gillala
I have added web refernce to this below client class using http://ipaddressofwerver/decisionclass/decisionclass.svc
The code:
try
{
DecisionClass ds = new DecisionClass();
string s = ds.Url;
Label1.Text = s;
string [] a = ds.GetList();
foreach (string i in a)
{
Response.Write(i);
}
}
catch (Exception Ex)
{
Response.Write(Ex.Message);
}
I am assuming the client is unable to connect to server because the server is not running when I try to access the methods.
If it's not running, it won't generate a WSDL either. However, it may have been running while you created the web reference, and then stopped.
Here are some things you can try to track down the problem:
Open the web service's URL, as specified in the web reference, in a regular web browser. This should bring up the web service's documentation page, and if you're running locally and haven't changed the web service's web.config, you can even call some simple methods using the provided test forms
See if you can access the web service with SoapUI or a similar tool.
Also, make sure you're running the web service in IIS, not in the Visual Studio development server - IIS will keep running when you close the project or even Visual Studio, but the development server might not.

Resources