Connect using Microsoft Entra authentication
This article provides information on how to develop Java applications that use the Microsoft Entra authentication feature with the Microsoft JDBC Driver for SQL Server.
You can use Microsoft Entra authentication, which is a mechanism to connect to Azure SQL Database, Azure SQL Manged Instance, and Azure Synapse Analytics using identities in Microsoft Entra ID. Use Microsoft Entra authentication to centrally manage identities of database users and as an alternative to SQL Server authentication. The JDBC driver allows you to specify your Microsoft Entra credentials in the JDBC connection string to connect to Azure SQL. For information on how to configure Microsoft Entra authentication visit Connecting to Azure SQL By Using Microsoft Entra authentication.
Connection properties to support Microsoft Entra authentication in the Microsoft JDBC Driver for SQL Server are:
- authentication: Use this property to indicate which SQL authentication method to use for the connection.
Possible values are:
ActiveDirectoryManagedIdentity
- Since driver version 8.3.1,
authentication=ActiveDirectoryMSI
can be used to connect to an Azure SQL Database/Synapse Analytics from an Azure Resource with "Identity" support enabled. Optionally, msiClientId can be specified in the Connection/DataSource properties along with this authentication mode.msiClientId
must contain the Client ID of a Managed Identity to be used to acquire the accessToken for establishing the connection. Since driver version v12.2,authentication=ActiveDirectoryManagedIdentity
can also be used to connect to an Azure SQL Database/Synapse Analytics from an Azure Resource with "Identity" support enabled. Optionally, the Client ID of a Managed Identity can also now be set in theuser
property. For more information, see Connect using ActiveDirectoryManagedIdentity authentication mode.
- Since driver version 8.3.1,
ActiveDirectoryDefault
- Since driver version 12.2,
authentication=ActiveDirectoryDefault
can be used to connect to Azure SQL/Synapse Analytics via the DefaultAzureCredential from the Azure Identity client library. For more information, see Connect using ActiveDirectoryDefault authentication mode.
- Since driver version 12.2,
ActiveDirectoryIntegrated
- Since driver version 6.0,
authentication=ActiveDirectoryIntegrated
can be used to connect to Azure SQL/Synapse Analytics via integrated authentication. To use this authentication mode, you must federate the on-premises Active Directory Federation Services (ADFS) with Microsoft Entra ID in the cloud. Once you set it up, you can connect by either adding the native librarymssql-jdbc_auth-<version>-<arch>.dll
to the application class path on Windows, or by setting up a Kerberos ticket for cross-platform authentication support. You're able to access Azure SQL/Azure Synapse Analytics without being prompted for credentials when you're logged in to a domain-joined machine. For more information, see Connect using ActiveDirectoryIntegrated authentication mode.
- Since driver version 6.0,
ActiveDirectoryPassword
- Since driver version 6.0,
authentication=ActiveDirectoryPassword
can be used to connect to Azure SQL/Synapse Analytics with Microsoft Entra username and password. For more information, see Connect using ActiveDirectoryPassword authentication mode.
- Since driver version 6.0,
ActiveDirectoryInteractive
- Since driver version 9.2,
authentication=ActiveDirectoryInteractive
can be used to connect to an Azure SQL/Synapse Analytics via interactive authentication flow (multifactor authentication). For more information, see Connect using ActiveDirectoryInteractive authentication mode.
- Since driver version 9.2,
ActiveDirectoryServicePrincipal
- Since driver version 9.2,
authentication=ActiveDirectoryServicePrincipal
can be used to connect to an Azure SQL/Synapse Analytics by specifying the application/client ID in the userName property and secret of a service principal identity in the password property. For more information, see Connect using ActiveDirectoryServicePrincipal authentication mode.
- Since driver version 9.2,
ActiveDirectoryServicePrincipalCertificate
- Since driver version 12.4,
authentication=ActiveDirectoryServicePrincipalCertificate
can be used to connect to an Azure SQL Database/Synapse Analytics by specifying the application/client ID in the userName property and the location of the Service Principal certificate in theclientCertificate
property. For more information, see Connect using ActiveDirectoryServicePrincipalCertificate authentication mode.
- Since driver version 12.4,
SqlPassword
- Use
authentication=SqlPassword
to connect to a SQL Server using userName/user and password properties.
- Use
NotSpecified
- Use
authentication=NotSpecified
or leave it as the default when none of these authentication methods are needed.
- Use
accessToken: Use this connection property to connect to a SQL Database with access token.
accessToken
can only be set using the Properties parameter of thegetConnection()
method in the DriverManager class. It can't be used in the connection URL.
For more information, see the authentication property on the Setting the Connection Properties page.
In addition to the basic driver System requirements, the following authentication modes have more requirements.
The following table lists required library dependencies for each authentication mode and driver version. Dependencies of dependencies are also required.
Note
In cases where the hotfix for a major release has a different dependency version than its major release, the hotfix is also listed.
Authentication option | Driver versions | Library dependencies |
---|---|---|
ActiveDirectoryPassword ActiveDirectoryIntegrated |
6.0 | Adal4j 1.3.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated |
6.2.2 - 6.4 | Adal4j 1.4.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated |
7.0 | Adal4j 1.6.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated |
7.2 | Adal4j 1.6.3Client-Runtime-for-AutoRest 1.6.5 |
ActiveDirectoryPassword ActiveDirectoryIntegrated |
7.4 - 8.2 | Adal4j l4j 1.6.4Client-Runtime-for-AutoRest 1.7.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated |
8.4 | Adal4j 1.6.5Client-Runtime-for-AutoRest 1.7.4 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal |
9.2 | msal4j 1.7.1 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal |
9.4 | msal4j 1.10.1 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal |
10.2 | msal4j 1.11.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal |
11.2 | msal4j 1.11.3 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal |
11.2.3 | msal4j 1.13.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal |
12.2 | msal4j 1.13.3 |
ActiveDirectoryManagedIdentity ActiveDirectoryMSI ActiveDirectoryDefault |
12.2 | azure-identity 1.7.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal ActiveDirectoryServicePrincipalCertificate |
12.4 | msal4j 1.13.8 |
ActiveDirectoryManagedIdentity ActiveDirectoryMSI ActiveDirectoryDefault |
12.4 | azure-identity 1.9.0 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal ActiveDirectoryServicePrincipalCertificate |
12.6 | msal4j 1.14.1 |
ActiveDirectoryManagedIdentity ActiveDirectoryMSI ActiveDirectoryDefault |
12.6 | azure-identity 1.11.1 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal ActiveDirectoryServicePrincipalCertificate |
12.6.3 | msal4j 1.15.1 |
ActiveDirectoryManagedIdentity ActiveDirectoryMSI ActiveDirectoryDefault |
12.6.3 | azure-identity 1.12.2 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal ActiveDirectoryServicePrincipalCertificate |
12.6.4 | msal4j 1.15.1 |
ActiveDirectoryManagedIdentity ActiveDirectoryMSI ActiveDirectoryDefault |
12.6.4 | azure-identity 1.12.2 |
ActiveDirectoryPassword ActiveDirectoryIntegrated ActiveDirectoryInteractive ActiveDirectoryServicePrincipal ActiveDirectoryServicePrincipalCertificate |
12.8 | msal4j 1.15.1 |
ActiveDirectoryManagedIdentity ActiveDirectoryMSI ActiveDirectoryDefault |
12.8 | azure-identity 1.12.2 |
This authentication mode is supported starting with version 7.2. To use it, specify authentication=ActiveDirectoryMSI
. Starting in version 12.2, authentication=ActiveDirectoryManagedIdentity
can also be specified.
In addition to the library dependency requirements listed in Client setup requirements, this feature has the following requirements:
The target database must have a contained database user, with CONNECT permission. The contained user must represent your Azure Resource's System Assigned Managed Identity or User Assigned Managed Identity, or one of the groups your Managed Identity belongs to.
The client environment must be an Azure Resource and must have "Identity" feature support enabled. The following table lists Azure services supported by each JDBC driver version:
Driver version Required dependencies Azure services supported 7.2 - 11.2 None Azure App Service and Azure Functions
Azure Virtual Machines12.2
12.4
12.6
12.8azure-identity 1.7.0
azure-identity 1.9.0
azure-identity 1.11.1
azure-identity 1.12.2Azure App Service and Azure Functions
Azure Arc
Azure Cloud Shell
Azure Kubernetes Service
Azure Service Fabric
Azure Virtual Machines
Azure Virtual Machines Scale Sets
The following example shows how to use authentication=ActiveDirectoryManagedIdentity
mode. Run this example from inside an Azure Resource that is configured for Managed Identity.
To run the example, replace the server/database name with your server/database name on the following lines:
ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
ds.setDatabaseName("demo"); // replace with your database name
//Optional
ds.setMSIClientId("<managed_identity_client>"); // Replace with Client ID of user-assigned managed identity to be used
The example to use ActiveDirectoryMSI
authentication mode:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MsEntraMSI {
public static void main(String[] args) throws Exception {
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database name
ds.setAuthentication("ActiveDirectoryMSI");
// Optional
ds.setMSIClientId("<managed_identity_client_guid>"); // Replace with Client ID of user-assigned managed identity to be used
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
The following example demonstrates how to use authentication=ActiveDirectoryManagedIdentity
mode.
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MSEntraManagedIdentity {
public static void main(String[] args) throws Exception {
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database name
ds.setAuthentication("ActiveDirectoryManagedIdentity"); // ActiveDirectoryManagedIdentity for JDBC driver version v12.2.0+
// Optional
ds.setUser("<managed_identity_client>"); // Replace with Client ID of User-Assigned Managed Identity to be used
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
These examples on an Azure Virtual Machine fetch an access token from System Assigned Managed Identity or User Assigned Managed Identity (if msiClientId
or user
is specified with a Client ID of a Managed Identity) and establishes a connection using the fetched access token. If a connection is established, you should see the following message:
You have successfully logged on as: <your Managed Identity username>
The ActiveDirectoryDefault
authentication option uses the Azure Identity client library's DefaultAzureCredential
chained TokenCredential
implementation. The credential combines commonly used authentication methods chained together.
ActiveDirectoryDefault
authentication requires a run time dependency on the Azure Identity client library for Managed Identity. For library version details, see Client setup requirements.
The following table lists the DefaultAzureCredential
credential chain for each JDBC driver version.
Driver version | azure-identity version docs | DefaultAzureCredential chain |
---|---|---|
12.2 | azure-identity 1.7.0 | Environment Managed Identity IntelliJ Azure CLI Azure PowerShell |
12.4 | azure-identity 1.9.0 | Environment Workload Identity Managed Identity Azure Developer CLI IntelliJ Azure CLI Azure PowerShell |
12.6 | azure-identity 1.11.1 | Environment Workload Identity Managed Identity Azure Developer CLI IntelliJ Azure CLI Azure PowerShell |
12.8 | azure-identity 1.12.2 | Environment Workload Identity Managed Identity Azure Developer CLI IntelliJ Azure CLI Azure PowerShell |
There are many variables that can be set to configure the Environment
credential. For details on configuring the DefaulAzureCredential
chain, including the Environment
credential, see the relevant version of the azure-identity docs linked in the previous table.
To use the IntellijCredential
on Windows, set the environment variable INTELLIJ_KEEPASS_PATH
to the location of your keepass
file. For example, INTELLIJ_KEEPASS_PATH=C:\user\your\path\to\the\keepass\file
.
To provide more tenants to the DefaultAzureCredential
, use the ADDITIONALLY_ALLOWED_TENANTS
environment variable. This variable takes a comma delimited list. For example, ADDITIONALLY_ALLOWED_TENANTS=<your-tenant-id-0>,<your-tenant-id-1>,<your-tenant-id-2>,...
The following example demonstrates how to use authentication=ActiveDirectoryDefault
mode with the AzureCliCredential within the DefaultAzureCredential
.
First sign in to the Azure CLI with the following command.
az login
After successfully logging in to the Azure CLI, run the following code.
import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import com.microsoft.sqlserver.jdbc.SQLServerDataSource; public class MSEntraDefault { public static void main(String[] args) throws Exception { SQLServerDataSource ds = new SQLServerDataSource(); ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name ds.setDatabaseName("demo"); // Replace with your database name ds.setAuthentication("ActiveDirectoryDefault"); try (Connection connection = ds.getConnection(); Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) { if (rs.next()) { System.out.println("You have successfully logged on as: " + rs.getString(1)); } } } }
There are two ways to use ActiveDirectoryIntegrated
authentication in the Microsoft JDBC Driver for SQL Server:
- On Windows,
mssql-jdbc_auth-<version>-<arch>.dll
from the downloaded package can be copied to a location in the system path. - If you can't use the DLL, starting with version 6.4, you can configure a Kerberos ticket. This method is supported across platforms (Windows, Linux, and macOS). For more information, see Set Kerberos ticket on Windows, Linux And macOS.
Ensure you have the required dependent libraries from the Client setup requirements.
The following example shows how to use authentication=ActiveDirectoryIntegrated
mode. This example runs on a domain-joined machine that is federated with Microsoft Entra ID. A database user that represents your Windows user must exist in the database and must have the CONNECT permission.
Replace the server/database name with your server/database name in the following lines before executing the example:
ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
ds.setDatabaseName("demo"); // replace with your database name
The example to use ActiveDirectoryIntegrated authentication mode:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MSEntraIntegrated {
public static void main(String[] args) throws Exception {
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database name
ds.setAuthentication("ActiveDirectoryIntegrated");
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
Running this example automatically uses your Kerberos ticket from the client platform and no password is required. If a connection is established, you should see the following message:
You have successfully logged on as: <your domain user name>
You must up a Kerberos ticket to link your current user to a Windows domain account. Following is a summary of the key steps.
Note
On Windows, mssql-jdbc_auth-<version>-<arch>.dll
from the downloaded package can be used instead of these Kerberos configuration steps. These steps are only required if you can't use the DLL.
JDK comes with kinit
, which you can use to get a TGT from Key Distribution Center (KDC) on a domain joined machine that is federated with Microsoft Entra ID.
Run on: Windows
Action:
- Use the command
kinit username@DOMAIN.COMPANY.COM
to get a TGT from KDC, then it prompts you for your domain password. - Use
klist
to see the available tickets. If the kinit was successful, you should see a ticket fromkrbtgt/DOMAIN.COMPANY.COM@ DOMAIN.COMPANY.COM
.
Note
You might have to specify a
.ini
file with-Djava.security.krb5.conf
for your application to locate KDC.- Use the command
Access to a Windows domain-joined machine to query your Kerberos Domain Controller.
Run on: Windows command line
Action:
nltest /dsgetdc:DOMAIN.COMPANY.COM
(whereDOMAIN.COMPANY.COM
maps to your domain's name)Sample Output
DC: \\co1-red-dc-33.domain.company.com Address: \\2111:4444:2111:33:1111:ecff:ffff:3333 ... The command completed successfully
Information to extract The DC name, in this case
co1-red-dc-33.domain.company.com
Run on: Linux/macOS
Action: Edit the
/etc/krb5.conf
in an editor of your choice. Configure the following keys[libdefaults] default_realm = DOMAIN.COMPANY.COM [realms] DOMAIN.COMPANY.COM = { kdc = co1-red-dc-28.domain.company.com }
Then save the
krb5.conf
file and exitNote
Domain must be in ALL CAPS.
- Run on: Linux/macOS
- Action:
- Use the command
kinit username@DOMAIN.COMPANY.COM
to get a TGT from KDC, then it prompts you for your domain password. - Use
klist
to see the available tickets. If the kinit was successful, you should see a ticket fromkrbtgt/DOMAIN.COMPANY.COM@ DOMAIN.COMPANY.COM
.
- Use the command
The following example shows how to use authentication=ActiveDirectoryPassword
mode.
To build and run the example:
Ensure you have the required dependent libraries from the Client setup requirements.
Locate the following lines of code and replace the server/database name with your server/database name.
ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name ds.setDatabaseName("demo"); // replace with your database name
Locate the following lines of code. Replace user name with the name of the Microsoft Entra user that you want to connect as.
ds.setUser("bob@example.com"); // replace with your username ds.setPassword("password"); // replace with your password
The example to use ActiveDirectoryPassword
authentication mode:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MSEntraUserPassword {
public static void main(String[] args) throws Exception{
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database
ds.setUser("bob@example.com"); // Replace with your username
ds.setPassword("password"); // Replace with your password
ds.setAuthentication("ActiveDirectoryPassword");
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
If the connection is established, you should see the following message as output:
You have successfully logged on as: <your user name>
The following example shows how to use authentication=ActiveDirectoryInteractive
mode.
To build and run the example:
Ensure you have the required dependent libraries from the Client setup requirements.
Locate the following lines of code and replace the server/database name with your server/database name.
ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name ds.setDatabaseName("demo"); // replace with your database name
Locate the following lines of code. Replace username with the name of the Microsoft Entra user that you want to connect as.
ds.setUser("bob@example.com"); // replace with your username
The example to use ActiveDirectoryInteractive
authentication mode:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MSEntraInteractive {
public static void main(String[] args) throws Exception{
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database
ds.setAuthentication("ActiveDirectoryInteractive");
// Optional login hint
ds.setUser("bob@example.com"); // Replace with your user name
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
When you run the program, a browser is displayed to authenticate the user. Exactly what you see depends on how you configure your Microsoft Entra ID. It might or might not include multifactor authentication prompts for username, password, PIN, or second device authentication via a phone. If multiple interactive authentication requests are done in the same program, later requests might not even prompt you if the authentication library can reuse a previously cached authentication token.
For information about how to configure Microsoft Entra ID to require multifactor authentication, see Getting started with Microsoft Entra multifactor authentication in the cloud.
For screenshots of these dialog boxes, see Using Microsoft Entra multifactor authentication.
If user authentication is completed successfully, you should see the following message in the browser:
Authentication complete. You can close the browser and return to the application.
This message only indicates that user authentication was successful but not necessarily a successful connection to the server. Upon return to the application, if a connection is established to the server, you should see the following message as output:
You have successfully logged on as: <your user name>
The following example shows how to use authentication=ActiveDirectoryServicePrincipal
mode.
To build and run the example:
Ensure you have the required dependent libraries from the Client setup requirements.
Locate the following lines of code and replace the server/database name with your server/database name.
ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name ds.setDatabaseName("demo"); // replace with your database name
Locate the following lines of code. Replace the value of
principalId
with the Application ID / Client ID of the Microsoft Entra service principal that you want to connect as. Replace the value ofprincipalSecret
with the secret.String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID. String principalSecret = "..."; // Replace with your Microsoft Entra principal secret.
Set the principal ID and principal secret using
setUser
andsetPassword
in version 10.2 and up, andsetAADSecurePrincipalId
andsetAADSecurePrincipalSecret
in version 9.4 and below.
The example to use ActiveDirectoryServicePrincipal
authentication mode:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MSEntraServicePrincipal {
public static void main(String[] args) throws Exception{
String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID.
String principalSecret = "..."; // Replace with your Microsoft Entra principal secret.
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database
ds.setAuthentication("ActiveDirectoryServicePrincipal");
ds.setUser(principalId); // setAADSecurePrincipalId for JDBC Driver 9.4 and below
ds.setPassword(principalSecret); // setAADSecurePrincipalSecret for JDBC Driver 9.4 and below
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
If a connection is established, you should see the following message as output:
You have successfully logged on as: <your app/client ID>
The following example shows how to use authentication=ActiveDirectoryServicePrincipalCertificate
mode.
To build and run the example:
Ensure you have the required dependent libraries from the Client setup requirements.
Locate the following lines of code and replace the server/database name with your server/database name.
ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name ds.setDatabaseName("demo"); // replace with your database name
Locate the following lines of code. Replace the value of
principalId
with the Application ID / Client ID of the Microsoft Entra service principal that you want to connect as. Replace the value ofclientCertificate
with the location of the service principal certificate.String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID. String clientCertificate = "..."; // Replace with the location for your Microsoft Entra service principal certificate.
If the previously mentioned certificate needs a password, set the principal Secret using
setPassword
in version 10.2 and up orsetAADSecurePrincipalSecret
in version 9.4 and below.If the certificate has an associated private key, set the private key using
setClientKey
. If this key requires a password, set the password for the private key usingsetClientKeyPassword
.
The example to use ActiveDirectoryServicePrincipalCertificate
authentication mode:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class MSEntraServicePrincipalCertificate {
public static void main(String[] args) throws Exception{
String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID.
String clientCertificate = "..."; // Replace with the location of your service principal certificate.
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
ds.setDatabaseName("demo"); // Replace with your database
ds.setAuthentication("ActiveDirectoryServicePrincipalCertificate");
ds.setUser(principalId); // setAADSecurePrincipalId for JDBC Driver 9.4 and below
ds.setClientCertificate(clientCertificate);
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
If a connection is established, you should see the following message as output:
You have successfully logged on as: <your app/client ID>
Applications/services can retrieve an access token from Microsoft Entra ID and use that to connect to Azure SQL Database, Azure SQL Managed Instance, and Azure Synapse Analytics.
Note
accessToken
can only be set using the Properties parameter of the getConnection()
method in the DriverManager class. It can't be used in the connection string. Starting with driver version 12.2, users can implement and provide an accessToken
callback to the driver for token renewal in connection pooling scenarios. Connection pooling scenarios require the connection pool implementation to use the standard JDBC connection pooling classes.
The following example contains a simple Java application that connects to Azure using access token-based authentication.
To build and run the example:
Create an application account in Microsoft Entra ID for your service.
- Sign in to the Azure portal.
- Go to Microsoft Entra ID in the left-hand navigation.
- Select App registrations.
- Select New registration.
- Enter
mytokentest
as a friendly name for the application. - Leave the default selection for supported account types, which can use the application.
- Select Register at the bottom.
- Don't need SIGN-ON URL. Provide anything:
https://mytokentest
. - Select
Create
at the bottom. - Upon selecting Register, the app is immediately created, and you're taken to its resource page.
- In the Essentials box, find the Application (client) ID and copy it. You need this value later to configure your application.
- Select Certificates & secrets from the navigation pane. On the Client secrets (0) tab, select New client secret. Enter a description for the secret and select an expiration (the default is fine). Select Add at the bottom. Important before leaving this page, copy the generated Value for your client secret. This value can't be viewed after leaving the page. This value is the client secret.
- Return to the App registrations pane for Microsoft Entra ID and find the Endpoints tab. Copy the URL under
OAuth 2.0 token endpoint
. This URL is your STS URL.
Connect to your database as a Microsoft Entra admin and use a T-SQL command to provision a contained database user for your application principal. For more information on how to create a Microsoft Entra admin and a contained database user, see the Connecting by using Microsoft Entra authentication.
CREATE USER [mytokentest] FROM EXTERNAL PROVIDER
On the client machine where you run the example, download the Microsoft Authentication Library (MSAL) for Java library and its dependencies. MSAL is only required to run this specific example. The example uses the APIs from this library to retrieve the access token from Microsoft Entra ID. If you already have an access token, you can skip this step and remove the section in the example that retrieves an access token.
In the following example, replace the STS URL, Client ID, Client Secret, server and database name with your values.
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
// The microsoft-authentication-library-for-java is needed to retrieve the access token in this example.
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.IClientCredential;
public class MSEntraTokenBased {
public static void main(String[] args) throws Exception {
// Retrieve the access token from Microsoft Entra ID.
String spn = "https://database.windows.net/";
String stsurl = "https://login.microsoftonline.com/..."; // Replace with your STS URL.
String clientId = "<service_principal_guid>"; // Replace with your client ID.
String clientSecret = "..."; // Replace with your client secret.
String scope = spn + "/.default";
Set<String> scopes = new HashSet<>();
scopes.add(scope);
ExecutorService executorService = Executors.newSingleThreadExecutor();
IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
ConfidentialClientApplication clientApplication = ConfidentialClientApplication
.builder(clientId, credential).executorService(executorService).authority(stsurl).build();
CompletableFuture<IAuthenticationResult> future = clientApplication
.acquireToken(ClientCredentialParameters.builder(scopes).build());
IAuthenticationResult authenticationResult = future.get();
String accessToken = authenticationResult.accessToken();
System.out.println("Access Token: " + accessToken);
// Connect with the access token.
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name.
ds.setDatabaseName("demo"); // Replace with your database name.
ds.setAccessToken(accessToken);
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
If the connection is successful, you should see the following message as output:
Access Token: <your access token>
You have successfully logged on as: <your client ID>
Like the access token property, the access token callback allows you to register a method that provides an access token to the driver. The benefit of this callback over the property is the callback allows the driver to request a new access token when the token is expired. For example, a connection pool creating a new connection can request a new token with a new expiration date. For more information, see Using connection pooling.
The following example demonstrates implementing and setting the accessToken callback.
import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MSEntraAccessTokenCallback {
public static void main(String[] args) {
SQLServerAccessTokenCallback callback = new SQLServerAccessTokenCallback() {
@Override
public SqlAuthenticationToken getAccessToken(String spn, String stsurl) {
String clientSecret = "..."; // Replace with your client secret.
String clientId = "<service_principal_guid>"; // Replace with your client ID.
String scope = spn + "/.default";
Set<String> scopes = new HashSet<>();
scopes.add(scope);
try {
ExecutorService executorService = Executors.newSingleThreadExecutor();
IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
ConfidentialClientApplication clientApplication = ConfidentialClientApplication
.builder(clientId, credential).executorService(executorService).authority(stsurl).build();
CompletableFuture<IAuthenticationResult> future = clientApplication
.acquireToken(ClientCredentialParameters.builder(scopes).build());
IAuthenticationResult authenticationResult = future.get();
String accessToken = authenticationResult.accessToken();
return new SqlAuthenticationToken(accessToken, authenticationResult.expiresOnDate().getTime());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replaces with your server name.
ds.setDatabaseName("demo"); // Replace with your database name.
ds.setAccessTokenCallback(callback);
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
If the connection is successful, you should see the following message as output:
You have successfully logged on as: <your client ID>
Starting from version 12.4, the accessToken
callback can be set through the accessTokenCallbackClass
connection string property. The following example shows how to set the accessToken
callback using this property:
import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MSEntraAccessTokenCallbackClass {
public static class AccessTokenCallbackClass implements SQLServerAccessTokenCallback {
@Override
public SqlAuthenticationToken getAccessToken(String spn, String stsurl) {
String clientSecret = "..."; // Replace with your client secret.
String clientId = "<service_principal_guid>"; // Replace with your client ID.
String scope = spn + "/.default";
Set<String> scopes = new HashSet<>();
scopes.add(scope);
try {
ExecutorService executorService = Executors.newSingleThreadExecutor();
IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
ConfidentialClientApplication clientApplication = ConfidentialClientApplication
.builder(clientId, credential).executorService(executorService).authority(stsurl).build();
CompletableFuture<IAuthenticationResult> future = clientApplication
.acquireToken(ClientCredentialParameters.builder(scopes).build());
IAuthenticationResult authenticationResult = future.get();
String accessToken = authenticationResult.accessToken();
return new SqlAuthenticationToken(accessToken, authenticationResult.expiresOnDate().getTime());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public static void main(String[] args) throws Exception {
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("msentra-managed-demo.database.windows.net"); // Replaces with your server name.
ds.setDatabaseName("demo"); // Replace with your database name.
ds.setAccessTokenCallbackClass(AccessTokenCallbackClass.class.getName());
try (Connection connection = ds.getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
if (rs.next()) {
System.out.println("You have successfully logged on as: " + rs.getString(1));
}
}
}
}
If the connection is successful, you should see the following message as output:
You have successfully logged on as: <your client ID>
Learn more about related concepts in the following articles: