*** Apologies folks - I appended wrong code ---now replaced below here
I have a simple Visual Studio .NET web forms app. I run it on my Azure VM called dexram (Windows 10) and I also created a SQL Server on the Azure VM. There is a user on the VM called 5001211 that has admin authority in Windows. It can use SSMS to access the database no problems.
All my connection string attempts fail in the C# code. This is strange as the VS web app and the SQL Server are both running on the Azure VM.
Here are the strings I tried and the messages I got underneath:
string Server = "Data Source = dexram; Initial Catalog = FruitNVeg; User ID=5001211;Password=Fitsh3ly;";
This connection string throws an error:
Login failed for user '5001211'
string Server = "Data Source = tcp:dexram,1433; Database = FruitNVeg; User ID = 5001211#dexram; Password = Fitsh3ly; Trusted_Connection = False; Encrypt = True;";
The certificate chain was issued by an authority that is not trusted
string Server = "Data Source = tcp:dexram,1433; Authentication = Active Directory Integrated; Database = FruitNVeg;";
The certificate chain was issued by an authority that is not trusted
string Server = "Data Source = tcp:dexram,1433; Authentication = Active Directory Password; Database = FruitNVeg; UID=5001211#dexram;PWD=Fitsh3ly;";
The certificate chain was issued by an authority that is not trusted
Thanks Dan - no luck - I created as per your suggestion and made 5001211 sysadmin and got following results:
string Server = "Data Source = dexram; Initial Catalog = FruitNVeg; User ID=5001211;Password=Fitsh3ly;";
Gives -- > Login failed for user '5001211'
string Server = "Data Source = tcp:dexram,1433; Database = FruitNVeg; User ID = 5001211#dexram; Password = Fitsh3ly; Trusted_Connection = True; Encrypt = True;";
Gives -- > The certificate chain was issued by an authority that is not trusted
I am thinking I need to get a cert. created as I think (?) my SQL calls from my VS app are going out over the internet (even though the 2 tools (VS and SQL Svr) are on the same VM machine) ?
you must first create a user in sql server after use from string format below
Data Source=instanse name or use .;Initial Catalog=database bame;User ID=created user in sql server;Password=your password
and do setting below for user
User dexram\5001211 is a Windows account. Your app connection string specifies a SQL login named 5001211. You need to create a SQL login named 5001211 and an associated database user:
USE FruitNVeg;
CREATE LOGIN [5001211] WITH PASSWORD = 'Fitsh3ly';
CREATE USER [5001211];
The user will also need permissions on the objects the application uses in the FruitNVeg database. Although you could add the login to a privileged role like sysadmin to avoid granting these permissions, the best practice is to use a minimally privileged account for routine application database access that has only the required permissions:
USE FruitNVeg;
GRANT SELECT ON dbo.Apples TO [5001211];
As per this URL --> https://blog.greglow.com/2020/01/16/sql-sql-server-the-certificate-chain-was-issued-by-an-authority-that-is-not-trusted/
I used the sql config manager and set "Trust Server Cert" to yes and that fixed the problem it seems
Related
I'm trying to access a serverless azure SQL database from an Azure Web Application running a docker container under Linux. The container is a .Net Core 3.1 web application using the latest EF Core. The web app has been configured to use a system assigned identity.
For the SQL user, I use the following PS script to get an SID, where the object ID is the system assigned identity object ID:
$principal = Get-AzADServicePrincipal -ObjectId $objectId
foreach ($byte in $principal.ApplicationId.ToByteArray())
{
$byteGuid += [System.String]::Format("{0:X2}", $byte)
}
$sid = "0x" + $byteGuid
Then, I created the user with db_owner role to the database using the SID like this...
'CREATE USER [AppUser] WITH DEFAULT_SCHEMA=[dbo], SID=' + '$(AppSiD)' + ' , TYPE = E'
...similar to the process described here:
https://blog.bredvid.no/handling-azure-managed-identity-access-to-azure-sql-in-an-azure-devops-pipeline-1e74e1beb10b
I've also updated the EF instance using the following method:
https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi#modify-aspnet-core
When the application tried to access the DB, the following exception is thrown:
Microsoft.Data.SqlClient.SqlException (0x80131904): Login failed for user '<token-identified principal>'.
EDIT I don't believe the SQL user to be causing the issue, as the error occurs whether the user exists or not.
I'd prefer to fix the error above but if there is is an alternative way to connect to the DB without using a SQL user I would appreciate the advice.
Thanks
EDIT
Elaborated on the SQL user process as the link is down at the time of posting
First you need to make your SQL database AAD-enabled. Then you can create a user for your Managed Identity like this
CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER;
And then of course assign permissions to that user as needed.
We have a SSIS package which accesses database columns which are encrypted using Always Encrypted.
This does not work when triggering the SSIS package through a SQL job using a proxy user.
Failed to decrypt a column encryption key using key store provider 'mssql_certificate_store'
We have tried logging in to the server as the domain user and triggering the SSIS package manually and we don't receive this error. So it seems that there is some issue accessing the certs when a proxy user is activating the ssis package.
Code for the setup of the proxy user:
CREATE CREDENTIAL [SSIS Credential]
WITH IDENTITY = N'DOMAIN\service_ssis_user', SECRET = N'DomainPassword'
IF NOT EXISTS (SELECT name FROM sysproxies WHERE name = 'SSIS Package')
BEGIN
EXEC msdb.dbo.sp_add_proxy
#proxy_name = N'SSIS Package',
#credential_name = N'SSIS Credential', #enabled = 1
EXEC msdb.dbo.sp_grant_proxy_to_subsystem
#proxy_name = N'SSIS Package', #subsystem_id = 11
EXEC msdb.dbo.sp_grant_login_to_proxy
#proxy_name = N'SSIS Package',
#login_name = N'DOMAIN\service_ssis_user'
END
GO
The aim is to get the SSIS package running as the domain user and able to access the certificates associated with this user
Update:
The proxy user does not "login" as the user that I have created credentials for, it simply uses the security context of the user to run the command. So it does not load their windows user profile which would happen when logging in directly as the Domain User. And therefor the certs are not accessible when running via proxy. I dont know how to get around this issue however.
Windows user profile is not Loaded when a proxy account is used. As a result the certificates associated with the user are not accessible when running via proxy.
My current application uses very powerful credentials to access the SQL Server back-end database. I want to improve the security in my application by using an application role created.
For example, if I created one called app-role, with a password:
EXECUTE sp_addapprole #rolename = 'app-role', #password = `right pony duracell binderclip`
I want to enable the use of this application automatically during connection by specifying it in a connection string. I don't want to risk there being any places in the software that are accidentally not re-engineered to call:
EXECUTE sp_setapprole #rolename = 'app-role', #password = `right pony duracell binderclip`, #encrypt = 'odbc'
So obviously I want this to happen automatically during connection.
Bonus Chatter
The application roles feature was first added in SQL Server 2000.
Bonus Reading
How to to use SQL Server application role in my connection string
I try (for the first time) to create a user account on my SQL Azure database.
I have read in some blogs that I have to create these command lines
CREATE LOGIN login_name WITH PASSWORD = 'strong_password';
CREATE USER 'user_name' FOR LOGIN 'login_name';
And then
USE [Database];
GO
GRANT CONNECT TO login_name;
But, when I try to connect with this new account on my database, I have the message error 916
The server principal "login_name is not able to access the database "master" under the current security context.
I don't understand because the don't create my new user for the master but for a specific database in my SQL Azure environment (I have 5 databases in my SQL Azure by the way)
If you have any idea to help me, thanks in advance
When first logging in, unless a database is specified in the connection string, a login connects to its default database. If the database is not specified in the CREATE LOGIN statement, the system default of master is used.
To fix this, use this for your CREATE LOGIN:
CREATE LOGIN login_name WITH PASSWORD = 'strong_password',
DEFAULT_DATABASE = MyDatabase;
I'm trying to script a creation of SQL Server identity to be then used to execute SQL Server agent jobs via a proxy.
It looks as though I can only use a Windows account and thence I would have to provide its password in plain text. Seriously? There must be a better way to do this. I need this script to work on my team-mates' machines as well as mine:
USE [msdb]
CREATE LOGIN [proxy_login] WITH PASSWORD=N'passw0rd',
DEFAULT_DATABASE=[SSISConfig], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
CREATE CREDENTIAL [my_cred] WITH IDENTITY='proxy_login', SECRET='passw0rd'
EXEC msdb.dbo.sp_add_proxy
#proxy_name=N'My_Proxy',
#credential_name=N'my_cred',
#enabled=1
Error:
Msg 14720, Level 16, State 1, Procedure sp_verify_credential_identifiers, Line 69 [Batch Start Line 0]
The operation failed because credential '#credential_name' identity is not a valid Windows account
In ideal world I would like to use the SYSTEM_USER login for the credential without having to supply their password.
Yes your assumption is right, credentials cannot be created for SQL Server logins it can only be Domain users (visible from your SQL Server), and yes you have to pass the password when creating credentials.
Once credentials has been created one or more proxies can use them.
Typically proxies in SQL Server are used to facilitate cross domain processes. A process executing (probably SSIS job etc.) on DomainA\ServerA at run-time will access databases on DomainB\ServerB, The user account running the job on DomainA\ServerA must have access to DomainB\ServerB. Now in this case a proxy on DomainA\ServerA can be used with the credentials of a User, let say UserB from DomainB with access to ServerB etc. The proxy at run-time when reaches to DomainB will provide the credentials for UserB and the process can continue to run.
SQL Server Agent jobs which run via Proxy needs Credentials. These credentials will usually accept windows username-password.
Better way:
If you're concerned with the security aspect, I will suggest you create a Powershell utility which will prompt for windows username, password(star marked) and set it directly in credentials and create proxy out of that via sql query execution.
sample(.ps1 file):
# read from user input
$Winpwd = read-host "Enter windows Password for ""$(whoami)""" -AsSecureString ;
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Winpwd)
$Winpwd = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
#execute sql
Add-Content main.sql "CREATE CREDENTIAL SSISAdmin WITH IDENTITY = '$(whoami)', SECRET = '$Winpwd';"
Add-Content main.sql "GO"