Azure SQL Contained User. Back-end can't connect using connection string - azure

I followed this guide https://www.mssqltips.com/sqlservertip/5242/adding-users-to-azure-sql-databases/ to create a new user for my back-end API with restricted permissions for basic security reasons but can't make the back-end connect to the server. Every time it tries to connect I'm getting
System.Data.SqlClient.SqlException: 'Login failed for user 'xxxx'.'
I'm able to log-in this new user via SSMS by setting the target database in the login window options.
The back-end can connect just fine with the default connection string supplied by the Azure Portal, witch uses the server admin login. Changing the username and password for the new user, keeping the Initial Catalog to my desired database does not work.
I would assume the back-end would be able to access it since the Initial Catalog property of the connection string is set to the database the contained user was created on. But nothing is working.
This is my connection string used on my back-end:
Server=tcp:xxx.database.windows.net,1433;Initial Catalog=dbName;Persist
Security Info=False;User
ID=newUser;Password=newUserPw;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection
Timeout=30;
I tried many guides but none worked before I found this one that seems to be very knowledgeable about creating Azure SQL users, but even so no luck so far.
This are the commands I used to create the user on the DB I need it to connect(ofc with my own values):
-- select your db in dropdown and create a contained user
CREATE USER [test]
WITH PASSWORD = 'SuperSecret!',
DEFAULT_SCHEMA = dbo;
-- add user to role(s) in db
ALTER ROLE db_datareader ADD MEMBER [test];
ALTER ROLE db_datawriter ADD MEMBER [test];
Anyone knows whats going on? I don't want to have to use my admin login on my back-end.

Turns out the straight answer is to set
Persist Security Info=True;
in the connection string.

When username and password are included in connection string, security-sensitive information such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state unless you set Persist Security info to true.
Reference: Persist Security Info , sqlconnectionstringbuilder

Related

Using a MongoDB Atlas database; how does one set up user accounts, if a user account/password is required to access the DB? (Node, express, mongoose)

Alrighty, so I have a MongoDB Atlas database set up, containing several objects. My current API has several get, post, put and delete end points which are working correctly. However, I am in the process of setting up user accounts and I am a little confused.
My project is built with React on the front end and my server is built with Node, express and mongoose. My goal is that of your typical web application and is as follows:
Go to main web app URL
Home page is a login or "create an account" screen.
Once logged in (or an account is created and you sign into it) you will then have access to get, post, put and potentially delete (if an admin) objects in my DB.
I have built a very basic sign-in, sign-out and "register an account" server which is working however, I am confused as to how to properly go about integrating this with the rest of my API. I currently have the server connecting to my Atlas DB using what is provided in the "connect" menu in the Atlas dashboard (without the < >)
mongodb+srv://<username>:<password>#<cluster-name>.ntwp5.mongodb.net/<collection-name>
Obviously, the username and password (which I can set in my Atlas dashboard) needs to be passed into the "username" and "password" fields in-order to connect to it. I was planning to use the same cluster and have a separate collection for users and my data.
What's confusing me is that in-order to connect to the MongoDB server above and gain access to the two databases, I need to pass in some username/password. However, in order to create an account (ie, creating a new username and password), I would already be utilizing a username and password to connect to the server.
So say I have a group of people in the same company using this application. Would I essentially have a single administrative username/password used by everyone to connect to the server URL? From there, users would be able to access the "users" collection and create an account. Do I then setup my existing API routes (which point to my collection of data) to check that the "signed-in" user exists before returning a successful request and access to that collection?
Or perhaps, the proper way is to use two completely separate databases; one for users and one for my data?
Sorry, I am new to working with Databases and I think the above makes sense to me but I want to verify if that is the correct way to go about handling this. Thanks!

Replicate db_datareader permissions for connecting to Azure SQL from external javascript

I am trying to tighten up security on connecting to our Azure SQL database by creating custom roles and users, depending on what access to the database is needed. Most of our connections are done via Google Apps Script and have previously used the admin login.
I know it is good practice to not use the db_datareader / db_datawriter roles, but I'm having connection issues whenever I use a custom roles/ users and our scripts. The custom user accounts / roles work fine in SSMS but when I use our Google Apps Script I get:
Connection URL is malformed
I know the account is authenticating because if I use the wrong password I get a different error. Additionally, the script still works fine with the original database admin account and a test account I made assigned to db_datareader role. Accounts with db_datawriter roles work fine as well. So I believe this error message has nothing to do with the actual connection URL.
There seems to be some permission granted by db_datareader / db_datawriter that allows for external scripts to connect and run and I am unsure how to replicate that. Perhaps something that to do with querying a list of the tables that the account /role has access to?
Here is a screenshot of the custom role's permissions, I have omitted database and table names, but these are all on the same database and differing tables and scalar functions that the script needs:
new role permissions
Any idea of what I can try to replicate these 'built-in' roles?
Check that your custom role resides in database scope (Expand DB in SSMS -> Security...)
Ensure your user is an assignee of the role
Check your connection string references a database name
Set the default database for the user from the user properties pane
To get the permissions of a role you could use one of the scripts in this thread.

Using Excel as the front end, Azure as the backend

I have a SQL Database on Azure to which I can successfully get connected from within an Excel file. I am using ADO and the connection string uses my own username and password. Since this file will be used by many users, how can I create a generic login and password so that I would not give out my own username and password in the code? The Excel file runs many VBA macros to communicate with the Azure SQL database.
I am using Excel 2010 (yeah, it is old, I have to) and this is my connection string:
mstrConnectionString = "Driver={SQL Server Native Client 11.0};" & _
"Server=tcp:<servername>.database.windows.net,1433;" & _
"Database=<databasename>;" & _
"Uid=<myusername>#<servername>;" & _
"Pwd={MyPassword};" & _
"Encrypt=yes;Connection Timeout=30;"
According your comment, I have an idea that you can create a new login/user for you Azure SQL database.
Then you use this user and password as public account to get or writer data from your Azure SQL database within Excel.
Here's the example T-SQL statement, this code is create a new login and a user in your Azure SQL database. You can run this query in SSMS:
--running in master db
USE [master]
GO
CREATE LOGIN [sagarreadonly] WITH PASSWORD='password'
GO
-- running in Azure SQL DB
USE [DataEncryptDemo]
GO
CREATE USER [sagarreadonly] FOR LOGIN [sagarreadonly] WITH DEFAULT_SCHEMA = Marketing;
GO
EXEC sp_addrolemember 'db_owner', 'sagarreadonly';
GO
The new user is created as 'db_owner' to the specified database.
For more details about database roles, please see Database-Level Roles.
About login and user:
A login is used for user authentication
A database user account is used for database access and permissions
validation.
Logins are associated to users by the security identifier (SID). A login is required for access to the SQL Server server. The process of verifying that a particular login is valid is called "authentication". This login must be associated to a SQL Server database user. You use the user account to control activities performed in the database. If no user account exists in a database for a specific login, the user that is using that login cannot access the database even though the user may be able to connect to SQL Server.
A Login is an identity used to connect to a SQL Server instance. A User allows you to log into a SQL Server database and is mapped to a Login. So you will need to first create a Login, before you can create a User in SQL Server.
Hope this helps.
You can create a "Database login" dialog box to prompt a user for database connection information by using text boxes, buttons, or other dialog box controls. Typically, when you type text in a text box, the text appears as you type. However, you can use a property of the Microsoft Visual Basic for Applications (VBA) Edition User Form to create the effect of a hidden or "masked" text box for creating a password dialog box, where you do not want the text that is typed in a text box to be "visible". Here you will find how to do that.
The information the user types on the "Database login" can be used to build the connection string you posted above.
To create a custom dialog in Excel please follow this instructions.

IBM Lotus java XPage rest service - does it require signing for each user?

I have made a Java ExtLib XPage custom REST service (CustomServiceBean) database basing on this solution: https://setza-projects.atlassian.net/wiki/spaces/RS/pages/363593730/IBM+Domino
I modified it though to use NotesCalendar class to create, update and delete events & resource reservations (so everything in fact is processed by the calendar, I'm only using raw documents for reading $Rooms in names.nsf and $Reservations in the reservations database). Everything works fine so far, it uses current session to open the calendar. I have some concerns regarding the permissions though.
What I want (and need):
Ability to create calendar events & reservations as SPECIFIC users, I don't want just one "main" user that will create everything. I want each IBM Lotus user to be able to login with their credentials and create or update their calendar events.
This database with XPage will be deployed on our client's servers, so I don't want to require some special configuring for each user in order to be able to access my REST service.
I set up a new local installation of Lotus Server and created a new application using my XPage database as template, and I couldn't access the API neither with admin account or other accounts:
HTTP JVM: CLFAD0229E: Security exception occurred servicing request for: /db.nsf/services.xsp/api - HTTP Code: 403. For more detailed information, please consult error-log-0.xml
As soon as I added my admin account to Server configuration -> Security -> Sign or run unrestricted methods and operations, it started working again. Not only for the admin account, but also for other accounts that were just created with an internet password and weren't assigned any specific roles or permissions. I didn't even sign the database.
So my question is, is this enough in order to get it working on client's production server? It kind of makes no sense to me, but it worked on my local server so I'm not sure, I'm new to IBM Lotus and I'm just doing an integration REST service.
If not, how could I do it, so I wouldn't really need to put the end client (Lotus server owner) into the hassle of configuring each user, while still being able to access the API as any Lotus user (providing the username and password)? I can either log-in as each indepentend user, or perform some impersonation with a "main" privileged account (create entries in someone else's calendar as him), although I think there is no way to do it in Java, because .getCalendar is a method of the Session class, I tried using createSession(), but I wasn't able to.
Every notes application needs to be signed by an administrator with an ID known to the customers environment. The Id which is used to sign the db must have the appropriate rights, through the security tab in the server document. If the app is not signed properly, the app won't run. Once the app is signed, it runs in the authorized users session with the users rights.

Connecting to a Database with WinAuth

In response to a question I asked about a week ago I changed our database engine to only accept Windows Authentication instead of SQL Authentication. Because our code runs in a different user context then that of the database connection we need to specify the username and password information in order for us to connect to the database. How do we do this using a ConnectionString? Remember, we are not using SQL Authentication anymore.
Thanks,
On your SQL Server instance, you need to add the domain group under the Security node (the one in the main server group, not in the individual databases). Under that node, the end result would be an item that resembles
<Your Domain>\Domain Users
Then in your application (Windows or Web) connection strings you want to set integrated security to be TRUE, and elsewhere, you need to set Impersonation to also be True. I am being vague here because the methods vary by application type.
Hopefully that sets you on the correct path.
Since you are using only Windows authentication, you can't in the connection string. The calling process will need to impersonate a windows principle (user) with the relevant access permissions.

Resources