I have developed a c# program I want to use to access a remote server from a client computer on the same domain.Every time I try to connect to the database I am getting an error login failed for user domain\myclientusername
Using the connection string below:
<add name="dbname" connectionString="Server=remoteservername;Database=dbname;Integrated Security=True;"/>
I have already checked and the server is set to allow remote connections. I am able to log on to the server using admin credentials do I need to set the connection string to use admin password and user name to connect to the database? or do I need to add my client profile credentials to the database permissions. Very new to deploying applications.
You will need to set up access to the database for the connecting user/client PC. You sort of "map" a user on the domain to a SQL user or group
Go to SQL management studio> connect to your database> expand databases > expand 'security' and then 'logins'
right click logins and select new login. search for the user of the connecting user/client PC. Then under the "user mapping" tab you can give access to the specific database. it may be best to give "db_owner" at first just to ensure you have the connection. after that, you should limit the access to only what is needed.
you can always check the SQL events log from the SQL machine itself and see what the specific authentication issues may be. go to "Events" in the Administrative tools (which is in control panel) and you can see SQL specific events.
Either you can remove the Integrated Security=True in your connection string and insert the username and password of a Login you create in you SQL Server database to your connection string.
Or, you can create a login for the user under which your c# program is running (yourself - for testing, domain service account under production) to the SQL Server and give it appropriate read/write access.
More information on connection strings: http://www.connectionstrings.com
More information on how to create login in SQL Server : http://msdn.microsoft.com/en-us/library/aa337562.aspx
When you set Integrated Security=True , the current Windows account credentials are used for authentication.
Since you are trying from a different PC than the one that is running the SQL instance it is much likely the acount you are trying to connect with differs from the acount registered to the instance log in.
what you can do is:
Use Integrated Security=sspi and provide the login credentials, e.g:
connectionString="Server=remoteservername;Database=dbname;User id= myUser; Password=myPass;Integrated Security=sspi";
you can also set Integrated Security=false and also provide the credentials, (but the connection won't be using Windows Athentication)
Related
For a SQL Server instance, to check if a windows user is present and has any access or not one can try various ways as detailed here.
I'm looking for something similar for SQL Server Analysis Services (SSAS) server.
I went into properties of SSAS Server from right-click context menu and on Security tab I can see that there are several windows users already configured:
Is there any way to check from a client application (written in C#) by making some sort of test connection or does SSAS also maintains some metadata database of its own like master database in SQL Server instance (DB engine) which can be queried. I checked the Databases node in SSAS server but I don't see any default databases there:
In the client application I'm working upon, I've windows user name and password as input. In my client application there is a simple winform with two text boxes to take AD user name and password which need to be connected to a SSAS Server. My gut feel is that password is of no relevance here as SSAS supports only Windows integrated authentication mode. My client application would be running under an account which already has access to SSAS server I'm trying to connect.
Update: After getting help from #Vaishali, I'm able to figure out that it is possible to make a test connection to an SSAS server using ADOMD.Net.
Now, the problem here is that the connection string implicitly uses the AD account of the user with which I'm running the client application to connect to the SSAS server. I don't think it would be possible mention an windows AD account user name and password explicitly in the ADOMD.Net connection strings while using Windows Integrated authentication. Even connection strings of SQL Server don't allow mentioning the windows username and password explicitly in the connection string as mentioned here.
Update 2: I have got a lead from one of my friends that it is possible to fire some MDX query on SSAS to get user access details.
Update 3: SSAS server supports only Windows Integrated Security mode of authentication unlike SQL Server DB engine which also supports userid-password based SQL authentication. So, some form of impersonation would be required to fire MDX queries on behalf of other user for which I'm trying to check access on SSAS server through Windows Integrated Security only.
Hmphh...It was quite a journey to really be able to nail it through ADOMD.Net.
Core methodology: The core philosophy is the fact that connection to SSAS server supports only Windows Integrated Security based authentication. The SQL authentication like we do for sa user in SQL Server isn't supported in SSAS.
So, the basic idea was to try to connect to the SSAS server using Windows Integrated Security based authentication and fire an MDX query in the context of the user we are trying to check. If the query gets executed successfully then the user has access. If the query execution returns an error/exception then the user doesn't have access.
Please note that just to be able to open a connection to the SSAS server is not an indicator of user-access due to reasons described here. You must fire a query to check access.
For ADOMD.Net until v12.x:
Now, we know that Windows Integrated Security based authentication always takes the user details from the user-context under which the application/process is running. You can not pass the user credentials in the connection string of ADOMD.Net connection. Here is the code I wrote to accomplish it. You need to refer to Microsoft.AnalysisServices.AdomdClient.dll in your C# project.
using Microsoft.AnalysisServices.AdomdClient;
public static int IsSsasAccessibleToUser(string ssasServerName)
{
var hasAccess = 0;
try
{
using (var adomdConnection = new AdomdConnection($"provider=olap;datasource={ssasServerName};Catalog=myDatabaseName"))
using (var adomdCommand = new AdomdCommand())
{
adomdCommand.CommandText = "SELECT [CATALOG_NAME] AS [DATABASE],CUBE_CAPTION AS [CUBE/PERSPECTIVE],BASE_CUBE_NAME FROM $system.MDSchema_Cubes WHERE CUBE_SOURCE = 1";
adomdCommand.Connection = adomdConnection;
adomdConnection.Open();
adomdCommand.ExecuteNonQuery();
Log("ExecuteNonQuery call succeeded so the user has access");
hasAccess = 1;
}
}
catch (Exception ex)
{
Log("There was an error firing query on the database in SSAS server. so user doesn't have access");
}
return hasAccess;
}
Now, to leverage Windows Integrated Security based authentication we can run this code in two ways:
Out-Proc Impersonation : Put this code inside a console application. Use the "Run as different user" option in the context menu when we right click the exe. Put the credentials of the user Y (let's say) so that application starts in the context of user Y for which we need to validate the access on SSAS server. ADOMD.Net will use user Y's identity while connecting using Windows Integrated Security for SSAS server. If code succeeds the user has access.
In-Proc Impersonation: The other case could be that you are running the application as user X but you want to test the access of user Y. Here effectively you require in-place impersonation while running the above code. For achieving it I used a famous NuGet package "Simple Impersonation" which uses the default .Net library classes WindowsImpersonationContext and WindowsIdentity . Creator of this NuGet package had first posted a great answer here.
Observation in SQL Server Profiler: After you've impersonated user Y, you will clearly see the MDX query getting fired in the context of user Y if you capture the session as shown below:
Caveats and concerns:
One issue that I faced while using this in-proc impersonation is that it doesn't work if the SSAS server is located on the same machine where the application code is running. This is due to the inherent behavior of native LogonUser API (using LOGON32_LOGON_NEW_CREDENTIALS LogonType) which is called during impersonation calls by the NuGete package. You can try other logon types as detailed here which suites you need.
You require password of the user as well along with the domain name and user name to do impersonation.
For ADOMD.Net v13.x onwards
Then, I came across this ChangeEffectiveUser API documentation on MSDN here. But, intellisense wasn't showing this API. Then I found out this API got added in ADOMD.Net with SQL Server 2016 release. There are various ways to get the latest release:
C:\Program Files\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.AdomdClient.dll
I'm not sure who dumps this file at this location. Is it part of Microsoft.Net extensions or SQL Server installation.
In Installation folder of Microsoft SQL Server. I got it at path - C:\Program Files\Microsoft SQL Server\130\Setup Bootstrap\Update Cache\KB3182545\ServicePack\x64\Microsoft.AnalysisServices.AdomdClient.dll
NuGet package here. For some weird reason best known to MS the NuGet package of v13.x of ADOMD.Net has been named Unofficial.Microsoft.AnalysisServices.AdomdClient. Not sure why they introduced a separate NuGet package with Unofficial prefix when this should have been simply the next version of the already existing NuGet package Microsoft.AnalysisServices.AdomdClient present here.
So the new API ChangeEffectiveUser present in latest version on AdomdConnection clas can be used easily to impersonate any user as below:
adomdConnection.Open();
//impersonate the user after opening the connection
adomdConnection.ChangeEffectiveUser("domainName\UserNameBeingImpersonated");
//now the query gets fired in the context of the impersonated user
adomdCommand.ExecuteNonQuery();
Observing Impersonation in SQL Server Profiler: Although one peculiar observation I had in the SQL Server Profiler is that the logs of query being fired still shows the name of the original user with which your application process is running.
So to check whether impersonation is happening or not I removed the access rights of the user domainName\UserNameBeingImpersonated from SSAS server. After that, when I ran the above code again then it resulted in exception whose message clearly states that - the user domainName\UserNameBeingImpersonated doesn't have permission on the SSAS server or the database doesn't exist. This error message clearly suggests that impersonation is working.
Advantages and Backward compatibility of this approach:
Although the API is very recent as it came up with SQL Server 2016 but I was able to use it successfully with SSAS server 2014 as well. So it looks fairly backward compatible.
This API works irrespective of whether your SSAS server is local or remote.
You just require the domain name and user name for doing impersonation. No password require.
What to do if we simply want to check the access on the SSAS server without involving any database present on the SSAS server?
Change the connection string to not involve any database. Remove the Catalog key as following connection string - "provider=olap;datasource={ssasServerName};"
Fire the following query instead to check access - SELECT * FROM $System.discover_locks in the code snippet shown initially in the post.
If you wish to check if user has accessibility to SSAS server, one option you can try with C# is: try connecting SSAS with given user credential, if you succeed, you have access.
If you are looking for roles and security mapped to individual cube database, following link will be usefull.
http://www.lucasnotes.com/2012/09/list-ssas-user-roles-using-powershell.html#comment-form
C# code lines:
import library Microsoft.AnalysisServices.AdomdClient;
and code lines would be:
DataSet ds = new DataSet();
AdomdConnection myconnect = new AdomdConnection(#"provider=olap;datasource=.\SQL20f12");
AdomdDataAdapter mycommand = new AdomdDataAdapter();
mycommand.SelectCommand = new AdomdCommand();
mycommand.SelectCommand.Connection = myconnect;
try
{
myconnect.Open();
}
catch
{
MessageBox.Show("error in connection");
}
Hope this works for you.
My program was working until yesterday. But my company moved to a new domain and I also had to do that. Now I cannot connect to SQL Server, what should I change in my connection string?
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Pedram;Data Source=DELL_RACK
The error I get for my inserts is:
Operation is not allowed when the object is closed.
By the way, I think I also upgraded my Visual Studio to Update 3. Could this also be the problem?
The connection string will stay the same. It won't change at all. This relies on the user's security context to authenticate to sql server. Therefore, we'll need to fix it so that the users accessing the database are authorized to use the database.
The change will need to be either in how you choose what user is logged in (ie: if this is an asp.net site doing impersonation, or similar process for setting the current user) orby grant login rights to users in the new domain in Sql Server, or both.
You can use SQL Server authentication Mix mode.
For create a Connection String in mix mode use this
Server=myServerAddress;Database=myDataBase;User Id=myUsername;
Password=myPassword;
and en total you can see this link : [http://www.connectionstrings.com/sql-server/][1]
if you use mix mode authentication , change windows permission can not make error in your program.
Hi guys I'm trying to connect to a MSSQL database with ASP.net! I've created a Database containing 3 tables, but every time I try and connect to the database I receive an error message stating I must obtain permission first... How do I connect or get the permission?
Windows Authentication
error
you do not have permission to open this file
contact the file owner or an administrator to obtain permission
You can adjust your string connection with IntegratedSecurity = true
Link : http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlconnectionstringbuilder.integratedsecurity.aspx
Nota : information current Windows account credentials are used for authentication
Nota : you can also use server account (false), but you must specify in your string connection
Another link about build string connection : http://www.connectionstrings.com/sql-server-2012
Try something different such as enabling "SQL Server and Windows Authentication mode" in SQL Management Studio
Right click the Server node => Properties => Security
Then create a new SQL user profile with full permissions to your database and use those credentials in you connection string.
You Application Pool Identity must have enough permission to access your db.
I've got a local WCF web service project that I'm trying to get to access my database. This is my setup:
SQLServer 2008 R2 Express
IIS 7.5
Using IIS APPPOOL\MyAppPool application pool
The AppPool is set to target .Net 4.0 and its identity is set to ApplicationPoolIdentity.
The AppPool user is added in the database and has been assigned dataReader and dataWriter rights. I've tried adding the user to the database both as a "Login" under Security\Logins and as a user under MyDatabase\Security\Users.
Since I'll eventually switch to sql server authentication, I also tried using a real windows user that I assigned reader/writer rights in the database.
I then tried converting the ApplicationPool's identity to NetworkService and added the NT AUTHORITY\NETWORK SERVICE user to the DB aswell but with equal lack of success.
This is the connection string that I'm currently using (With integrated security):
Server=.\SQLEXPRESS;Database=MyDatabase;Integrated Security=true"
As soon as I try to interact with the database in my web service code I get this error:
System.Data.SqlClient.SqlException: Cannot open database "MyDatabase" requested by the login. The login failed. Login failed
for user 'IIS APPPOOL\MyAppPool'.
When using other users than the ApplicationPool then their user names are displayed instead of the IIS APPPOOL one.
Does anyone have any idea what I could've missed?
UPDATE:
With some help from Oded and Tomek I'm now pretty sure that it has to do with the SQL Server. When using SQL Server Authentication I get this error (In the windows event log)
Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only.>
Using Integrated Security (IIS APPPOOL\MyAppPool user) I get this error in the event log
Reason: Failed to open the explicitly specified database.
The server is configured to use "SQL Server and Windows Authentication mode" though which puzzles me. It seems like the second message simply means that the credentials were wrong, which also seems weird since the AppPool user does not have a password. Using the script posted by guptam in post 6 here: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=121202 does NOT show my IISAPPPOOL user nor the one created for SQLServer Authentication. The users do exist under both Login and Users and they have the correct rights assigned.
The connection string should be:
"Server=.\SQLEXPRESS;Database=MyDatabase;Integrated Security=SSPI;"
The value for Integrated Security is SSPI, not True.
There is an alternative syntax:
"Server=.\SQLEXPRESS;Database=MyDatabase;Trusted_Connection=True;"
The key here is Trusted_Connection, not Integrated Security.
I suggest taking a look at connectionstrings.com - a good resource for correct connection strings.
Go to your IIS Manager -> ApplicationPool. Right Click your website ApplicationPool and chose Advance Settings. And change Identity to LocalSystem.
Reference
Can you try these steps (some steps of your description are a bit unclear). Let's try to use "sql server authentication"
Create Login Security->Logins, mark "sql server authentication", provide password, untick "user mast change password at next login"
Select "default database" to the one you use
Go to "User Mapping" page and select your database
Use below connection string with user you just configured
connectionString="Data Source=YourDbServerName;Initial Catalog=YourDbName;User ID=YourLogin;Password=YourPass"
I eventually decided to reinstall SSMS and to recreate my database from scratch. It's now up and running as it should. I must've had something fundamentally wrong in some basic setting. Sry for all the confusion and thx for all the help!
I am always doing the following Login module:
Create a table with Username and Password
Login by checking the user table.
So how do I use integrated Login just like the application like Sql Server? I don't mean by passing a connection string, I mean it will check the credential of my application without putting any username and password.
Thanks
EDIT:
I don't mean the SQL Server integrated Login, I mean my application's integrated login, is it possible?
For example, my application will read the AD's name and compare to the current username, then I don't need the user to type in a password for my application.
I am not sure how do I do that and where to start, since if I search Integrated Login, 99.9% of the results from Google will give me the connection string, which I am not looking for that.
[This answer assumes that you're on an Active Directory domain]
Are you using active directory windows authentication? If this is the case you can use the integrated security option in the connection string.
Here's an example connection string using integrated security:
"Data Source=MyServer;Initial Catalog=db name;Integrated Security=True"
This would reduce the complexity allowing you to forget about having to ask the user for a username and password because it'll pick up the windows credentials that they've logged into the workstation with.
Edit:
If the application is a website then you'll need to set the SQL server as "trusted for delegation" in active directory (see http://msdn.microsoft.com/en-us/library/aa905162(SQL.80).aspx). This will allow the webserver to delegate the user's windows login credentials to the SQL server. If you don't do this then the SQL connection will be anonymous.
Assuming that your application will be running with Active Directory on the local network I think there are a few options, depending on how do you want to implement authorization.
If you want/need to do authorization with some custom rules/logic then the first thing you need is to determine who ran the application:
Environment.UserName in conjunction with Environment.UserDomainName will give you enough information;
Alternatively (and more secure) you have use the following code snippet:
AppDomain.CurrentDomain.SetPrincipalPolicy(
System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
var identity = Thread.CurrentPrincipal.Identity;
From the identity you can extract Security Identifier which is designed to be globally unique. (But not that pretty as domain\username pair.)
After getting current user's name you can apply whatever authorization rules you want.