|
| 1 | +--- |
| 2 | +title: Create and utilize Azure Active Directory server logins |
| 3 | +description: This article guides you through creating and utilizing Azure Active Directory logins in the virtual master database of Azure SQL |
| 4 | +ms.service: sql-db-mi |
| 5 | +ms.subservice: security |
| 6 | +ms.topic: tutorial |
| 7 | +author: GithubMirek |
| 8 | +ms.author: mireks |
| 9 | +ms.reviewer: vanto |
| 10 | +ms.date: 03/14/2022 |
| 11 | +--- |
| 12 | + |
| 13 | +# Tutorial: Create and utilize Azure Active Directory server logins |
| 14 | + |
| 15 | +[!INCLUDE[appliesto-sqldb-sqlmi-asa-dedicated-only](../includes/appliesto-sqldb-sqlmi-asa-dedicated-only.md)] |
| 16 | + |
| 17 | +> [!NOTE] |
| 18 | +> Azure Active Directory (Azure AD) server principals (logins) are currently in public preview for Azure SQL Database. Azure SQL Managed Instance can already utilize Azure AD logins. |
| 19 | +
|
| 20 | +This article guides you through creating and utilizing [Azure Active Directory (Azure AD) principals (logins)](authentication-azure-ad-logins.md) in the virtual master database of Azure SQL. |
| 21 | + |
| 22 | +In this tutorial, you learn how to: |
| 23 | + |
| 24 | +> [!div class="checklist"] |
| 25 | +> - Create an Azure AD login in the virtual master database with the new syntax extension for Azure SQL Database |
| 26 | +> - Create a user mapped to an Azure AD login in the virtual master database |
| 27 | +> - Grant server roles to an Azure AD user |
| 28 | +> - Disable an Azure AD login |
| 29 | +
|
| 30 | +## Prerequisites |
| 31 | + |
| 32 | +- A SQL Database or SQL Managed Instance with a database. See [Quickstart: Create an Azure SQL Database single database](single-database-create-quickstart.md) if you haven't already created an Azure SQL Database, or [Quickstart: Create an Azure SQL Managed Instance](../managed-instance/instance-create-quickstart.md). |
| 33 | +- Azure AD authentication set up for SQL Database or Managed Instance. For more information, see [Configure and manage Azure AD authentication with Azure SQL](authentication-aad-configure.md). |
| 34 | +- This article instructs you on creating an Azure AD login and user within the virtual master database. Only an Azure AD admin can create a user within the virtual master database, so we recommend you use the Azure AD admin account when going through this tutorial. An Azure AD principal with the `loginmanager` role can create a login, but not a user within the virtual master database. |
| 35 | + |
| 36 | +## Create Azure AD login |
| 37 | + |
| 38 | +1. Create an Azure SQL Database login for an Azure AD account. In our example, we'll use `[email protected]` that exists in our Azure AD domain called `contoso`. A login can also be created from an Azure AD group or [service principal (applications) ](authentication-aad-service-principal.md). For example, `mygroup` that is an Azure AD group consisting of Azure AD accounts that are a member of that group. For more information, see [CREATE LOGIN (Transact-SQL) ](/sql/t-sql/statements/create-login-transact-sql?view=azuresqldb-current&preserve-view=true). |
| 39 | + |
| 40 | + > [!NOTE] |
| 41 | + > The first Azure AD login must be created by the Azure Active Directory admin. A SQL login cannot create Azure AD logins. |
| 42 | +
|
| 43 | +1. Using [SQL Server Management Studio (SSMS)](/sql/ssms/download-sql-server-management-studio-ssms), log into your SQL Database with the Azure AD admin account set up for the server. |
| 44 | +1. Run the following query: |
| 45 | + |
| 46 | + ```sql |
| 47 | + Use master |
| 48 | + CREATE LOGIN [bob@contoso.com] FROM EXTERNAL PROVIDER |
| 49 | + GO |
| 50 | + ``` |
| 51 | + |
| 52 | +1. Check the created login in `sys.server_principals`. Execute the following query: |
| 53 | + |
| 54 | + ```sql |
| 55 | + SELECT name, type_desc, type, is_disabled |
| 56 | + FROM sys.server_principals |
| 57 | + WHERE type_desc like 'external%' |
| 58 | + ``` |
| 59 | + |
| 60 | + You would see a similar output to the following: |
| 61 | + |
| 62 | + ```output |
| 63 | + Name type_desc type is_disabled |
| 64 | + [email protected] EXTERNAL_LOGIN E 0 |
| 65 | + ``` |
| 66 | + |
| 67 | +1. The login `[email protected]` has been created in the virtual master database. |
| 68 | + |
| 69 | +## Create user from an Azure AD login |
| 70 | + |
| 71 | +1. Now that we've created an Azure AD login, we can create a database-level Azure AD user that is mapped to the Azure AD login in the virtual master database. We'll continue to use our example, `[email protected]` to create a user in the virtual master database, as we want to demonstrate adding the user to special roles. Only an Azure AD admin or SQL server admin can create users in the virtual master database. |
| 72 | + |
| 73 | +1. We're using the virtual master database, but you can switch to a database of your choice if you want to create users in other databases. Run the following query. |
| 74 | + |
| 75 | + ```sql |
| 76 | + Use master |
| 77 | + CREATE USER [bob@contoso.com] FROM LOGIN [bob@contoso.com] |
| 78 | + ``` |
| 79 | + |
| 80 | + > [!TIP] |
| 81 | + > Although it is not required to use Azure AD user aliases (for example, `[email protected]`), it is a recommended best practice to use the same alias for Azure AD users and Azure AD logins. |
| 82 | +
|
| 83 | +1. Check the created user in `sys.database_principals`. Execute the following query: |
| 84 | + |
| 85 | + ```sql |
| 86 | + SELECT name, type_desc, type |
| 87 | + FROM sys.database_principals |
| 88 | + WHERE type_desc like 'external%' |
| 89 | + ``` |
| 90 | + |
| 91 | + You would see a similar output to the following: |
| 92 | + |
| 93 | + ```output |
| 94 | + Name type_desc type |
| 95 | + |
| 96 | + ``` |
| 97 | + |
| 98 | +> [!NOTE] |
| 99 | +> The existing syntax to create an Azure AD user without an Azure AD login is still supported, and requires the creation of a contained user inside SQL Database (without login). |
| 100 | +> |
| 101 | +> For example, `CREATE USER [[email protected]] FROM EXTERNAL PROVIDER`. |
| 102 | +
|
| 103 | +## Grant server-level roles to Azure AD logins |
| 104 | + |
| 105 | +You can add logins to the [built-in server-level roles](security-server-roles.md#built-in-server-level-roles), such as the **##MS_DefinitionReader##**, **##MS_ServerStateReader##**, or **##MS_ServerStateManager##** role. |
| 106 | + |
| 107 | +> [!NOTE] |
| 108 | +> The server-level roles mentioned here are not supported for Azure AD groups. |
| 109 | +
|
| 110 | +```sql |
| 111 | +ALTER SERVER ROLE ##MS_DefinitionReader## ADD MEMBER [AzureAD_object]; |
| 112 | +``` |
| 113 | + |
| 114 | +```sql |
| 115 | +ALTER SERVER ROLE ##MS_ServerStateReader## ADD MEMBER [AzureAD_object]; |
| 116 | +``` |
| 117 | + |
| 118 | +```sql |
| 119 | +ALTER SERVER ROLE ##MS_ServerStateManager## ADD MEMBER [AzureAD_object]; |
| 120 | +``` |
| 121 | + |
| 122 | +Permissions aren't effective until the user reconnects. Flush the DBCC cache as well: |
| 123 | + |
| 124 | +```sql |
| 125 | +DBCC FLUSHAUTHCACHE |
| 126 | +DBCC FREESYSTEMCACHE('TokenAndPermUserStore') WITH NO_INFOMSGS |
| 127 | +``` |
| 128 | + |
| 129 | +To check which Azure AD logins are part of server-level roles, run the following query: |
| 130 | + |
| 131 | +```sql |
| 132 | +SELECT roles.principal_id AS RolePID,roles.name AS RolePName, |
| 133 | + server_role_members.member_principal_id AS MemberPID, members.name AS MemberPName |
| 134 | + FROM sys.server_role_members AS server_role_members |
| 135 | + INNER JOIN sys.server_principals AS roles |
| 136 | + ON server_role_members.role_principal_id = roles.principal_id |
| 137 | + INNER JOIN sys.server_principals AS members |
| 138 | + ON server_role_members.member_principal_id = members.principal_id; |
| 139 | +``` |
| 140 | + |
| 141 | +## Grant special roles for Azure AD users |
| 142 | + |
| 143 | +[Special roles for SQL Database](/sql/relational-databases/security/authentication-access/database-level-roles#special-roles-for--and-azure-synapse) can be assigned to users in the virtual master database. |
| 144 | + |
| 145 | +In order to grant one of the special database roles to a user, the user must exist in the virtual master database. |
| 146 | + |
| 147 | +To add a user to a role, you can run the following query: |
| 148 | + |
| 149 | +```sql |
| 150 | +ALTER ROLE [dbamanger] ADD MEMBER [AzureAD_object] |
| 151 | +``` |
| 152 | + |
| 153 | +To remove a user from a role, run the following query: |
| 154 | + |
| 155 | +```sql |
| 156 | +ALTER ROLE [dbamanger] DROP MEMBER [AzureAD_object] |
| 157 | +``` |
| 158 | + |
| 159 | +`AzureAD_object` can be an Azure AD user, group, or service principal in Azure AD. |
| 160 | + |
| 161 | +In our example, we created the user `[email protected]`. Let's give the user the **dbmanager ** and **loginmanager ** roles. |
| 162 | + |
| 163 | +1. Run the following query: |
| 164 | + |
| 165 | + ```sql |
| 166 | + ALTER ROLE [dbamanger] ADD MEMBER [bob@contoso.com] |
| 167 | + ALTER ROLE [loginmanager] ADD MEMBER [bob@contoso.com] |
| 168 | + ``` |
| 169 | + |
| 170 | +1. Check the database role assignment by running the following query: |
| 171 | + |
| 172 | + ```sql |
| 173 | + SELECT DP1.name AS DatabaseRoleName, |
| 174 | + isnull (DP2.name, 'No members') AS DatabaseUserName |
| 175 | + FROM sys.database_role_members AS DRM |
| 176 | + RIGHT OUTER JOIN sys.database_principals AS DP1 |
| 177 | + ON DRM.role_principal_id = DP1.principal_id |
| 178 | + LEFT OUTER JOIN sys.database_principals AS DP2 |
| 179 | + ON DRM.member_principal_id = DP2.principal_id |
| 180 | + WHERE DP1.type = 'R'and DP2.name like 'bob%' |
| 181 | + ``` |
| 182 | + |
| 183 | + You would see a similar output to the following: |
| 184 | + |
| 185 | + ```output |
| 186 | + DatabaseRoleName DatabaseUserName |
| 187 | + |
| 188 | + |
| 189 | + ``` |
| 190 | + |
| 191 | +## Optional - Disable a login |
| 192 | + |
| 193 | +The [ALTER LOGIN (Transact-SQL)](/sql/t-sql/statements/alter-login-transact-sql?view=azuresqldb-current&preserve-view=true) DDL syntax can be used to enable or disable an Azure AD login in Azure SQL Database. |
| 194 | + |
| 195 | +```sql |
| 196 | +ALTER LOGIN [bob@contoso.com] DISABLE |
| 197 | +``` |
| 198 | + |
| 199 | +For the `DISABLE` or `ENABLE` changes to take immediate effect, the authentication cache and the **TokenAndPermUserStore** cache must be cleared using the following T-SQL commands: |
| 200 | + |
| 201 | +```sql |
| 202 | +DBCC FLUSHAUTHCACHE |
| 203 | +DBCC FREESYSTEMCACHE('TokenAndPermUserStore') WITH NO_INFOMSGS |
| 204 | +``` |
| 205 | + |
| 206 | +Check that the login has been disabled by executing the following query: |
| 207 | + |
| 208 | +```sql |
| 209 | +SELECT name, type_desc, type |
| 210 | +FROM sys.server_principals |
| 211 | +WHERE is_disabled = 1 |
| 212 | +``` |
| 213 | + |
| 214 | +A use case for this would be to allow read-only on [geo-replicas](active-geo-replication-overview.md), but deny connection on a primary server. |
| 215 | + |
| 216 | +## See also |
| 217 | + |
| 218 | +For more information and examples, see: |
| 219 | + |
| 220 | +- [Azure Active Directory server principals](authentication-azure-ad-logins.md) |
| 221 | +- [CREATE LOGIN (Transact-SQL)](/sql/t-sql/statements/create-login-transact-sql?view=azuresqldb-current&preserve-view=true) |
| 222 | +- [CREATE USER (Transact-SQL)](/sql/t-sql/statements/create-user-transact-sql) |
0 commit comments