Azure Key Vault configuration issue when deploying a .Net Core 6 Worker App as a Windows Service - windows-services

I have a Net Core 6 worker app which I am deloying as a Windows Service. My App uses Azure Key Vault which works OK during development, but once I publish the app and try to run it from a Windows Service, the service fails to start unless the service is configured to Log on using a specific Windows user account with saved credentials.
I've been following the MS Docs https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service
The MS docs example doesn't seem to use a particular account to run the service, they use the local system account instead. This was evident from the fact that the example powershell commands in the docs used for creating the service, doesn't refer to any specific Windows user account.
After a while of head scratching, I eventually realised this issue has something to do with the fact it's unable to locate the certificate I installed in Windows that's used for connecting with Azure KeyVault.
When realising this, I modified the X509Store location in Net Core to use the LocaLMachine store instead of the CurrentUser store. I then re-installed the certificate into that new store location and tried again, but the Windows Service still doesnt start.
The code sample below does work OK if the app uses the CurrentUser cert store but I'm trying to figure out a way that I can deploy the app and have Windows Service start the service using the Local System Account:
IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
// See https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service
options.ServiceName = "My Service Name";
})
.ConfigureServices(services =>
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
// Add my services here...
})
.ConfigureAppConfiguration((context, config) => // Azure KeyVault Configuration
{
if (context.HostingEnvironment.IsDevelopment() | context.HostingEnvironment.IsProduction())
{
// See https://learn.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-6.0
// See https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/security/key-vault-configuration/samples/3.x/SampleApp/Startup.cs
var root = config.Build();
using var x509Store = new X509Store(StoreLocation.LocalMachine); // *WONT WORK USING LOCALMACHINE* only CurrentUser
x509Store.Open(OpenFlags.ReadOnly);
var x509Certificate = x509Store.Certificates
.Find(
X509FindType.FindByThumbprint,
root["AzureADCertThumbprint"],
validOnly: false)
.OfType<X509Certificate2>()
.Single();
config.AddAzureKeyVault(
new Uri($"https://{root["KeyVaultName"]}.vault.azure.net/"),
new ClientCertificateCredential(
root["AzureADDirectoryId"],
root["AzureADApplicationId"],
x509Certificate));
}
})
.Build();
So when starting up the service by having the configuraton set to search the cetificate store using LocalMachine, I get the following errors shown below:
On which line 87 refers to an issue encountered with the X609Store
It's a little odd though the fact that the error message is referring to the code from the project location on my Google Drive, despite the fact that the published project directory is actually stored on the root of C Drive. I use my G Drive for storing all my VS projects but the actual production test deployment was pubslished and copied to my C Drive. But the second error message of the two shown in Windows event viewer does in fact point to the correct location of the published project on C Drive. The first error message is talking about the .NET Runtime, not sure why its resolving this from my project folder location when considering I deloyed/published the app as a self contained one which to me should mean it's using its own self contained runtime instance for .NET
Anyhow, I only have this issue once I set the X509Store to "StoreLocation.LocalMachine", as soon as I change it back to "StoreLocation.CurrentUser" then everything works OK. I had also checked that I have the certificate installed in both the current user & local machine cert stores correctly, placed in the store as shown below:

I was struggling with the same issue last 2 days and finally it worked after placing my certificate in Local Computer/ Personal store.

Related

ASP.NET web app loads as local user instead of Azure AD login

I'm trying to migrate from local NLTM authentication to Azure AD login for an on premise app. I have set up the connected service, but everytime the SignIn method is called:
The request is already authenticated and it's using my local PC name, so the O365 log in is never triggered. Debugging doesn't help as the User info and Request don't seem to exist outside of the AccountController. Does anyone know what is going on and how I can get it to load up the login instead?
If anyone else finds this, check and triple check your web config and project files for any lingering windows authentication variables. Failing that try creating a new project with authentication and then copy the content of the old project across bit by bit. It turned out for me to be something dodgy in the project, but even using a comparison tool afterwards showed no discernible differences.
Only thing I can think of is that the Authentication with Azure Active Directory Connected Services made changes that broke something, but using the auth option during project creation did it properly.

azure file share access via web application

C# ASP.NET MVC web application - I followed all the steps from https://blogs.iis.net/davidso/azurefile in order to be able to access my Azure location by unc.
My newly created local user is in the IISUSER Group and has the same username and pwd (storage key).
I then created an application in my website using a new APP Pool (integrated) w/said local user.
I ran the caspol command as well.
The issue I run into is when trying to do a file.SaveAs, I get an error
Incorrect username or password
Server.MapPath({application}) returns the correct unc path but doing a Directory.Exists won't locate the path.
When viewing the "connect as" with specified user in IIS I get no issues, additionally I can access the unc path directly from my local machine with same creds.
I tried going to the app pool of the application and set the user directly but no change there. Are there changes I need to make on the Website configuration that the application sits in? Prior to converting this to an application I initially had it configured as a virtual directory and got the same error.
Set the load user profile to "True" in the application pool:
try to set the azure user in iis anonymous authentication by clicking on the edit:

Can't read a usb token (certificate) when the application is called by a service

I have two systems, one is an ERP and the other is a POS application, and i have a customer which uses an usb token to assign some files. I have two scenarios:
When i use the ERP to assign a file, he calls a application which is made just for do it, its called DFe and it works well, he finds the certificate.
In my POS, to do the same operation, it calls general service application who menages all our system, and this service call DFe, but when DFe is called from my general service, it doesn't find mine certificate, Windows returns the error "key set is not defined". I already did my service logon with user's credentials, but it didn't worked
Why my application doesn't find the certificate in this second scenario?
PS: The system is Windows 7
I solved the problem moving the certificate from local user to computer local on mmc.exe, I set the service to run on local computer and it works

Excel 2010 interop issues

Right, this is driving me insane. This works fine locally with Excel 2013, but when the website is published to a remote server with Excel 2010 it fails. From what I can see the DCOM configuration is the same locally as remote.
After fighting with Excel 2010 and DCOM permissions for over an hour now the best I have got is this exception: System.Runtime.InteropServices.COMException (0x80070BBC): Office has detected a problem with this file. To help protect your computer this file cannot be opened.
This is the result of a web application trying to open a *.xls file from a location it has just uploaded to. The application pool is running under ApplicationPoolIdentity and I have set the permissions for this specific app pool under mmc -32 on Launch and Activation Permissions so there's no problem running Excel. What I think I'm facing here is protected mode issues as the file is definitely not corrupt.
I've gone into Excel and Trust Centre settings and have added the location where the *.xls file is uploaded to (and subsequently opened) as a trusted location. If I open the file on the hosting server (under my domain account) I don't get the protected view block on the file - however, the Identity on the DCOM configuration is set to the launching user. So, what does this mean from the following (or something I haven't listed):
I need to add this location as trusted at a group policy level because the account launching the actual application doesn't have this configuration in its profile?
I need to create an actual account on the server and use this account as the Identity for running the application?
... ?
Just to clarify I've already been down the DCOM Security config route and RIDICULOUS issues with C:\Windows\System32\config\systemprofile\Desktop and C:\Windows\SysWOW64\config\systemprofile\Desktop. The configuration is:
.NET 4.5 (classic pipeline) app pool running under ApplicationPoolIdentity
DCOM Config > Security > Launch and Activation Permissions all set for this specific identity (Access Permissions and Configuration Permissions all set to Use Default)
File is uploaded correctly and appears in destination, opening on the server itself (under my domain account) respects the Trusted Location and doesn't give protected mode warning
Process to parse fails with the above exception.
Here is a screenshot of the Interop assembly I'm using if this is pertinent.
Ok... for anyone stumbling on this issue I have bitten the bullet and had to do the following:
Create a local account (AutomatedOffice in my instance) and set DCOM config to run Excel under this account
Log in as above account and change Excel settings to add folder in application root to trusted location and disable protected mode messages
Allow "Network Service" to invoke DCOM processes locally (through server DCOM config and not CLSID config)
Add NTFS permissions for this account on C:\Windows[System32|SYSWOW64]\config\systemprofile\Desktop paths
What was weird, after creating the account I was getting the following exception Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. which was resolved by adding HOST\Users and HOST\NetworkServices group to DCOM security (local only!!!) settings.
You need to add in trust center, security locations the folder where your website is published, for examplo if your website reads a file from c:\temporal\ you must put on excel, security locations that folder name

Unauthorized when query.get() in Parse .NET SDK in worker role.

ParseClient.Initialize("id", "key");
//get the publish instance.
string publishInstanceId = msg.Split(':')[1];
var getPublishQuery = ParseObject.GetQuery("PublishInstance");
getPublishQuery.GetAsync(publishInstanceId).Wait(); //Exception raised here - System.AggregateException - Unauthorized.
My App ID and Keys are valid and I've checked it thrice. I have also used Master Key, CLient Key as well as .NET key. None of them work.
This code runs in a worker role in Windows Azure Cloud Services.
Im using 1.2.16 version of PArse .NET SDK.
Is your PublishInstance set to allow anonymous access? From the looks of the above you're not logging in, so you could be getting that error due to permissions.
Personally I would suggest creating a service account and logging in using that so you can lock your permissions down.

Resources