Error: Twilio.Exceptions.AuthenticationException: 'Username can not be null' - c#

I'm trying to create a Twilio app in C#, I took the code on the official documentation. I installed all the packages that the doc ask, for and try to run the app, but the following message error appears:
Code:
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
TwilioClient.Init(
Environment.GetEnvironmentVariable("********"),
Environment.GetEnvironmentVariable("********")
);
var message = MessageResource.Create(
from: new PhoneNumber("whatsapp:********"),
to: new PhoneNumber("Whatsapp:********"),
body: "Test"
);
Console.WriteLine("Message SID: ", message.Sid);
Error:
Unhandled exception. Twilio.Exceptions.AuthenticationException: Username can not be null
at Twilio.TwilioClient.SetUsername(String username)
at Twilio.TwilioClient.Init(String username, String password)
at Program.<Main>$(String[] args) in
line 5
I tried to implement the code line that appears in the error message, but the error is still there
Code:
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
TwilioClient.Init(
Environment.GetEnvironmentVariable("*********"),
Environment.GetEnvironmentVariable("*********")
);
Twilio.TwilioClient.SetUsername(
username: "*********#gmail.com"
);
Twilio.TwilioClient.Init(
username: "*********#gmail.com",
password: "*********"
);
var message = MessageResource.Create(
from: new PhoneNumber("whatsapp:*********"),
to: new PhoneNumber("Whatsapp:*********"),
body: "Teste"
);
Console.WriteLine("Message SID: ", message.Sid);
Something important to mention is that I create and set my account on Twilio, so everything is all right
This happens when I debug:
Debug

Please try the following code snippet:
Set Twilio Account SID (String Identifiers at Twilio) as username twilio.com/docs/glossary/what-is-a-sid and
Set Twilio Auth Token as a password
var sid = "34digitSID";
var authToken = "authToken";
TwilioClient.Init(sid, authToken);
For security reasons we can save this in appsettings.json file in asp.net MVC and read it as follows:
var sid = Configuration.GetValue<string>("AppSettings:Twilio:AccountSID");
var authToken = Configuration.GetValue<string>("AppSettings:Twilio:AuthToken");
TwilioClient.Init(sid, authToken);

Twilio tutorials and samples will usually use environment variables, but you have to make sure you set the environment variables first.
This is to avoid hard coding sensitive information like Account SID and Auth Token, which could then be accidentally committed to source control.
You're currently passing null to the first parameter of TwilioClient.Init which is why the error occurs. The reason that you're passing null is that the environment variable you're trying to pull isn't configured yet.
If you're running your .NET project from the .NET CLI, before running the project, configure the environment variables like this:
If you're using a bash or bash-like shell (mac/linux/unix):
export TwilioAccountSid=[TWILIO_ACCOUNT_SID]
export TwilioAuthToken=[TWILIO_AUTH_TOKEN]
If you're using PowerShell:
export TwilioAccountSid=[TWILIO_ACCOUNT_SID]
export TwilioAuthToken=[TWILIO_AUTH_TOKEN]
If you're using CMD:
set "TwilioAccountSid=[TWILIO_ACCOUNT_SID]"
set "TwilioAuthToken=[TWILIO_AUTH_TOKEN]"
Once you close your shell, the environment variables are lost and you'll need to set them again next time.
If you're not running the project from the CLI, but from an IDE, the IDE may also let you configure environment variables, but depending on the IDE, it may be stored in a plain text file inside of your project, which introduces the same risk of accidentally putting it into source control and leaking the sensitive tokens.
You can also set environment on Windows, profile or system wide using their built-in UI.
Lastly, the samples use Environment Variables because they are universally available (on all OS's and infrastructure) and are the simplest way to safely get started, but .NET has a much better way of configuring applications.
Here's an article that will take you from using environment variables to the .NET Configuration Builder and some of its features.
PS, let us know how you're running your project, like what IDE, what shell, etc. and also what Operating System you're using, so we can provide more specific instructions.

Related

DefaultAzureCredetials can't authenticate via Visual Studio - Can't find AzureServiceAuth\tokenProvider.json

I'm attempting to connect to an Azure Key Vault instance from a .NET 4.7 application running locally under IIS and the debugger (Visual Studio 2022 17.4.4) but am encountering the below exception(s) from the Azure.Identity package when it attempts to retrieve a token to authenticate to Azure when calling to perform a KeyVault action such as GetSecretAsync().
DefaultAzureCredential failed to retrieve a token from the included
credentials. See the troubleshooting guide for more information.
https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot
ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.
Visual Studio Token provider can't be accessed at C:\WINDOWS\system32\config\systemprofile\AppData\Local.IdentityService\AzureServiceAuth\tokenprovider.json
I need to connect to the KeyVault instance via a User Assigned Managed Identity in cloud environments such as production, whereas in development environments, we therefore need to connect via the developer's Visual Studio account to authenticate them to access the service, similarly. Perhaps I have misunderstood, but I believed this is possible via the DefaultAzureCredential option, which will try various methods of authentication in order (such as environment variables, managed identities, then Visual Studio credentials, etc) until one succeeds.
When inspecting the inner exception(s) relating to the Visual Studio Credentials flow, I see the System.Exception {System.IO.DirectoryNotFoundException} exception message states...
"Could not find a part of the path 'C:\WINDOWS\system32\config\systemprofile\AppData\Local.IdentityService\AzureServiceAuth\tokenprovider.json'.
Previously, this message had stated the below message (which I understand to be the more recent location for this file), until I attempted to run under Visual Studio 2019 for comparison, at which point, it changed to the above message.
"Could not find a part of the path C:\Users[AppPoolName]\AppData\Local.IdentityService\AzureServiceAuth\tokenProvider.json".
At first, I noticed the path didn't exist from .IdentityService onward, and so followed the suggestion on this MSFT forum post to restore the AppAuthentification extension from VS2019 into VS2022's configuration to restore the C:\Users\<AppPoolName>\AppData\Local\.IdentityService\AzureServiceAuth\tokenprovider.json file and providers the TokenProviders as a path to C:\Program Files (x86)\Microsoft Visual Studio\<version>\Enterprise\Common7\IDE\Extensions\<random dir name>\TokenService\Microsoft.Asal.TokenService.exe. On the next build, I noticed .IdentityService had been created, but not the proceeding directory or file.
I then tried logging out and into Visual Studio a number of times, but this did not seem to create the remaining missing directory and file. Creating the directory and file manually of course resolve the System.IO.DirectoryNotFoundException, but the error message then informs me that the file schema is incorrect. I'm unable to find an example with the correct schema and values.
In terms of client configuration options, I've been explicitly limiting the modes of authentication flow to just ManagedIdentity and VisualStudioCredential for simplicity after noticing other methods (e.g. AzureCLI and Azure PowerShell Module` also failed, despite being logged in to them).
_client = new SecretClient(new Uri(options.KeyVaultUri), new DefaultAzureCredential(
new DefaultAzureCredentialOptions
{
ExcludeManagedIdentityCredential = false,
ExcludeVisualStudioCredential = false,
ExcludeInteractiveBrowserCredential = true,
ExcludeAzurePowerShellCredential = true,
ExcludeAzureCliCredential = true,
ExcludeEnvironmentCredential = true,
ExcludeVisualStudioCodeCredential = true,
ExcludeSharedTokenCacheCredential = true,
ManagedIdentityClientId = options.ManagementIdentityClientId
}
));
I've also tried the suggestions on Azure SDK GitHub Issue #4590 of settings setProfileEnvironment and loadUserProfile to true in case it's an IIS permissions issue, but this made no difference - the same errors continue.
Finally, the only other reference I've found to the tokenProvider.json file is in Microsoft's documentation for App Authentication, but the re-authenticate button doesn't exist in the Tools > Options > Azure Service Authentication window as suggested.
"If you run into problems using Visual Studio, such as errors that
involve the token provider file, carefully review the preceding steps.
You may need to reauthenticate your developer token. To do so, select
Tools > Options, and then select Azure Service Authentication. Look
for a Re-authenticate link under the selected account. Select it to
authenticate."
As I'm able to locate C:\Program Files (x86)\Microsoft Visual Studio\<version>\Enterprise\Common7\IDE\Extensions\<random dir name>\TokenService\Microsoft.Asal.TokenService.exe and its related configuration file, I suspect it's the missing tokenProvider.json file that's the issue, but I'm not aware of what is responsible for creating that, nor what it should contain.
Any insight or pointers would be appreciated.
Notable packages and their versions in use:
Azure.Identity # v1.8.0
Azure.Security.KeyVault.Secrets # v4.4.0
Edit (1)
As one might expect, I'm able to configure an alternative flow to work by granting an RBAC record upon the Key Vault for an Azure AD Application Registration and then using the ClientSecretCredential flow in place of the DefaultAzureCredentials flow (as below). But this doesn't solve the problem in the best way so I'd be interested if anyone can spot where I'm going wrong with the DefaultAzureCredentials flow, if at all.
_client = new SecretClient(new Uri(options.KeyVaultUri),
new ClientSecretCredential(options.TenantId, options.ClientId, options.Secret)
);
Having found this question on SO, I found that tokenProvider.json existed in the same directory under C:\Users\<local user account> (via %LOCALAPPDATA%.IdentityService\AzureServiceAuth\) and was able to analyse it for reference and duplicate it to the IIS.
As suggested by Johnny5, it seems VisualStudioCredentials executes as the signed-in domain user, but IIS is running as the ApplicationPoolIdentity, hence it doesn't access the file under the domain user location and doesn't create one as it's not signed into Visual Studio. After a little research on how to alter this, I was able to set the IIS Application Pool identity as my domain user which matched the signed-in Visual Studio account.
To do this, follow these steps
Open IIS Manager > Go to Application Pools
Right-click the relevant pool, then click Advanced Settings...
Click the 3-dot button next to the Identity settings (likely ApplicationPoolIdentity)
Select Custom Account and enter your credentials (including any domain prefix - e.g. DOMAIN\MyUser)
If you aren't sure of your domain, open a command prompt and enter echo %USERDOMAIN% to find it.
I then set the SecretClient authentication flow back to utilise DefaultAzureCredential like so, re-tested locally, and success - secrets retrieved.
_client = new SecretClient(new Uri(options.KeyVaultUri), new DefaultAzureCredential(
new DefaultAzureCredentialOptions()
{
ExcludeEnvironmentCredential = true,
ExcludeVisualStudioCodeCredential = true,
ExcludeAzureCliCredential = true,
ExcludeAzurePowerShellCredential = true,
ExcludeSharedTokenCacheCredential = true,
ExcludeInteractiveBrowserCredential = true,
ExcludeManagedIdentityCredential = false,
ExcludeVisualStudioCredential = false,
ManagedIdentityClientId = options.ManagementIdentityClientId,
}));

firebase: google environment variable not found on mac

i am trying to connect to the google firestore. i was able to connect, giving me key.json file as param:
FirestoreDb db = new FirestoreDbBuilder { ProjectId = "interiorcircle", CredentialsPath = "/Users/juliustolksdorf/Projects/Interior_Circle/keys/interiorcircle-4f70f209e160.json" }.Build()
But i heard its more common to do this via env variable. I tried setting it up wth terminal in .zshenv and also in .bash_profile (both).
Then i also went into terminal and set the variable.
Now, when I set "env" into terminal I am getting this line:
So it does look like the file is set correctly. But when I try to run my application with:
var credential = GoogleCredential.GetApplicationDefault();
(which is the recommended way)
my debugger hangs for about 5 minutes until it thorws an exception:
One or more errors occurred. (The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.)
So what am I doing wrong here? Im stuck at this for hours now.
EDIT:
I am working with xamarin.forms application. I set the variable in terminal from mac OS, not in console of xamarin.
I tried:
var x = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
But im being returned "null"

Error accessing Azure Storage using DefaultAzureCredential

I have been using c# code to get blob items for the past few days, however, with no changes to the way the program gets the blob data, it stopped working. I run into the same error every time I run now:
"EnvironmentCredential authentication unavailable. Environment variables are not fully configured"
Here is the code I am using to connect to Azure:
Uri accountUri = new Uri(mystorageurl);
BlobServiceClient client = new BlobServiceClient(accountUri, new DefaultAzureCredential(true));
BlobContainerClient container = client.GetBlobContainerClient(blobname);
BlobClient bundle = container.GetBlobClient(itemname);
What I've been confused by is that if I run this same code in a separate vs solution, I get no error getting the files from Azure. I've also tried sending the same solution that's getting the error to another person and they were able to run it without issue. I know it isn't an issue with environment variables, since it used to work up until now and they haven't been modified in any way.
This unresolved issue on github is most similar to what I've encountered:
https://github.com/Azure/azure-sdk-for-net/issues/16079
It worked fine when you never set Environment variables, it means that you didn't use EnvironmentCredential. The DefaultAzureCredential will attempt to authenticate via the following mechanisms in order, and Environment is the first one.
If you just use Environment to authenticate, it's better to use EnvironmentCredential instead of DefaultAzureCredential. And it's necessary to set the following variables.
AZURE_CLIENT_ID: id of an Azure Active Directory application
AZURE_TENANT_ID: id of the application's Azure Active Directory tenant
AZURE_CLIENT_SECRET: one of the application's client secrets

Azure Function fails to find file

I have an azure function that uses the Azure context. When I execute my function from visual studio 2019 on my machine, it executes correctly. However when I publish this to my Azure account, I get an error that the my.azureauth file cannot be found.
Could not find file 'D:\Program Files (x86)\SiteExtensions\Functions\2.0.12950\32bit\my.azureauth'
The code that is used:
var authFilePath = "my.azureauth";
Console.WriteLine($"Authenticating with Azure using credentials in file at {authFilePath}");
azure = Azure.Authenticate(authFilePath).WithDefaultSubscription();
sub = azure.GetCurrentSubscription();
Console.WriteLine($"Authenticated with subscription '{sub.DisplayName}' (ID: {sub.SubscriptionId})");
This is code that I found on one of the Microsoft tutorials. I have set my my.azureauth file to "Copy Always".
Could anyone point my in the right direction?
You are get this file path because the Directory.GetCurrentDirectory() would return D:\Program Files (x86)\SiteExtensions\Functions\2.0.12950\32bit instead of D:\home\site\wwwroot\ or D:\home\site\wwwroot\FunctionName.
And if you want to get the wwwroot folder or the function app directory you should use ExecutionContext. Further more information you could refer to this wiki doc.
So the right file path should be context.FunctionDirectory+"\my.azureauth" or context.FunctionAppDirectory+"\my.azureauth", which one to use depends on where your file is stored.
I have found that Kudu is extremely useful in seeing what has been deployed to Azure.
Navigate to your function in the Azure portal.
The instructions here will help get to the kudu console.
https://www.gslab.com/blogs/kudu-azure-web-app
From there you can browse the files which have been deployed into your function's file system.
If you add " , ExecutionContext context)" at the end of the function's run entry point, you can then get the folder which your function is running from with "var path = context.FunctionAppDirectory;
PS apologies for any formatting I am editing this on my phone.
Welcome to Stackoverflow.
Firstly, I'd recommend strongly against using file-based authentication as shown in your question.
From notes:
Note, file-based authentication is an experimental feature that may or may not be available in later releases. The file format it relies on is subject to change as well.
Instead, I would personally store the connection string details (AzureCredentials) in the config file (Web/SiteSettings) and use the provided constructor...
Again, the below are taken from the documentation notes:
Similarly to the file-based approach, this method requires a service principal registration, but instead of storing the credentials in a local file, the required inputs can be supplied directly via an instance of the AzureCredentials class:
var creds = new AzureCredentialsFactory().FromServicePrincipal(client, key, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);
or
var creds = new AzureCredentialsFactory().FromServicePrincipal(client, pfxCertificatePath, password, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);
where client, tenant, subscriptionId, and key or pfxCertificatePath and password are strings with the required pieces of information about your service principal and subscription. The last parameter, AzureEnvironment.AzureGlobalCloud represents the Azure worldwide public cloud. You can use a different value out of the currently supported alternatives in the AzureEnvironment enum.
The first example is most likely the one you should be looking at.
The notes I got this information from can be accessed here.
If you have some problems with AAD, these screenshots may help you.
Client ID:
Key:
Please note that the Key value can only be copied when it is created, after which it will be hidden.
Hope this helps you get started with AAD quickly.

Firestore C#: Missing or insufficient permissions

I am currently exploring Firebase's Cloud Firestore in C# and has encountered with the error which I could not resolve after searching SO. It seems that the resources for Firestore in C# is quite limited:
"Status(StatusCode=PermissionDenied, Detail=\"Missing or insufficient permissions.\")"
My code so far:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "FirebaseCsharpTest.json");
string project = "MyProjectId";
FirestoreDb db = FirestoreDb.Create(project);
Console.WriteLine("Created Cloud Firestore client with project ID: {0}", project);
AddPerson(db).GetAwaiter().GetResult();
}
public static async Task AddPerson(FirestoreDb db)
{
CollectionReference collection = db.Collection("users");
DocumentReference document = await collection.AddAsync(new
{
Name = new
{ First = "Ada", Last = "Lovelace" },
Born = 1815
});
}
}
I have checked on my Firebase console that the Firestore security rules are set to public (as of now, for testing sake). I have also ensured that the authentication json file is the right file generated from Google Developer Console as suggested in this post.
Is there something I'm missing?
EDIT:
My permissions on google cloud console:
Do check the projectID that you have been adding.
ProjectID is supposed to be the one that is specified in your json file.
This is a Cloud IAM issue and not a security rule issues. The C# server client library creates a privileged server environment that doesn't take into account Cloud Firestore security rules.. It seems that either your key file's service account doesn't have the correct IAM role or your code is not finding your keyfile.
Try using the full path to your keyfile instead of the relative path.
You can also try setting up a new service account and key file as described here.
Also, make sure you are changing the project variable:
string project = "NewFirebaseCsharpTest";
FirestoreDb db = FirestoreDb.Create(project);
Change the string project to the Id of the project and not the name of the project. The Id will probably start with the name and have a numeric suffix.
If that fails, go to the Log Explorer and query the logs. You will see an error that explains why your permission was denied.
You're never going to get enough information from the client-side for security reasons. Google isn't going to tell someone trying to gain access to something they shouldn't have access to what is going wrong. But, an admin can view the logs on the other side which will log all the information.

Categories