Why would Azure Search Indexer stop working on a Live app - c#

I have a .Net/C# app that calls the Azure Search Service. It's been working fine to find a list of PDF files I have in Azure storage based on keywords submitted. But a couple of days ago, the live app on Azure stopped working - no documents are returned from a search. However, on Local, the app works fine with the same code. I'm suspecting something may have changed with firewall rules, but I can't find where that may have occurred. Hopefully someone has had something similar happen and has a solution.
Here's the code that stopped working on Live.
var indexClient = GetIndexClient(); // sets up SearchIndexClient with uri, credentials, etc.
SearchParameters sp =
new SearchParameters()
{
Select = new[] { "metadata_storage_name" },
SearchMode = SearchMode.Any
};
var docs = indexClient.Documents.Search(searchString, sp); // this line no longer works on Live

As it turns out, it had to do with Microsoft's TLS 1.1 and 1.0 decommissioning in the last 2 weeks. I was able to add the following to my code to make it work again (added to my page_load procedure in the default template):
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
However, I'm still working on an issue where the PDF links that are listed in an editor window (using CKEditor extension), will no longer work. I'm assuming this is the same problem, as it works on my local, but not from the Azure web app.

Related

ASP.NET Core 6 MVC app hosted on one server trying to access a remote Directory on another server throws 500.30 error

This bounty has ended. Answers to this question are eligible for a +50 reputation bounty. Bounty grace period ends in 22 hours.
whisk is looking for an answer from a reputable source.
I created an image uploading app for a client and they want to host it on its own IIS server. When I publish the app to the server I get the error
HTTP Error 500.30 - ASP.NET Core app failed to start
I have installed all the .NET v6 SDK, Runtime and hosting bundle that is needed to host the app.
After looking around on SO and google I was able to run the appNameHere.dll from the command prompt and it runs just fine without showing any errors. When I do that I can open it locally on the server and have the app show up. It's just when it's public facing I get the error.
I have narrowed it down to these few lines of code in the Program.cs file
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.GetFullPath("\\\\12.34.56.789\\c$\\ABC\\FolderName\\ProjectName\\Images\\ItemImages\\")),
RequestPath = new PathString("/ItemImages")
});
When I comment these out, the app shows up fine and works, but I can't get the files from the other site.
I can also set up a folder locally in the "C:\UnitImages" and everything works as well.
I created a shared connection to the main server to test the path as well and it works there too. So I'm a bit lost on where to go next.
Update
As stated in one of the links from #Code Maverick I have updated the Application Pool Identity to the user that has full access to the folders and I still get the Error that's stated above.
I came across this article and tried it but I'm getting an error 'NetworkConnection' is a namespace but is used like a type
repo for ref.
var sourceCredentials = new NetworkCredential { Domain = "12.34.56.789", UserName = "Administrator", Password = "123456" };
using (new NetworkConnection("\\\\12.34.56.789\\c$\\ABC\\FolderName\\ProjectName\\Images\\UnitImages\\", sourceCredentials))
{
// to serve static froms from \\network\shared location
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.GetFullPath("\\\\12.34.56.789\\c$\\ABC\\FolderName\\ProjectName\\Images\\UnitImages\\")),
RequestPath = new PathString("/UnitImages")
});
}
Based on this and this, you may need to provide IIS_IUSRS group the ability to write to the share.
You personally may be able to access the share, but your web application hosted within IIS needs the same access privilege. This does have security implications though.

Discord.NET Trying to get SocketUser as SocketGuildUser returning null

I am working on a C# Discord.Net bot, and have come across an issue I thought I had previously resolved.
I need to get the user mentioned in the message as a 'SocketGuildUser'. This works perfectly fine when I attempt it on my own user. However, it wasn't working on my friend's user. While it could get a 'SocketUnknownUser', it failed to get a 'SocketGuildUser', just returning null. After I removed a certain role from them, the bot worked completely fine for a couple of days. However, all of sudden, it has now stopped being able to get a 'SocketGuildUser' from my friend's user, with no changes to the relevant code.
Here is the relevant code:
var userToModCheck = message.MentionedUsers.ElementAt(0);
var userToMod = message.MentionedUsers.ElementAt(0) as SocketGuildUser;
userToModCheck returns the correct username and user ID, but as a SocketUnknownUser. userToMod returns null.
So far, I have tried:
Checking the bot 'Privileged Gateway Intents' permissions in the Discord developer portal
Using a separate function(Context.Guild.GetUser) to get the SocketGuildUser using the user ID
Changing roles
Restarting both computers
Searching the internet
Edit: There are no issues when the mentioned user is online and has the online status. Very strange.
Edit 2: Switching 'AlwaysDownloadUsers' to true does not resolve the issue.
'DiscordSocketConfig' wasn't configured properly. Firstly, make sure all 'Priveleged Gateway Intents' are enabled in the Discord Developer Portal. (Application > Bot).
Change 'AlwaysDownloadUsers' to true, and 'GatewayIntents' to all, then apply it to the client:
var config = new DiscordSocketConfig{ AlwaysDownloadUsers = true, GatewatIntents = GatewayIntents.All };
_client = new DiscordSocketClient{config};
The bot then works properly.

Blazor App: Container.ReadItemAsync fails to connect to Azure Database when AddAuthentication used

I'm using C# in Visual Studios to create a Blazor App to connect to an Azure Database. Bit new to Blazor/Azure but I managed to get it working and retrieve the data.
I was initially using IServiceCollection.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie()
This all works fine, I'm looking to use Azure's Active Directory to verify users, which seems to work on its own, but now when the code does:
await Container.ReadItemAsync
it doesn't return the ItemResponse (or anything at all).
I've tried Googling the issue, but I haven't found anything relevant. I assume that there is an issue connecting to the azure DB relating to permissions, but I can't work out how to change it. Being new to cloud development, I'm not versed in the lingo. :)
Thanks,
Please try this:
Instead of string use JObject to return value.
instead of:
ItemResponse<string> result = await container.ReadItemAsync<string>(documentDBStorageId, PartitionKey.None, iro);
use this code:
ItemResponse<JObject> result = await container.ReadItemAsync<JObject>(documentDBStorageId, PartitionKey.None, iro);
return result.Resource.ToString();

Google Cloud PubSub V1 using GCloud Emulator

I'm fighting with Google Docs for setting up Cloud PubSub with .NET using a PubSub emulator.
https://cloud.google.com/dotnet/docs/getting-started/using-pub-sub
https://cloud.google.com/pubsub/docs/publisher
https://cloud.google.com/pubsub/docs/emulator
Coming from a Rails background, I'm tasked to implement Cloud PubSub for a .NET product, running our google cloud on .NET Core, to enable it to publish.
Google::Cloud::Pubsub.new(project: project_id, emulator_host: emulator_host)
From the documentation using .NET, I keep coming back to the following:
PublisherServiceApiClient publisherClient = PublisherServiceApiClient.Create();
PublisherClient publisher = PublisherClient.Create(...)
However, the library used from the docs Google.Cloud.PubSub.V1 -Pre
does not contain the definition.
'PublisherClient' does not contain a definition for 'Create'.
Instead, I get CreateAsync that takes in TopicName, PublisherClient.ClientCreationSettings and PublisherClient.Settings.
https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/api/Google.Cloud.PubSub.V1.PublisherClient.html
I noticed that PublisherServiceApiClient can take in a Channel, but I'm confused on how to get this going.
To conclude with an actual question, how does one currently implement Cloud PubSub with .NET for in cloud and then locally with emulator? Adding to that, am I using the wrong library or the wrong docs?
Any suggestions, pointers or piece of advice would be truly appreciated.
I managed a solution that I am happy with.
Instead of using the PublisherClient, I went with using the PublisherServiceApiClient alone.
emulatorAddr = Environment.GetEnvironmentVariable("PUBSUB_EMULATOR_HOST");
if (emulatorAddr != null)
{
channel = new Channel(emulatorAddr, ChannelCredentials.Insecure);
pub = PublisherServiceApiClient.Create(channel);
}
else
{
pub = PublisherServiceApiClient.Create();
}
Which meant that publishing was slightly more involved then sending string to the PublisherClient, but overall not so bad.
PubsubMessage msg = new PubsubMessage
{
Data = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(payload))
};
pub.PublishAsync(topic, new[]{ msg });
If the project is running in a Google Compute Engine, it will have default credentials. Otherwise, wether you're running an emulator locally or in docker you can define PUBSUB_EMULATOR_HOST.
What really helped was this https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/index.html
To make the PublisherClient connect to a local emulator, you need to pass custom ServiceEndpoint and ChannelCredentials to CreateAsync:
var serviceEndpoint = new ServiceEndpoint(theEmulatorHost, theEmulatorPort);
var publisherClient = await PublisherClient.CreateAsync(
topicName,
new PublisherClient.ClientCreationSettings(credentials: ChannelCredentials.Insecure, serviceEndpoint: serviceEndpoint));
To switch to the real PubSub, just leave away the ClientCreationSettings.
You can use the EmulatorDetection property on the ClientCreationSettings using extension method .WithEmulatorDetection(EmulatorDetection.EmulatorOrProduction). Like this:
PublisherClient publisher = await PublisherClient.CreateAsync(
topicName,
new PublisherClient.ClientCreationSettings()
.WithEmulatorDetection(EmulatorDetection.EmulatorOrProduction));
This will work if you have the following environment variable for the local emulator endpoint: PUBSUB_EMULATOR_HOST=localhost:8085
(If you use Visual Studio you might have to restart VS for the environment variable to be detected)
In windows I had problems using the set PUBSUB_EMULATOR_HOST=localhost:8085 command, so I ended up adding it manually.
Details here: https://cloud.google.com/pubsub/docs/emulator
Extra tip: you can add topics directly to API using curl: curl -X PUT http://localhost:8085/v1/projects/my-project-name/topics/my-topic

CngKey.Import on azure

var rawData = Convert.FromBase64String(_signingKey);
var cng = CngKey.Import(rawData, CngKeyBlobFormat.Pkcs8PrivateBlob);
I use this code to extract key, from embedded base64 string.
It works fine when I test it locally but when I publish on azure I get following exception:
WindowsCryptographicException: The system cannot find the file specified
(once again I'm not reading from any file)
I need this to communicate with apple apns for push notifications, is there any workaround?
And this happens only on free service plan, if I switch to basic plan it's working.
I ran into the same error after publishing an existing application to Azure. In my case the problem was solved after I set WEBSITE_LOAD_USER_PROFILE = 1 in App Services / App Name / Application Settings.
Setting WEBSITE_LOAD_USER_PROFILE to equal 1 in the Azure App Service configuration definitely got my remote iOS notifications working. Using dotAPNS for C# .NET I also needed to omit apns.UseSandbox().
It seems that it causes by there is no certificate attached in your Azure Mobile App. If it is that case, we need to upload the "Development" or "Distribution" SSL certificate to the WebApp. More info about how to send push notifications to iOS App, please refer to the azure document.
I've had a similar error trying to construct a X509Certificate2 from a byte array - worked fine locally but once I deploy to Azure Web App, I got the same and VERY misleading file not found exception.
The real issue turned out to be that there was no user store associated with the web service account. You can also get a similar error if there are permission-related errors with accessing the certificate store on Windows.
In any case - In my scenario I fixed the problem by using MachineKeySet:
new X509Certificate2(certRawBytes, default(string), X509KeyStorageFlags.MachineKeySet);
So, in your scenario, try something like:
var keyParams = new CngKeyCreationParameters
{
KeyCreationOptions = CngKeyCreationOptions.MachineKey,
};
CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams);
Note: You may have to set a few parameters to get the above working. The Import method doesn't seem to support MachineKey - but you should be able to achieve similar outcome by using the Create method.
To add to #strohmsn's answer, you can also set the App Service settings with this value directly within Visual Studio on the Publish page for web apps: Right click on web app and select Publish, then select App Service Settings, and you can add setting properties there: WEBSITE_LOAD_USER_PROFILE = 1 in this case. See screenshot:
For making it works, I needed TWO things in AzureWebApp..
So my code is :
//I load the PrivateKey here
ReadedByte = System.IO.File.ReadAllBytes(strPathPrivateKey);
//create the RSA thing
RSA rsa = System.Security.Cryptography.RSA.Create();
//import the key. It crashed HERE with the 'System cannot find file specified'
rsa.ImportPkcs8PrivateKey(source: ReadedByte,bytesRead: out int _);
It works perfectly locally. But, to make it WORK on Azure Web App, I had to have those TWO requirements :
1 - the WEBSITE_LOAD_USER_PROFILE = 1 spoken in the discussion above and below
2 - The App Service Plan must include "Custom domains / SSL" !
...so No 'F1 Share Infrastructure' nor 'D1 Share Infrastructure'. The lowest Service plan that worked for me was 'B1 - 100 Total Acu'.
Maybe I have something wrong somewhere else in my code, or my 'RSA' choice is bad..anyway...
It now works!

Categories