Trouble creating an sql connection string - c#

I have an example of a login page that runs off of sql in which I am trying to customize it to my server.
I'm running into issues with the sql string.
Here is the original (with my table info). This appears to be pulling the username and password from the login control with #user and #password; I think. If not what is it doing? what exactly is #user and #password?
string sql = "select count(*) from ResidentUserDatabase where users = #user and passwords = #password";
Here is where I hard coded a username and password in. This works and I was able to login just fine. Obvioulsy not useable, but confirms i am connecting to the database and pulling user info
string sql = "select count(*) from ResidentUserDatabase where users = 'user' and passwords = 'pass'";
Now, here is where i have issues (since the first version doesn't work...). I tried to bypass the #user and #password and am apparently not doing it right.
string sql = "select count(*) from ResidentUserDatabase where users = '" + LoginControl.UserName.ToString() + "' and passwords = '" + LoginControl.UserName.ToString() + "'";
I'm not really sure where to go from here, or why the example doesnt work.
thanks

The #user and #password are parameters of a "parameterized sql query". What you have created in your 3rd code sample is a real security problem. Google the term "Sql Injection attack". If you are unfamiliar with this kind of security concerns, then I would strongly urge you not to be building the login forms for your application. "Here be dragons"

You have a few things going bad for you here.
First of all, you should not concatenate strings as this leaves you open to SQL injection. Google it and you will see why.
Second, the #user and #password tokens are parameters of a SQL query. What you want to do is add parameters to whatever object you are using to execute the SQL (e.g. SqlCommand). How to do that in detail is beyond the scope of the question.
Third, your string-concatenating query is using the same field for username and password. That is why it doesn't work.

Related

LINQ generates incomplete query

so i have this query
var pac = from p in context.pacientebi where p.personalid == piradinomeri select p;
it generates this sql
SELECT
[Extent1].[id] AS [id],
[Extent1].[name] AS [name],
[Extent1].[surname] AS [surname],
[Extent1].[dateofbirth] AS [dateofbirth],
[Extent1].[personalid] AS [personalid],
[Extent1].[phonenumber] AS [phonenumber],
[Extent1].[sqesi] AS [sqesi],
[Extent1].[address] AS [address],
[Extent1].[shemosvlisdro] AS [shemosvlisdro],
[Extent1].[email] AS [email]
FROM [dbo].[pacientis] AS [Extent1]
WHERE ([Extent1].[personalid] = #p__linq__0) OR (([Extent1].[personalid] IS NULL) AND (#p__linq__0 IS NULL))
and doesn't return any value, if i change table name to include database name
like this
FROM [dbo].[pacientis]
to this
[CachedeskBase].[dbo].[pacientis]
everything is fine.
so why does linq to slq generate incomplete query?
I have an idea of what might be causing your problem;
You should check that your current Connection String contains a default catalogue parameter and possibly make sure that your application's database user default database is set.
Setting The initial catalogue/database variable in the connection string:
You might have miss typed or forgot to include a default catalogue/database in your connection string.
Including the default catalogue in your connection string tells your database server which database to use for your requests. (In this case, your LINQ/entity framework requests.)
Here is an example of a connection string containing a default catalogue:
data source=[Your server's address];initial catalog=[Your database CachedeskBase in your case];persist security info=[set to false if you plan on using sql authentification, else true];user id=[Your default user];password=[your user's password];MultipleActiveResultSets=True;App=EntityFramework
Side note: in a production or even development environment you shouldn't include plain database usernames and passwords. I would recommend you look into ISS App Pools if you are planning on deploying this application. When using an app pool you do not specify a user for your application and therefore their passwords. The user id and password fields are replaced by integrated security tag
Setting the application's database user default database:
This action is not recommended as you should always have a default catalogue/database for your user that doesn't contain any potentially dangerous data. This is mostly for security as you want to add hurdles in the path of potential intruders. Making your application's database your user's default database should not be something you want to happen.
As I have a SQL server instance running, I'll be using SQL Server for my example.
In SQL Server Management Studio, go to the security folder and then in the logins folder of the object editor for your database and double click on your user. (If you are using IIS app pools, look for IIS APPPOOL\[your app pool name]).
This should open the login properties window, allowing you to set the default database of your user.
You might need to specify your connectionstring to the datacontext as asked here.
Dim connectionString = "Data Source=myserver;Initial Catalog=mydatabasename;Integrated Security=True"
Using ctx As New HRManagerDataContext(connectionString))
Return (From us As User In ctx.Users
Where us.IsActive = True
Select us)
End Using

SQL Server 2012 & .NET suser_sname() returns different values dependent on accessed from Local IIS or Remote IIS

I'm having an issue with returning the desired username into SQL Server as a default value for a table. All was working well while I was working on my local machine and the remote SQL Server. When I deployed my project this week, I found that my SQL Server 2012 triggers were returning the server name of the IIS server (IIS01) instead of returning the desired value, the username of the user running the web application.
The following table is written to by UPDATE and INSERT triggers for another table. The table design is this:
CREATE TABLE [dbo].[table]
(
[id] [int] NOT NULL,
[username] [varchar](50) NULL,
[dt_changed] [smalldatetime] NULL,
[actiontype] [char](1) NULL
)
GO
ALTER TABLE [dbo].[table]
ADD CONSTRAINT [DF_table_username] DEFAULT suser_sname()) FOR [username]
GO
ALTER TABLE [dbo].[table]
ADD CONSTRAINT [DF_table_dt_changed] DEFAULT (getdate()) FOR [dt_changed]
GO
When I write to the triggered table via .NET running on IIS Express Visual Studio, it inserts the correct username into the table,
id username dt_changed actiontype
534 domain\drewl 2017-11-07 13:39:00 I
When I write to the triggered table from .NET running on IIS on a remote IIS01 server, it inserts an incorrect username into the table. The username inserted is the servername of the domain.
id username dt_changed actiontype
533 domain\IIS01$ 2017-11-07 11:16:00 I
In .NET, I am using a couple different ways of getting the username of the user running the script,
System.Web.HttpContext.Current.User.Identity.Name
<asp:LoginName runat="server" />
Both of these return the correct user on both the local IIS Express and the remote IIS01 IIS server.
In order to rule out that I was not using the wrong SQL command for the username, I wrote this bit of C# to show me the values for each.
string ResourceLoginName = Convert.ToString(System.Web.HttpContext.Current.User.Identity.Name);
string UsernameOnly = ResourceLoginName.Split('\\')[1];
detectedusername.InnerHtml = UsernameOnly;
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["RMConnectionString"].ConnectionString;
con.Open();
SqlCommand cmd = new SqlCommand("SELECT 'ORIGINAL_LOGIN()' AS UserFunction, ORIGINAL_LOGIN() AS UserValue UNION SELECT 'SUSER_NAME(SUSER_ID())' AS UserFunction, SUSER_NAME(SUSER_ID()) AS UserValue UNION SELECT 'SUSER_SNAME(SUSER_SID())' AS UserFunction,SUSER_SNAME(SUSER_SID()) AS UserValue UNION SELECT 'SYSTEM_USER' AS UserFunction,SYSTEM_USER AS UserValue UNION SELECT 'CURRENT_USER' AS UserFunction,CURRENT_USER AS UserValue UNION SELECT 'USER_NAME(USER_ID())' AS UserFunction,USER_NAME(USER_ID()) AS UserValue UNION SELECT 'SESSION_USER' AS UserFunction,SESSION_USER AS UserValue UNION SELECT 'USER' AS UserFunction,USER AS UserValue", con);
cmd.CommandType = CommandType.Text;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
Users.DataSource = dt;
Users.DataBind();
As above, the IIS Express returns the correct usernames,
.NET
drewl
SQL
Function Value
CURRENT_USER dbo
ORIGINAL_LOGIN() MTROGERS\drewl
SESSION_USER dbo
SUSER_NAME(SUSER_ID()) MTROGERS\drewl
SUSER_SNAME(SUSER_SID()) MTROGERS\drewl
SYSTEM_USER MTROGERS\drewl
USER dbo
USER_NAME(USER_ID()) dbo
While the remote IIS01 IIS server returns,
.NET
drewl
SQL
Function Value
CURRENT_USER domain\IIS01$
ORIGINAL_LOGIN() domain\IIS01$
SESSION_USER domain\IIS01$
SUSER_NAME(SUSER_ID()) domain\IIS01$
SUSER_SNAME(SUSER_SID()) domain\IIS01$
SYSTEM_USER domain\IIS01$
USER domain\IIS01$
USER_NAME(USER_ID()) domain\IIS01$
What am I missing here and how can I get it to work in the remote (PROD) IIS like it does in IIS Express?
After some more head scratching and research, I found this Stack Overflow question\answer,
I changed my WebConfig to use impersonation,
<identity impersonate="true" />
Set the AppPool to Classic mode (from Integrated), then followed Mike Pollitt's answer, to use Basic Authentication instead of Windows Authentication.
In IIS, only Basic Authentication logs users on with a security token that flows across the network to a remote SQL server. By default, other IIS security modes used in conjunction with the identity configuration element settings will not result in a token that can authenticate to a remote SQL Server.In IIS, only Basic Authentication logs users on with a security token that flows across the network to a remote SQL server. By default, other IIS security modes used in conjunction with the identity configuration element settings will not result in a token that can authenticate to a remote SQL Server.
Once I changed this and restarted the website in IIS, it now returns the correct username.

Create Login and Validating Users in Asp.net

I have created login page and i want to verify the users if they have access or not. I have done most of the work but just need couple of things here:
1) if user is validated, then i want to redirect to Home.aspx page
2) After the user is validated i want to be able to save the user id in a session so they don't have to login every time if they are redirected to another page.
Basically, once they login successfully they should be able to navigate other pages in the application. thanks.
here is the code behind:
protected void ValidateUser3(object sender, EventArgs e)
{
int userId = 0;
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("Validate_User"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Username", txtUID.Text.Trim());
cmd.Parameters.AddWithValue("#Password", txtPWD.Text.Trim());
cmd.Connection = con;
con.Open();
userId = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
}
switch (userId)
{
case -1:
logLbl.Text = "Username and/or password is incorrect.";
break;
case -2:
logLbl.Text = "Account has not been activated.";
break;
}
}
}
Here is my stored proc:
ALTER PROCEDURE [dbo].[Validate_User]
#Username NVARCHAR(20),
#Password NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #UserId INT, #LastLoginDate DATETIME
SELECT #UserId = UserId, #LastLoginDate = LastLoginDate
FROM myTable WHERE Username = #Username AND [Password] = #Password
IF #UserId IS NOT NULL
BEGIN
IF NOT EXISTS(SELECT UserId FROM [Main].[UserActivation] WHERE UserId = #UserId)
BEGIN
UPDATE myTable.[dbo].[UserProfile]
SET LastLoginDate = GETDATE()
WHERE UserId = #UserId
SELECT #UserId [UserId] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
END
ELSE
BEGIN
SELECT -1 -- User invalid.
END
END
First up I'd look at tightening that security. Don't save passwords in your database, not even hashed ones. And follow krillgar's advice in the comments to your question :)
What you want to do with each user account is create a unique salt code - a random value, with a minimum of 8 in length (the more the better naturally): See here for creating a salt code. You want to save that in your database in the users table. So you'll have something like a table structure like: UserId, UserName, PassString, SaltCode, Active
Pick a Hashing method; MD5 or SHA1 are typical examples. When the password is created you take the username, merge it into the password, add your salt code then Hash it. This will create a unique string - that's what you save into your database in the PassString field.
So when someone logs in you take the username and password, look up the user record, get the salt code. Hash it all together then compare the two hashed strings.
Check out this section on Stack Overflow: How to hash a password
This makes your passwords irreversible without all segments of the data in other words; the password the user enters to login is the missing key to the puzzle. If someone is somehow able to get the data out of your table they'll have to a ton of work to crack a user's account.
so to now answer your actual question :)
Just like you have with your Stored Procedure, when the user is successfully matched return a value such as 1. I would suggest you keep your return codes and userid value separate so there's less ambiguity in your code. You got a choice with your SP, you can either return the userid back in with the return code on a Select statement ie Select 1, #UserId or you can use an OUTPUT parameter, here's a fairly decent example: Using stored procedure output parameters in C# (I'd favour the latter).
Now working with what you've got (and by that I mean, not telling you to go off an use System.IdentityModel.Service, UserPrinciple and the likes)...
Once that successful login has been acknowledged by your SP, use a session variable in the following manner, Session variables are kept server side so unless your server is compromised you'll be ok:
Session["UserId"] = userId;
Response.Redirect("Home.aspx");
Now on pages like Home.aspx you just need some code along the lines of;
bool userLoggedIn = false;
if (Session["User"] != null) //check the session variable is actually valid
{
if (!String.IsNullOrEmpty(Session["User"]))
{
userLoggedIn = true;
}
}
if (!userLoggedIn)
{
Response.Redirect("login.aspx");
}
Though it would be a lot wiser to create a class in the App_Code folder to handle this, last thing you want is duplicated code all over your site.
The issue you'll run into is giving user's rights. I'm not clear from your question but I got the impression you wanted a binary login, ie: if a user is authenticated they have access, plain and simple. If you're after segmented security; controlling what each user can or cannot do then you need to be looking down the route of Claims based security, here's an example of that to get you thinking: http://www.codeproject.com/Articles/2905/Role-based-Security-with-Forms-Authentication
I hope that helps and wasn't too long a read :)

Sending authentication information to SQL Server isn't working (C#)

I already asked about a similar issue to this one but I've narrowed it down to my problem and I've been working on this for hours and unable to figure this out.
Basically, I have a visual studio wep application and I'm trying to use a login page and sql server database to validate user credentials. The user enters a string for username and password on the log-in screen which gets sent here on the code behind:
private bool ValidateUser(string userName, string passWord)
{
SqlConnection conn;
SqlCommand cmd;
string lookupPassword = null;
// Consult with your SQL Server administrator for an appropriate connection
// string to use to connect to your local SQL Server.
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["databaseConnect"].ConnectionString);
conn.Open();
// Create SqlCommand to select pwd field from users table given supplied userName.
cmd = new SqlCommand("Select Password from Users where User=#userName;", conn);
cmd.Parameters.Add("#userName", System.Data.SqlDbType.VarChar, 25);
cmd.Parameters["#userName"].Value = userName;
lookupPassword = (string)cmd.ExecuteScalar();
// If no password found, return false.
if (null == lookupPassword)
{
return false;
}
private void cmdLogin_ServerClick(object sender, System.EventArgs e)
{
if (ValidateUser(txtUserName.Value,txtUserPass.Value) )
(logs in)
}
The application is connected a table in a database, which currently holds one test item, as shown here: http://i.imgur.com/YFOQYKm.jpg
However, when I enter "test" as username and "password" as password, it doesn't accept the log-in.
I tried to include only the relevant parts of my code to make it more clear for anybody trying to answer the question but here's a few comments about my problem:
-When I set if (null == lookupPassword) to "return true" instead of "return false" the application allows logins. Which means lookupPassword is still null after "lookupPassword = (string)cmd.ExecuteScalar();"
-The application works fine when I change if(ValidateUser(txtUserName.Value,txtUserPass.Value)) to if(userName=test and passWord=password). So the problem is not with the actual act of logging into the application, it just isn't finding the SQL Server credentials to be true.
-"databaseConnect" is working elsewhere on the application, so that is not the issue.
-The application is not breaking when I submit the login credentials, it is simply not accepting them as correct.
Going off that, it seems to me that the problem comes from these four lines:
cmd = new SqlCommand("Select Password from Users where User=#userName;", conn);
cmd.Parameters.Add("#userName", System.Data.SqlDbType.VarChar, 25);
cmd.Parameters["#userName"].Value = userName;
lookupPassword = (string)cmd.ExecuteScalar();
Does anybody see where the problem might be for me? I'm very new to programming so please keep the answers as simple as possible please. Thank you in advance for any help. :)
This table design is using several reserved words in SQL Server. If you cannot modify this schema, you can update your query as follows:
SELECT [Password] FROM [Users] WHERE [User] = #Username
That being said, storing passwords in plaintext is a horrible security practice. Passwords should never be stored encrypted or as plaintext, they should be hashed using a salt to help avoid rainbow tables from cracking your password. I would look into the suggestion from #Richard regarding Rfc2898DeriveBytes. You can also search Google or Bing for using salt and SHA256.

Error connecting to SQL server through string, not recognising user name or password

the problem I am having is connecting to an account on my sql server (2005) from an ASP.NET application.
Ive tried using the default sa login and users ive created already also the setting of the sql management studio are set to mixed properties, I have the string connection in the webconfig as well but also doesnt work.
c# code
//string conStr = ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
string conStr = #"server=JAMES-PC\SQLEXPRESS; database=projectDB; uid=james; password=password;";
string query = "SELECT [TaskID], [Task], [Start Date] AS Start_Date, [End Date] AS End_Date, [Priority], [Time Allowance] AS Time_Allowance, [Details], [Catagory] FROM [schedulerData0]";
SqlDataAdapter dataAdapt = new SqlDataAdapter(query, conStr);
DataTable table = new DataTable();
dataAdapt.Fill(table);
GridView1.DataSource = table;
GridView1.DataBind();
The error message I receive is:
Login failed for user 'james'. The user is not associated with a trusted SQL Server connection.
Any help appreciated
James
Your SQL SERVER configured for Windows Only connections and you current windows user not associated as trusted. Try to configure your SQL SEREVR to accept Mixed Mode connections.
Try this,I'm not sure but hope it will work-
<connectionStrings>
<add name ="conStr" connectionString ="Initial Catalog = projectDB;
Data Source =JAMES-PC\SQLEXPRESS; User Id=james;Password=password;"/>
</connectionStrings>
try mapping projectDB to user:james. open SQL Server Management Studio, select Security - Logins, double click user:james, select page:User Mapping, check projectDB.
Please try the following format If It is Sql Server user mode,
ConStr = "Server=JAMES-PC\SQLEXPRESS;Database=projectDB;User Id=james;
Password=password;"
if you are trying to connect using windows,
then you must provide Trusted Connection = true

Categories