Azure SQL database - application user setup - sql-server

I am using Azure SQL database with sharding (single tenant approach). So, when the application connects to DB it goes into Shard and creates a proper connection to the tenant's DB (tenant is identified by login name).
However, we've been using a server admin credentials for that on a development stage.
Now, I'd like to create a separate application user with much more limited permissions compared to server admin.
In a very general case, what I want is to have a user that can connect to the Shard Map and figure out a connection string to any of the Shards, but have different permissions for each of the shards. For example, some application user may need to be able to connect to DB_1 with full read-write permissions, to DB_2 with read-only permissions and no permissions to connect to DB_3.
In a simpler case I just need a user that doesn't have any update permissions to ShardMap and other internal databases, but has a normal read/write/execute access to all tenant databases(shards).
I was googling around and din't find any good recipe how to do that, what are the best practices, etc.
I'd appreciate if someone could answer me or point to a docs.
Thank yuo!

In each database create a role for the Application Users, and grant the minimal permissions needed for the application to run. Granting permissions on the Schema level is a good choice here, as you don't have to manage object-level permissions.
create role ApplicationUsers;
grant select, insert, update, delete, execute on schema::dbo to ApplicationUsers;
Then if you want a single identity to access all the databases, create a login with a password. Then in each Tenant database create a user mapped to that login.
--create a server-level Login
create login AppUser with Password ='asdfAds01980(*)(*)(#&$)##';
--add a user mapped to that login in each database
create user AppUser for login AppUser;
alter role ApplicationUsres add member AppUser;
Or create a user in each database with a different password or a database user mapped to an Azure Active Directory identity.
create user AppUser with Password ='asdfAds01980(*)(*)(#&$)##';
alter role ApplicationUsers add member AppUser;
or
create user [tenant123user#mydomain.onmicrosoft.com] from external provider;
alter role ApplicationUsers add member [tenant123user#mydomain.onmicrosoft.com];

Related

Rotate passwords with zero down time

Big question: How to rotate passwords in an Oracle database in a zero downtime (ZDT) way?
My current thought is to rotate the users. Originally, I had MY_USER that had all the tables and such. Now, I have:
CREATE USER MY_USER NO AUTHENTICATION;
GRANT CREATE SESSION TO MY_USER;
CREATE USER MY_USER_PROXY_1 IDENTIFIED BY "abc123";
GRANT CREATE SESSION TO MY_USER_PROXY_1;
ALTER USER MY_USER GRANT CONNECT THROUGH MY_USER_PROXY_1;
When I want to rotate the password, I simply create MY_USER_PROXY_2 and give the 'connect through' grant to MY_USER. This way, the app can continue to create new connections until I deploy it using the new user. Because of the 'connect through', the new user is essentially the same as the old user so everything should continue to work without much fanfare. Afterwards, I can decommission MY_USER_PROXY_1 or let the password normally expire
This seems like a reasonable approach if there is 1 'physical' user (MY_USER)
However, I am already using proxy users for multi-tenancy. Same as before, but instead of 1 user, there could be hundreds of users going through the same proxy user:
CREATE USER TENANT_PROXY_1 IDENTIFIED BY "abc123";
GRANT CREATE SESSION TO TENANT_PROXY_1;
-- During tenant onboard
CREATE USER TENANT_1234 NO AUTHENTICATION;
GRANT CREATE SESSION TO TENANT_1234;
ALTER USER TENANT_1234 GRANT CONNECT THROUGH TENANT_PROXY_1;
The issue with creating TENANT_PROXY_2 is recreating all the connect through grants. I could iterate through all the users like 'TENANT_%' and apply the grant that way but will always be a window of opportunity after TENANT_PROXY_2 is created and updated with the grants BUT BEFORE the app is restarted to use the new proxy user. So it would add the grant to TENANT_PROXY_1 and thus fail when the proxy user is rotated to TENANT_PROXY_2
I tried using roles (both as the connector and the connectee) but looks like only users are supported:
ALTER USER TENANT_1234 GRANT CONNECT THROUGH TENANT_PROXY_ROLE;
GRANT ROLE TENANT_PROXY_ROLE TO TENANT_PROXY_1;
-- or
ALTER ROLE TENANT_PROXY_ROLE GRANT CONNECT THROUGH TENANT_PROXY_1;
GRANT ROLE TENANT_PROXY_ROLE TO TENANT_1234;
My only thought is to pre-create TENANT_PROXY_1 through TENANT_PROXY_N and apply the grant to all N proxy users during onboarding and manually round-robin through the N users. Not quite as graceful, but still seems reasonable
Any thoughts on either solution? Databases have been around for decades, is there any official solution or pattern to ZDT password rotation problem?

How to create different resource groups in azure SQL Database level which is associated with azure active directory

My requirement I have 20 users all are configured in azure active directory resource group.
I have one Azure SQL Server under I have 3 Azure SQL Databases like Dev, QA and UAT
In Active Directory configured 20 users I need different access in each database level, some people need only read access and some people need both write and read, etc.
Please help me to do this.
Is it possible to create users group in each database level with different roles for azure active directory users?
users can login SSMS with azure active directory credentials but each user having different access in each database
you can create groups in AAD and provide the groups/users access on the database individually.
Execute the below queries in individual databases:
1)
CREATE USER [GroupName] FROM EXTERNAL PROVIDER or
CREATE USER [xyz#abc.com] FROM EXTERNAL PROVIDER
2)
exec sp_addrolemember 'db_datareader', '<>' or
exec sp_addrolemember 'dbowner', '<>' etc based on the roles which you want to assign.
Note :
Since the user is not created at server level and directly at databases level, while trying to connect via SSMS ,
Put the database name explicitly.
Per my experience, you need manually configure the AAD users with different permissions or database role in each database.
In addition, you need connect to the Azure SQL with Azure AD admin account, only the admin account can do the operations for each database.
For example, one of the AAD user 'aa#abc.com' only needs have the read permission in database Dev but needs read/writer permission in database QA and UAT. User 'bb#abc.com' needs read/writer permission in database 'Dev' and read permission in 'QA' and 'UAT'. In each database, different users are derived to two roles. Then we can not configure group level permission for these AAD users in each database.
After doing that, all the users in your AAD group will have the different permissions in different database. When connect to the database with SSMS, current user can see all the databases which he has the permission to access. You also can choose the specific database in SSMS connection properties like #Nandan said.
HTH.

SQL server & Azure active directory - creating new contained azure ad guest users

I'm trying to create database users that are integrated with azure active directory. All of our users are guest users. I've been following multiple articles on how to create users in the SQL db but none have worked.
For example, this article: https://www.mssqltips.com/sqlservertip/5242/adding-users-to-azure-sql-databases/
Suggest to create users like so:
CREATE USER [name#domain.com]
FROM EXTERNAL PROVIDER
WITH DEFAULT_SCHEMA = dbo;
This yields the error:
Principal 'name#domain.comm' could not be found or this principal type is not supported.
Googling this error lands me on stackoverflow post (https://dba.stackexchange.com/questions/148325/add-active-directory-user-for-azure-sql-db):
which suggests:
CREATE USER [name_domain.com#EXT##<yourAzureSubscriptionPrefix>.onmicrosoft.com] FROM EXTERNAL PROVIDER
and accesses:
EXEC sp_addrolemember 'db_datareader', 'name_domain.com#EXT##<yourAzureSubscriptionPrefix>.onmicrosoft.com'
EXEC sp_addrolemember 'db_datawriter', 'name_domain.com#EXT##<yourAzureSubscriptionPrefix>.onmicrosoft.com'
and this does not give an error, but it also does not provide access to the database. Since I get error NT AUTHORITY/ANONYMOUS LOGIN
I also tried to create an AAD group and provide that group access, also no error here but couldn't login either.
Couple of notes:
All IP addresses are allowed on the firewall
all users have been added in sql db IAM (not sure if this is even necessary)
I've enabled Active Directory Admin in the sql server, I put the subscription admin here
This is also the users with which I created users in the SQL DB
I'm able to create native sql users without a problem
Still I'm only able to login using the Active Directory Admin, and no other user is able to login.
Any advice on how I can login to my Azure sql database using windows credentials from Azure Active Directory?
When using external users, you need to use the "mangled user principal name" when adding them.
That's this one:
CREATE USER [name_domain.com#EXT##<your-azure-ad-default-domain>.onmicrosoft.com] FROM EXTERNAL PROVIDER
Secondly, the users will be created only in that database; they cannot connect to master.
So you need to choose the DB to connect to.
You may also need to specify the AAD tenant id in advanced connection settings.
The reason you might need to do this is because by default an external user will login to their home tenant. Which is not the one connected to your DB. So you may need to specify the tenant to have them explicitly login against your tenant.

Security roles on master database in Azure SQL

I´m building an Azure SQL resource monitor, and I have to grant permission for a login to access the 'sys.resource_stats' on the master database of a Azure SQL 'server'. I can´t use neither loginmanager or dbmanager roles, because they grant some permission I don´t want to grant for a monitor application.
Is there another database role on the master database which i can add members?
I have recently created a special monitoring login/database user (see below) and I didn't find any reason to assign roles (I'm Azure noob thought).
Step 1
Create a login and a database user in master database:
-- in master database
-- create a login
create login <LOGIN> with password = '<PASSWORD>'
-- create a corresponding database user
create user <USER> from login <LOGIN>;
Step 2
Authorize the login to use a target database:
-- in target database
-- create a corresponding database user
create user <USER> from login <LOGIN>;
-- grant permission to view dynamic management views
grant view database state to <USER>;
In practice <LOGIN> and <USER> are the same, like foo_monitor.
See also:
Managing Databases and Logins in Azure SQL Database.
Which privileges does a user need to query used size in SQL Azure database?

Best way to create SQL user with read only permissions?

What is the best-practice to create a read-only user for a specific database?
I created a new user and granted the db_datareader role, however, this user still has access to the master db and other system databases. is that ok? or should i deny access on some system tables/databases as well to make it more secure?
Thanks.
Ok, so if i create a new user, will he have any more default permissions i have to deny?
if i do
~create login
~create user for login..
~grant EXECUTE for user
will the user only have EXECUTE permissions or will he have additional permissions as well for the active database?
Hi I believe the user can view other database in the object explorer too.
CREATE LOGIN me with password = 'me', check_policy = off
sp_changedbowner 'me'
GO
USE MASTER
GO
DENY VIEW ANY DATABASE TO me
GO
Well you can use denywrite as an role option. The user has to "see" the master, because the master contains the list of databases that he will enventually connect to, but he will only have guest privalages there. You can then deny access to other specific databases. AFAIK he does not need to see tempdb or msdb as its the SQL engine that accesses these

Resources