Specified username in connection string gets replaced at runtime - sql-server

I have a web site project as an entry point and defined the connection string there:
"ConnectionStrings": {
"DataPlaygroundConnection": "Server=DataPlayhouse;Database=BusinessHandshake;User ID=bhuser1;Password=bh#12345;MultipleActiveResultSets=True;Connect Timeout=360;App=Company - Portal - Staging"
}
I started facing issues just recently that when running, I'd get Login failed for user 'bhuser1' error. But the credentials are working as I can connect to DB with any DB Manager (SSMS). Then I added Serilog to understand whats happening as the exception was thrown from Program.cs
After adding Serilog, I find this exception block:
10/20/2020 07:54:49 +04:00 Application Starting.
10/20/2020 07:54:49 +04:00 Using an in-memory repository. Keys will not be persisted to storage.
10/20/2020 07:54:49 +04:00 Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.
10/20/2020 07:54:49 +04:00 No XML encryptor configured. Key {a012bed6-42e0-475d-a11d-44ae3a5599a9} may be persisted to storage in unencrypted form.
10/20/2020 07:54:58 +04:00 An error occurred using the connection to database '"BusinessHandshake"' on server '"DataPlayhouse"'.
10/20/2020 07:54:58 +04:00 An exception occurred while iterating over the results of a query for context type '"Folio.Infrastructure.Data.Contexts.PlaygroundBiContext"'."
""Microsoft.Data.SqlClient.SqlException (0x80131904): Login failed for user 'bhuser1'.
The credentials in the json file are correct and I am able to use the same credentials in Azure Studio to connect to the database.
I do not have any customization code in context:
public partial class PlayHouseContext : DbContext
{
public PlayHouseContext()
{
}
public PlayHouseContext(DbContextOptions<PlayHouseContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("");
}
}
}
I have a similar error on my local dev machine: SqlException: Login failed for user 'bhuser1'.
On my dev machine, the credentials are correct and I can use SSMS to easily access the said DB and all the elements within.
I'm unable to understand this one.

Thanks #DaleK.
Trusted_Connection means windows authentication. I had to remove that and do the same in the appsettings.Development.json as well.

Related

SQL Server 2016 Always Encrypted Timeout at Published IIS

I Have strange problem when i tried to publish my asp.net mvc application to my local (pc) iis with "Always Encrypted" Enabled.
My application keep timeout when i tried to access database using EF6 at local IIS (not express) :
But if i tried to access & debug my asp.net mvc app using Visual Studio 2017, database with 'always encrypted enabled' can be accessed perfectly without timeout.
And also i can access it with SQL Management Studio without problem.
Both (SMSS & ASP.NET web config) using this configuration.
Column Encryption Setting=enabled;
Note : I'm using ASP.NET MVC 5 & EF 6, SQL Server 2016 Developer Edition.
Sorry for my bad english.
UPDATED :
I have tried using .NET Framework Data Provider to see if there's any clue that'll help me solving this issue, Using following code :
var context = new TestDevEntities();
StringBuilder sb = new StringBuilder();
string connectionString = context.Database.Connection.ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand(#"SELECT [id],[name],[CCno] FROM [TestDev].[dbo].[testEncCol]", connection, null, SqlCommandColumnEncryptionSetting.ResultSetOnly))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
sb.Append(reader[2] + ";");
}
}
}
}
}
above code show me this error :
Now, with this kind of error i know i exactly i must do :)
Change the identity of application pool to the 'user' who previously generated the certificate.
Export currentuser cert (used by always encrypted) and import to the user that you want to use as application pool identity.
Now its worked!
EF should throw some kind of error as clear as .NET Data Providers do, instead of timeout failure that really confuse me #_#
UPDATED (1) :
Now the question is how to use it (Certificate) with default ApplicationPoolIdentity instead of custom account?
UPDATED (2) :
I have done what jakub suggest, but still no luck.
Thanks
One way (could be the only way) to use the DefaultAppPool identity instead of a custom (user) account is to store the certificate in the Local Machine certificate store (not Current User).
Once you create a certificate in the Local Machine certificate store, you need to grant DefaultAppPool access to the cert. You can do that using Microsoft Management Console (and the plugin for Local Computer certs):
Right click on the cert, select All Tasks > Manage Private Keys.
Click Add.
Set location to your computer (not your domain).
Enter IIS AppPool\DefaultAppPool as the object name.
Click OK twice.

Identityserver4 - Hosting in IIS

How to host ASPNET CORE APP with IdentityServer4 in IIS. The app is running fine from localhost but not as a web application setup in IIS.
For Example,
http://localhost:5000/connect/token is working but http://example.com/myauthapp/connect/token is not reachable - returning 500 - internal server error when tried from a console app using identity model or via postman. I am able to login to the app using web browser but not thru a console app or postman.
Further Troubleshoot and I find the below.
An unhandled exception has occurred: IDX10638: Cannot created the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.RsaSecurityKey.
System.InvalidOperationException: IDX10638: Cannot created the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.RsaSecurityKey.
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt)
at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
How can I solve this issue?
As Arun noted in his comment, the certificate has to be installed on the server.
1 . To test this on localhost first, make sure you are using "AddSigningCredential" not "AddTemporarySigningCredential".
services.AddIdentityServer()
.AddSigningCredential(new X509Certificate2(Path.Combine(_environment.ContentRootPath, "certs", "IdentityServer4Auth.pfx")));
//.AddTemporarySigningCredential()
;
Create the certificate in your project (create certs folder), running this in visual studio command:
"C:\Program Files (x86)\Windows Kits\8.1\bin\x64\makecert" -n
"CN=IdentityServer4Auth" -a sha256 -sv IdentityServer4Auth.pvk -r
IdentityServer4Auth.cer -b 01/01/2017 -e 01/01/2025
"C:\Program Files (x86)\Windows Kits\8.1\bin\x64\pvk2pfx" -pvk IdentityServer4Auth.pvk
-spc IdentityServer4Auth.cer -pfx IdentityServer4Auth.pfx
Test on localhost
If successful, deploy to iis server , install the certificate on the server by double clicking on it, and test.
Make sure the application pool "load user profile" is set to true :
Go to IIS Manager
Go to the application pool instance
Click advanced settings
Under Process model, set Load User Profile to true
Restart IIS
If this fails with a 500, like with me (and there is no logs to help you out), try this. To fix this recreate the certificate on the server the same way as in step 2 in the certs folder . double click the cert to install.
You might have to install the developer kit if you dont have visual studio installed:
https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk
A little background first, on why it is working on your Local Development computer and not running under IIS on a QA or Production Environment. If you are using Temporary Signing Credential when adding the service Identity Server 4 like so,
services.AddIdentityServer().AddTemporarySigningCredential();
Then you have to make sure the "User" that the "Process" is running as has a Private Key available for ID4 to create a Temporary Certificate. This is why the error message is
SignatureProvider, 'key.HasPrivateKey' is false, cannot create
signatures. Key: Microsoft.IdentityModel.Tokens.RsaSecurityKey.
In the case of Windows, this private key is generated by Windows automatically and can be found at the folder %APPDATA%\Microsoft\Crypto\RSA of the User or C:\Users\Username\AppData\Roaming\Microsoft\Crypto\RSA. The reason why this Private Key is missing is perhaps because the User that your Process is running as has never logged onto that Computer.
The likely SOLUTION in that case is to log in once as the User that will be running the Process on that Server. It is quite common for the Private Key directory to be missing if your Application Pool within IIS runs as a "non-service" user with very High Privileges and that user has never interactively logged onto the Server itself. This also explains why "localhost" works on your development computer, while running on a Production or QA Server may not.
More information on how and where Windows creates the Private Key for a User can be found here in this link Microsoft Key Storage and Retrieval. Also, it is recommended as mentioned by David Smit to explicitly specify a Private Key file, instead of using Temporary Signing Credentials. That is the cleaner solution if you are allowed to make code changes.
services.AddIdentityServer()
.AddSigningCredential(new X509Certificate2("C:\Certs\IdentityServer4PrivateKeyFile.pfx")));

Code-first MVC 4 using Entity Framework and SQL Server 2012

This question is not about SQL Server "3xpr355" (the obfuscation
in quotes is by design; it should prevent future searches from hitting
dead-ends, as mine have done).
I am using code-first and Entity Framework to develop an MVC 4 application. The SQL Server, IIS, and Visual Studio are all running on the same machine.
I was originally using SQL Server "3xpr355" but the requirement to put it on an exposed-to-the-Internet-via-ISS machine made hooking it up to a full-featured SQL Server necessary. I have the application set up to drop and re-create the database whenever the models change:
public class XyzDBContext : DbContext
{
public XyzDBContext()
: base("XyzDBContext")
{
Database.SetInitializer<XyzDBContext>(new DropCreateDatabaseIfModelChanges<XyzDBContext>());
}
public DbSet<XyzModel> XyzModels{ get; set; }
}
Here are my connection strings:
<connectionStrings>
<add
name="DefaultConnection"
connectionString="Data Source=.;Initial Catalog=aspnet-Xyz-20150131102119;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
<add
name="XyzDBContext"
connectionString="Data Source=.;Initial Catalog=XyzDatabase;Integrated Security=True"
providerName="System.Data.SqlClient"/>
</connectionStrings>
Expectations:
Execution of the portions of the application that use XyzDBContext should cause the database "XyzDatabase" to be created (if necessary).
Execution of the portions of the application that use the Membership Provider should cause the database "aspnet-Xyz-20150131102119" to be created (if necessary).
Actual Results:
Exception is thrown: System.Data.ProviderIncompatibleException "An
error occurred while getting provider information from the database.
This can be caused by Entity Framework using an incorrect connection
string. Check the inner exceptions for details and ensure that the
connection string is correct."
Inner Exception:
System.Data.ProviderIncompatibleException "The provider did not
return a ProviderManifestToken string."
Inner Exception:
System.Data.SqlClient.SqlException "Login failed for user
'DOMAIN\SERVER$'."
Measures:
I have tried using SQL Server Management Studio to add a login for the "DOMAIN\SERVER$" user, but the login always fails.
I have researched and tried many permutations of the connection strings, all but a few of the examples I have found were for use with SQL Server "3xpr355".
Well if you map each connection string (database) to it's own DbContext the you could reach your expectations but you still have to work with two contexts (which is painful).
Your third actual result is due to IIS that can't connect to the database. You have to go to IIS manager and change the identity of the application pool under which your application runs (You can change it to LocalSystem)
Finally, try this if you have already the databases created:
public class DefaultConnectionContext : DbContext, IDisposable
{
public DefaultConnectionContext()
: base("name=DefaultConnection")
{
Database.SetInitializer<DefaultConnectionContext>(null);
}
// Some dbsets
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
public class XyzDBContext : DbContext, IDisposable
{
public XyzDBContext()
: base("name=XyzDBContext")
{
Database.SetInitializer<XyzDBContext>(null);
}
// Some dbsets
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Hope That helps
The solution to this problem is multifaceted:
Create an Application Pool
In IIS Manager, visit the "Application Pools" node and select the "Add Application Pool..." Action:
Select the new Application Pool and select the "Advanced Settings..." Action, then select the "..." button (on the "Identity" field):
Set the Application Pool identity to "LocalSystem"
Grant Permission
In SQL Server Management Studio (when connected to the database service), visit the "NT AUTHORITY\SYSTEM" node under "Logins" and bring up the "Properties" view, then select the "Server Roles" page, and grant all of the privileges by selecting the check-boxes:
In IIS Manager, Right-click on your site and select "Manage Application/Advanced Settings..." and Set the "Application Pool" property value to "CodeFirstMVC".
Run the Application
Run the application and visit the areas that would require a new database to be created; you should now see a new database on your SQL Server instance.

how to configure connection to the database in clouds services

I have surfed the web for two days looking for a better way to configure my application that I am uploading to AppFog so that it successfully connects to the mysql database in the cloud.
I have created the mysql service and I did bind it to the application. I also created tables and put some data on them using the local console ( using af tunnel mydatabase) in linux
but my apps does not seem to find the database. My application uses JDBC ... I used the database username and password and databasename given to me from the console (those funny chars in the screen) and it did not work. so I put my own credentials, still, no success...
I tried using the url that points to my application at the port given to the on the console, but still... actually, I put in the details the showed on the console to connect to the database in the cloud after deploying ... but my app seems not to find my database and its tables....
I do not know what is wrong...
please help..
MORE:
This is the code I used to try this connection:
try {
String connectionURL = "jdbc:mysql://http://someapp.aws.af.cm:10000 /OnlinePassword";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(connectionURL, USER, PASS);
statement = conn.createStatement();
}
Use appfog environment variable called VCAP_SERVICES to automatically detect your MySQL database credentials and connection info. You can take advantage of this to display all the info which will be in JSON format and use it to connect your app to MySQL database. You may try this.
First create a servlet and retrieve your database connection using a context attribute as follows:
public class DbInfoServlet extends HttpServlet
{
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
{
request.setAttribute("jsonContent", java.lang.System.getenv("VCAP_SERVICES"));
request.getRequestDispatcher("/index.jsp").view.forward(request, response);
}
}
Then create a index.jsp file to display you DB connection info as follows:
<body>
<p>
<!-- Click here to display DB info -->
<!-- Display of your DB connection and credentials info is here. This will show in JSON document format
-->
<c:out value="${jsonContent}" />
</p>
</body>
Use hostname(i.e. IP), port, name(i.e. database name), username, password parameters from JSON document content to modify your JDBC connection code as follows:
try {
String connectionURL = "jdbc:mysql://hostname:3306/name";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(connectionURL, username, password);
statement = conn.createStatement();
}
If the above doesn't work, simply ensure that you are using the latest version of MySQL-connector-java jar file.
Have fun!

No Process Is on the Other End of the Pipe

I receive this error when I try to connect to SQL Server 2005. I have enabled TCP/IP, Named Pipes, and restarted the server but that is not working.
For me the issue was that the SQL server was in Windows Authentication mode only, even though I set it to mixed during the install.
In the object explorer, right click on the server, properties and then the Security page and set Server authentication to SQL Server and Windows Authentication mode.
FYI, I've just had the same error.
I switched to Windows authentication, disconnected, then tried to login again with SQL authentication. This time I was told my password had expired. I changed the password and it all worked again.
I tried the troubleshooting steps in both microsoft tech articles, and oddly no luck.
I managed to fix the solution by changing my authentication from SQL Server Auth to Windows Auth. Though I am not sure the technical reason why this works?
It may help to make sure the database specified in the initial catalog exists.
I got this error when I (deliberately) reduced the configuration of maximum SQL Server memory to 16Mb and restarted.
So it might be a memory issue.
I encountered this problem when the password for the login that I was attempting to connect with had expired.
One another reason for this error message could be the case when you've deleted the database your application uses, and you didn't run the following commands from your visual studio:
Add-Migration MigrationNameHere
Update-Database
I assume you have seen this:
http://technet.microsoft.com/en-us/library/ms175496.aspx
how about this?
http://blogs.msdn.com/sql_protocols/archive/2006/07/26/678596.aspx
1st check the Window's Event Log for the following error:
Could not connect because the maximum number of ’1′ user connections
has already been reached. The system administrator can use
sp_configure to increase the maximum value. The connection has been
closed.
To solve the problem do the following:
Open Microsoft SQL Server Management Studio
Open a new query
Type the under given code and press the execute button
sp_configure ‘show advanced options’, 1;
GO
reconfigure
GO
sp_configure ‘user connections’, 0;
GO
reconfigure
GO
Source: http://www.windowstechupdates.com/microsoft-sql-server-error-233-no-process-is-on-the-other-end-of-the-pipe/
In my case make sure that your connection string has ;password=
A connection was successfully established with the server, but then an error occurred
during the login process. (provider: Shared Memory Provider, error: 0 - No process is
on the other end of the pipe.) (Microsoft SQL Server, Error: 233)
This error will occur when the login does not have an active "Default Database" assigned.
In my case this occurred after taking a DB Offline. The previous DBA had assigned a non-system DB as the Default DB for a login. After that DB was taken offline, the login failed threw this error 233.
To Check & Fix this...
Login to the SQL Server Instance via SSMS using a different login.
Go to... >> Security >> Logins >> {Login Name} >> General
Check the "Default Database" is set to an active DB (I reverted back to 'master').
Logout & then try logging in again using the login that was just updated.
in my case :
it was blocked by Symantec AV and firewall
just for trial I have to disable symantec n firewall
i think i'll have further checking
If you have created the migrations, you could execute them in the Startup.cs as follows.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.Migrate();
}
...
This will create the database and the tables using your added migrations.
If you're not using Entity Framework Migrations, and instead just need your DbContext model created exactly as it is in your context class at first run, then you can use:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.EnsureCreated();
}
...

Resources