Reputation: 6428
I want user object only when exact password along with case matches. However this query fetches result even when case for password is not same:
db.Users.Where(u => u.Username.ToLower() == username.ToLower() &&
u.Password == password).FirstOrDefault();
What am I missing?
Upvotes: 5
Views: 4489
Reputation: 4902
try altering your column like this:
alter table [Users] alter column [password] nvarchar(100) collate Chinese_PRC_CS_AI
Upvotes: 0
Reputation: 1063884
If the database is configured as case-insensitive, then you cannot get it to do a case-sensitive comparison on the password (unless you resort to TSQL tricks). However! You should not be storing a password - you should be storing a salted hash (ideally salted per user). And the hash (as a blob) should be fine to compare this way.
Upvotes: 3
Reputation: 52137
What is the database type of the password and what collation sequence are you using?
It it's the VARCHAR and you use case-insensitive collation, the behavior you describe is exactly what would be expected.
Default collation sequences for some databases may be case-insensitive (e.g. take a look at SQL SERVER – Collate – Case Sensitive SQL Query Search), so you might be using case-insensitive collation without even knowing it. Obviously, you'll need to change the collation to get the correct results.
Upvotes: 1
Reputation: 113352
Simplest way is to do the username matching in the DB under it's case-insensitve rules and the password matching in .NET under its case-sensitive rules:
db.Users.Where(u => u.Username == username).ToList().Where(u => u.Password == password).FirstOrDefault();
The ToList()
moves from db-based LINQ to object-based LINQ, and since there would only be one matching case anyway, the performance impact of doing so is negligible.
Still has the problem of storing a password in a database though!
Upvotes: 7
Reputation: 58763
Change the collation of the Password
column in your Users
table to use a case-sensitive collation such as Latin1_General_CS_AS.
Or, as others have commented, consider changing your solution to store hashes of the passwords instead (e.g. an SHA1 hash) and compare hashed values rather than plaintext passwords.
Upvotes: 1
Reputation: 137188
Try:
db.Users.Where(u => string.Compare(u.Username, username, System.StringComparison.OrdinalIngoreCase) == 0 &&
string.Compare(u.Password, password) == 0).FirstOrDefault();
Because this is being executed in the SQL you can't use the .NET/Linq comparison methods.
Upvotes: 2
Reputation: 956
If u.Password
and password
are of string type, then your code should work as expected.
Upvotes: 0