Keyword not supported: 'authentication' error for azure integrated connection - azure

Getting Keyword not supported: 'authentication' error while trying to connect an azure DB through 'Active Directory Integrated' option in .NET core 2.1 project.
Note: I am using EF core to connect the Data source.

TL;DR
As called out by #Aamir Mulla in the comments, this has officially been added since Version 2.0.0
UPDATE - 16/08/2019
Active Directory Password Authentication has now been added for .NET Core in Microsoft.Data.SqlClient 1.0.19221.1-Preview
Unfortunately, the authentication keyword is not yet fully supported in .NET Core. Here is an issue which discusses this.
But .NET Core 2.2 has added some support for this use case as mentioned in this comment. The basic idea is to get the access token by any means (ADAL, REST, etc.) and set SqlConnection.AccessToken to it.
As for using this with EF Core, there's a good discussion about this in this github issue and in particular the comment by mgolois provides a simple implementation to the solution that cbriaball mentions in the thread.
Here is the same for reference
Note that this sample is using the Microsoft.Azure.Services.AppAuthentication library
// DB Context Class
public class SampleDbContext : DbContext
{
public SampleDbContext(DbContextOptions<TeamsDbContext> options) : base(options)
{
var conn = (System.Data.SqlClient.SqlConnection)this.Database.GetDbConnection();
conn.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;
}
}
// Startup.cs
services.AddDbContext<SampleDbContext>(options =>
{
options.UseSqlServer(<Connection String>);
});
The connection string would be something like this
Server=tcp:<server_name>.database.windows.net,1433;Database=<db_name>;

If you're still having the issue, make sure you have
Microsoft.Data.SqlClient package installed, not System.Data.SqlClient. They both contain SqlConnection class, switching the package for the first one fixed the issue for me.

As of today 7/18/2022 , I am still getting the issue from Azure when trying to use it through ManagedIdentity.
The microsoft doc at https://learn.microsoft.com/en-us/azure/app-service/tutorial-connect-msi-sql-database?tabs=windowsclient%2Cefcore%2Cdotnetcore
to use managed identity we need to use the connection string in this format!
"Server=tcp:.database.windows.net;Authentication=Active Directory Default; Database=;"
But looks like Azure is not liking it!
However, adding the access token helped!
var connectionString =
"Server=tcp:yourazuresqlservername.database.windows.net; Database=yourazuresqldbname;";
var con = new SqlConnection(connectionString);
//And then
con.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;
con.Open();
//Do sql tasks
con.Close();

Related

How to get a TokenCredential from a ServiceClientCredential object?

In my application, we presently are using ServiceClientCredentials from Microsoft.Rest. We are migrating parts of our application over to start using Azure.ResourceManager's ArmClient.
Basically all of our previous application integrations into Azure were using Microsoft.Azure.ResourceManager, which exposed agents like BlobClient or SecretClient, and these all accepted ServiceClientCredentials as a valid token type.
Now, with ArmClient I need to authenticate using DefaultAzureCredential which derives from Azure.Core's TokenCredential.
Surprisingly I haven't been able to find any examples yet of how to create this TokenCredential.
DefaultAzureCredential just works on my local PC since I'm signed into Visual Studio, but not on my build pipeline where I use Certificate based auth exposed as a ServiceClientCredential.
This was easier than I thought. The fix ended up being adding a new ServiceCollection extension method and passing in IWebHostEnvironment.
I use that to determine whether running in local debug, in which case we can use DefaultAzureCredential, or whether running in prod mode, in which case we should use Certificate Based auth.
It looks somewhat like this and works like a charm.
public static IServiceCollection AddDefaultAzureToken (this IServiceCollection services, IWebHostEnvironment environment)
{
if (environment.IsDevelopment())
{
var l = new DefaultAzureCredential();
services.AddSingleton<TokenCredential, l>;
}
else
{
var certCredential= new ClientCertificateCredential(null, null, "Abc");
services.AddSingleton<TokenCredential, certCredential>;
}
return services;
}
This works since DefaultAzureCredential and ClientCertficateCredential all have a common ancestor of TokenCredential, and the L in SOLID, the Liskov Substitution principle tells us that any implementation of a class can be substituted for any other instance of that class without breaking the application.
Note: the above sample was pseudocode and may need slight changing to work in your environment and should be cleaned to match your teams coding standards.

Azure Java SDK for MySQL/PostgreSQL databases?

So, Azure has three variants of SQL services:
SQL Database: https://azure.microsoft.com/en-in/services/sql-database/
MySQL: https://azure.microsoft.com/en-in/services/mysql/
PostgreSQL: https://azure.microsoft.com/en-in/services/postgresql/
I can see that there is a Java SDK for the first one. Are there any Java SDKs available for the MySQL/Postgres service APIs?
Maybe this question isn't fit for SO, but wasn't able to get any response on Github issues, so asking it here.
Looking at the source code here, I believe there are no SDKs for MySQL & Postgres database management in Java as of today.
Since SDKs are essentially a wrapper over REST API, one option for you would be to implement REST API yourself till the time support for these come into SDK.
Here are the links to the REST APIs for MySQL & Postgres:
MySQL: https://learn.microsoft.com/en-us/rest/api/mysql/
Postgres: https://learn.microsoft.com/en-us/rest/api/postgresql/
Azure Java SDK version 1.33.1 doesn't have an inbuilt MySQL management client yet. However, you can use Maven dependency mentioned here
The entry class should be MySQLManager.
Here is a sample code that I have written to create a MySQL server instance using the same client.
#Override
public Server createMySQLServer(AzureTokenCredentials credential,
AzureMySqlModel model) {
if (credential == null || model == null)
return null;
Server server = null;
if (model.validate()) {
try {
ServerPropertiesForDefaultCreate defaultProp = new ServerPropertiesForDefaultCreate();
ServerPropertiesForCreate withVersion = defaultProp.withAdministratorLogin(
model.getAdministratorLogin()).withAdministratorLoginPassword(
model.getAdministratorPassword()).withVersion(
model.getServerVersion());
server = MySQLManager.configure().withLogLevel(
LogLevel.BODY).authenticate(credential,
credential.defaultSubscriptionId()).servers().define(
model.getServerName()).withRegion(
model.getRegion()).withExistingResourceGroup(
model.getResourceGroup()).withProperties(
withVersion).create();
} catch (Exception ex) {
log.error("Error creating MySQL server {}", ex.getMessage());
}
}
return server;
}
AzureMySqlModel is just a custom Java POJO to get the required details for creating a MySQL server.
Nowadays, both of postgres and mysql was added to Azure SDK
Here, I want to note that both of them have flexible server and those also have different dependencies. Don't repeat my mistake, above dependencies does not work flexible servers.
Akash's answer is also right, but this dependency will become deprecated from next year.

The name 'PromptBehavior' does not exist in the current context

Trying to build a .NET core 1.1 console app with AAD using Microsoft.IdentityModel.Clients.ActiveDirectory (3.13.8).
I'm trying to use AcquireTokenAsync to auth like this
var authParam = new PlatformParameters(PromptBehavior.Auto);
var result = context.AcquireTokenAsync("https://management.core.windows.net/", clientId, new Uri("https://localhost/"), authParam);
result.Wait();
However I Intellisense underlines PromptBehavior and tells me that The name 'PromptBehavior' does not exist in the current context. I also cannot build due to this error.
Not sure how to proceed.
PromptBehavior, and the flows which use it, are not defined for .NET Core, only for full .NET: https://learn.microsoft.com/en-us/active-directory/adal/microsoft.identitymodel.clients.activedirectory.promptbehavior

Azure DiagnosticMonitor API is now obsolete

We are currently in the process of doing some overhauls to our WorkerRole on Azure. Our current implementation uses the DiagnosticsMonitor to automatically put all of the trace and error information into the WAD-Logs table in our storage account and works well. However, as we are implementing the Diagnostics portion of the role in our rewrite, ReSharper is diligently informing me that DiagnosticMonitor is now an obsolete API. However, I cannot find any information that shows what is meant to replace this API.
Some relevant information (all of these should be latest versions via NuGet):
Microsoft.WindowsAzure.Diagnostics :: version 2.5.0.0
Microsoft.WindowsAzure.Configuration:: version 3.0.0.0
Microsoft.WindowsAzure.ServiceRuntime:: version 2.5.0.0
Microsoft.WindowsAzure.Storage:: version 4.3.0.0
The code we are attempting to replicate
public static void ConfigureDiagnostics()
{
//warning here on DiagnosticMonitor
var config = DiagnosticMonitor.GetDefaultInitialConfiguration();
config.ConfigurationChangePollInterval = TimeSpan.FromMinutes(1d);
config.Logs.BufferQuotaInMB = 500;
config.Logs.ScheduledTransferLogLevelFilter = Microsoft.WindowsAzure.Diagnostics.LogLevel.Error;
config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
//warning here on DiagnosticMonitor
DiagnosticMonitor.StartWithConnectionString(ConfigurationManager.AppSettings.Get("LogStorageConnectionString"), config);
}
This was the "old" way of doing the diagnostics and we're deprecating this solution in favor of the new XML based one, meaning you can also remotely configure the Diagnostics infrastructure etc.
More info you can find here on how to migrate as well.

Log in to CRM from ASP.NET

I'm writing an application in which I have to log on to a CRM 2011 server from ASP.NET code. I quickly found this article:
http://msdn.microsoft.com/en-us/library/cc156363.aspx
The problem I'm having is in this bit of code from that article:
//Create the Service
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.CrmAuthenticationTokenValue = token;
service.Url = crmurl;
Visual Studio can't resolve CrmService. So I tried to add a web reference to this project and point the web reference at the CRM service I'm using. The URL I'm getting from Settings->Customizations in CRM, and I'm using the Organization Service endpoint. However, after I add that reference CrmService is still unresolvable. What am I doing wrong?
First off, you have linked a CRM 4 MSDN article, some things have changed so you might want try this one instead: Authenticate Users with Microsoft Dynamics CRM Web Services.
Then as an alternative you may want to try the CrmConnection class, its a helper library in Microsoft.Xrm.Client. It means you can use a connection string approach to authenticate with CRM (and let the class takes care of all the hard work).
var connection = CrmConnection.Parse("Url=http://crm.contoso.com/xrmContoso; Domain=CONTOSO; Username=jsmith; Password=passcode;");
var service = new OrganizationService(connection);
var context = new CrmOrganizationServiceContext(connection);
You can also keep the connection strings in config files makes life significantly easier.
Related articles:
Simplified Connection to Microsoft Dynamics CRM.
Sample: Simplified Connection Quick Start using Microsoft Dynamics CRM.
If you're using standard AD authentication with a local environment this answer should work fine: How to Authenticate to CRM 2011?
Actually, the login procedure is heavily dependent on the authentication provider you're targeting. I'm currently in the process of structuring that info in a pedagogic way on my blog so you're welcome to check it out and nag if it's too techy.
There are at the moment four such ways.
Active directory
Live id
Federation
Online federation
Which is applicable in your case, you should know already. If not, there's code for that too uploaded just a few days ago.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
...
public AuthenticationProviderType GetAuthenticationProviderType(Uri address)
{
IServiceManagement<IOrganizationService> organizationServiceManagement
= ServiceConfigurationFactory.CreateManagement
<IOrganizationService>(address);
return organizationServiceManagement.AuthenticationType;
}
Assuming that you're aiming for AD, you're in luck. It's the easiest.
Uri organizationUrl = new Uri("http ... Organization.svc");
OrganizationServiceProxy organizationService = new OrganizationServiceProxy(
organizationUrl, null, null, null);
If you're aiming for Live Id - that's stingy. I'm still trying to set up a graspable example. The ones at MSDN are just too heavy and confusing. At least when one's dense and lazy like me. More info at mentioned but undisclosed location.

Resources