I want to get the Current loggedin UserID of the user without using Membership How can I achieve that ?
Here is my code
string CurrentlyLoggedInUser = Session["User"].ToString(); // get the userId for username and compare
string userId = CurrentlyLoggedInUser; // assign the userid here and check ok
if (Id == userId)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('You cannot delete yourself');window.location ='AdduserProfile.aspx';", true);
return;
}
But I am not getting the ID. Please help
Values from Session
if (dt != null && dt.Rows.Count > 0)
{
if (dt.Rows[0]["usertype"].ToString() == "0") //SuperAdmin
{
Session["UserType"] = "0";
Session["User"] = dt.Rows[0]["username"].ToString();
Response.Redirect("csrdashboards.aspx");
}
else if (dt.Rows[0]["usertype"].ToString() == "1") // Admin
{
Session["UserType"] = "1";
Session["User"] = dt.Rows[0]["username"].ToString();
Response.Redirect("csrdashboards.aspx");
}
else if (dt.Rows[0]["usertype"].ToString() == "2") // User
{
Session["UserType"] = "2";
Session["User"] = dt.Rows[0]["username"].ToString();
Response.Redirect("csrdashboards.aspx");
}
}
I want to get the Current loggedin UserID of the user without using
Membership How can I achieve that ?
Don't.
Look, I know that Membership isn't a shining example of the very best in API design. I know there are things that I personally would have done differently, as would many others, and there can be a strong temptation to roll your own membership API.
But if you're not 100% confident of your ability to do a better job, don't even try. Security infrastructure is too important and too easy to get wrong, and there's a dangerously high likelihood that you'll get something wrong and leave your site vulnerable.
I don't want to put anybody down, but looking at the quality of the code you've posted (code duplication, unnecessary assignments, multiple dictionary lookups, unnecessary-looking conversions to string all over the place) and some of the statements you're making (about having a "password" field in your database with no mention of hashing), you are not yet at the level of ability required for this, and you're heading for disaster.
"How do I...?" is the wrong question here. "Should I...?" is the first question you should ask, and I'm afraid the answer is no. Use Membership, it's not perfect but it's going to be a lot more secure and robust than anything you come up with yourself.
Related
I am working on a side project(student, not homework, just holiday curiosity), which would be my simple personal password manager/vault. It will be a windows app. I want it to support more than just one user. Now that i have my login screen and other functionalities, i struggle to find a simple and effective way to check if login and password of the user are correct. I store the information in a simple SQL table called Users(picture below). Now, i want to get the bool result, whether are these two strings (username,password) in database. i will include some code and screenshots below. Any help appreciated!
P.S.: I am pretty familiar with mySQL(Oracle), i just canĀ“t fin a good way to do this without being ridiculous. :)
namespace KeyLocker.Database {
[Serializable]
public class UserDatabase {
public void AddUser(string username,string password,string question,string answer) {
using(var db = new KeyLockerContext()) {
db.Add(new User { Username = username,Password = password,SecurityQuestion = question,SecurityAnswer = answer });
db.SaveChanges();
}
}
public bool CheckUser(string username,string password) {
using(var db = new KeyLockerContext()) {
/*here i need to find out if username is present in database
and if it is, i need to find out if the password is correct*/
}
}
}
}
Table Users ScreenShot
Table SQL detail
At first glance, it seems like the easiest code to execute your idea would be:
public bool CheckUser(string username,string password) {
using(var db = new KeyLockerContext()) {
// Check if that combination already exists in DB.
var result = db.Users.Where(x => x.Username == username && x.Password == password).SingleOrDefault();
// See if result has a value, SingleOrDefault() returns null if no match
return (result == null);
}
}
EDIT/Disclaimer: Since there seems to be some confusion, this is an idea for how to quickly check if an object w/ certain values already exists in the DB - not a complete authentication library. You should never store cleartext passwords.
So in my Discord bot, I am creating a full moderation system where users with appropriate privileges may hand out warnings to other users, these will be recorded, once 3 warnings are hit, the user is muted for a set time, this can occur 5 times for which they are muted for longer periods of time, after the fifth mute when the user reaches 3 more warnings, they are banned permanently. So I have pretty much made the whole thing which was no issue with a history viewer of users etc, but the problem I am having is with comparing roles. I have found a solution that I am not sure if it works properly in the long run, but was the only method I could think of. I want it to not allow users to warn those with higher ranks than themselves. This is the code I have for it:
public class Warn : ModuleBase<SocketCommandContext>
{
[Command("Warn")]
public async Task WarnMain([Remainder, Summary("Warn a user for a reason.")] IGuildUser user, string warnInfo)
{
var userRole = -1;
var victimRole = -1;
var counter = 0;
foreach(var role in Context.Guild.Roles)
{
if (Context.Guild.GetUser(Context.User.Id).Roles.Contains(role) && userRole == -1)
{
userRole = counter;
}
if (Context.Guild.GetUser(user.Id).Roles.Contains(role) && victimRole == -1)
{
victimRole = counter;
}
}
if (userRole < victimRole)
// blah blah
}
}
If you know of a better way or more efficient way of doing this, please share, would be much appreciated. Thanks.
First off, I would like to point out that discord.py has their own method of comparing between permissions. You could try to run their python script in your C# code, or 'translate' it from python into C#. You can check out their source code for comparing between permissions here.
For me personally, since my bot is not really made for moderation, I took the lazy way out and made a simple function that compares permissions using nested if-else statements.
private static bool PermissionComparison(GuildPermissions targetGuildPerms, GuildPermissions userGuildPerms)
{
//True if the target has a higher role.
bool targetHasHigherPerms = false;
//If the user is not admin but target is.
if(!userGuildPerms.Administrator && targetGuildPerms.Administrator) {
//The target has higher permission than the user.
targetHasHigherPerms = true;
} else if(!userGuildPerms.ManageGuild && targetGuildPerms.ManageGuild) {
targetHasHigherPerms = true;
} else if(!userGuildPerms.ManageChannels && targetGuildPerms.ManageChannels) {
targetHasHigherPerms = true;
} else if(!userGuildPerms.BanMembers && targetGuildPerms.BanMembers) {
targetHasHigherPerms = true;
} else if(!userGuildPerms.KickMembers && targetGuildPerms.KickMembers) {
targetHasHigherPerms = true;
}
return targetHasHigherPerms;
}
I would personally suggest using other methods instead if they seem better.
It seems the way I did it is the only way to actually compare roles as far as I can tell. Spent the last 4 hours looking for alternatives but did not come across anything.
My method is simply going through each role and comparing, I believe the API already sorts the roles from highest first to lowest last. You can then use a counter to compare the numbers at which the highest role is found that is assigned the the user.
Comparing permissions doesn't always work, especially in my case, therefore I could not use that method either. This seems to work best for me. If anyone has anything better feel free to share, I'd love to see how I can improve it.
If you cast the user to a SocketGuilderUser then you can compare the Hierarchy property.
Its basically the same thing you are already doing just avoids looping through the roles.
Users of my site have experienced some strange behaviour yesterday (first time I've seen this issue), and unfortunately I don't have much in the way of error logs to try to figure out what's going on. The site had a higher-than-normal number of people online at once, albeit not a large number in the grand scheme of things (maybe 50 to 100 users all trying to perform similar functions). I can't recreate the issue in my development environment, haven't seen it before, and don't really know why it is happening.
The crux of the problem is that users can register or log on successfully, but a small number of them could see other users' data.
The site is ASP.NET MVC 3.
Users are logging on and I set an authentication cookie - here's the LogOn action:
[HttpPost]
public ActionResult LogOn(AccountLogOnViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (!Membership.ValidateUser(model.UserName, model.Password))
{
ModelState.AddModelError("login-message", "Incorrect username or password");
}
}
if (ModelState.IsValid)
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
Session.Remove("MenuItems");
return Redirect(returnUrl ?? Url.Action("Index", "Home"));
}
else
{
model.ReturnUrl = returnUrl;
return View(model);
}
}
AccountLogOnViewModel is a simple object with two string properties, UserName and Password.
From what I can gather, this is fine - if you log in as NickW then doing something like User.Identity.Name correctly gives you "NickW" (when users were seeing other users' data, they reported that that "Welcome, NickW" text on screen was showing them the correct value - this is written out using User.Identity.Name)
The site also uses a custom membership provider. It overrides the ValidateLogin method, and the GetUser method. ValidateLogin appears to be working just fine so I'm not concerned about it.
The overridden GetUser method is as follows:
public override MembershipUser GetUser(string username, bool userIsOnline)
{
User user = _userRepository.Users.FirstOrDefault(u => u.UserName == username);
MembershipUser membershipUser = null;
if (user == null)
return membershipUser;
membershipUser = new MembershipUser(this.Name,
user.UserName,
user.Id,
user.Email,
null,
user.Comments,
user.IsActivated,
user.IsLockedOut,
user.CreatedDate,
user.LastLoginDate,
user.LastLoginDate,
user.LastModifiedDate,
Convert.ToDateTime(user.LastLockedOutDate));
return membershipUser;
}
So I'm attempting to retrieve a User object from my database, and using that to create a new MembershipUser object. My database User table has additional columns on top of those required by the membership provider - e.g. name, address, phone number etc.
At various points in the rest of the website (for example if you go to the Profile page), I retrieve a user object from the database and use it to populate the screen. The line I use to retrieve the User object is:
User user = userRepository.Users.FirstOrDefault(u => u.UserName == Membership.GetUser().UserName);
Here is a cut down version of the userRepository (i.e. just removing unrelated code).
public class SqlUserRepository : IUserRepository
{
private Table<User> usersTable;
private string _connectionString;
public SqlUserRepository(string connectionString)
{
_connectionString = connectionString;
usersTable = (new DataContext(connectionString)).GetTable<User>();
}
public IQueryable<User> Users
{
get { return usersTable; }
}
public void CreateUser(AccountRegisterViewModel user)
{
User newUser = new User();
newUser.UserName = user.UserName;
newUser.Salutation = user.Salutation;
newUser.PhoneNumber = user.PhoneNumber;
newUser.SecondaryPhoneNumber = user.SecondaryPhoneNumber;
newUser.FirstName = user.FirstName;
newUser.LastName = user.LastName;
newUser.PasswordSalt = CreateSalt();
newUser.Password = CreatePasswordHash(user.Password, newUser.PasswordSalt);
newUser.Email = user.Email;
newUser.CreatedDate = DateTime.UtcNow;
newUser.Comments = "Created from web registration";
newUser.LastModifiedDate = DateTime.UtcNow;
newUser.LastLoginDate = DateTime.UtcNow;
newUser.IsActivated = true;
newUser.IsLockedOut = false;
newUser.MayContact = user.MayContact;
usersTable.InsertOnSubmit(newUser);
usersTable.Context.SubmitChanges();
}
}
So it appears to me as if the auth cookie I'm setting is fine, but either:
When I first go in to the membership provider's GetUser() method, it retrieves the wrong record from the database and therefore sets up a MembershipUser object with the wrong username; subsequently when I look in the database for "this" user I'm actually looking for the wrong username.
Or: Intermittently when I do userRepository.FirstOrDefault(x => x.UserName == Membership.GetUser().Name) it retrieves the wrong record.
Or: something else is going wrong that I haven't thought of.
As I say, this seems to be a problem when the site was under load, so I'm wondering if it's some sort of caching issue somewhere? But I really don't know.
One thought I had was to change the way I retrieve the user in case the problem lies with the membership provider, and use this instead:
userRepository.FirstOrDefault(x => x.UserName == User.Identity.Name)
// or HttpContext.Current.User.Identity.Name if not within a controller
But really I'm not even sure what's going on so have no idea whether this will resolve the issue. Could it be a caching problem somewhere? It appears (but I can't be 100% certain) that when user A could see user B's details, it was always the case that user B was also active in the system (or had been within the previous 20 minutes).
I know it's a long shot, but does anyone have any idea how this could happen? Obviously it's a major concern and needs to be fixed urgently, but without knowing why it's happening I can't fix it!
Thanks in advance for any help,
Nick
Some things to consider:
Instead of using FirstOrDefault, use SingleOrDefault. FirstOrDefault assumes there will be more than 1 record of data matching your query. Since you are querying by username, there should only be 1 matching row, correct? In that case, use SingleOrDefault instead. When there are multiple rows that match the query, SingleOrDefault will throw an exception.
To get the username, instead of invoking Membership.GetUser().UserName, use User.Identity.Name. The User property on an MVC controller references an IPrincipal that should match the user's forms authentication cookie value. Since you have a custom membership provider, this should help eliminate its methods as a source of the problem.
There could be a caching issue if you have caching set up for the MVC project. Do you use the OutputCacheAttribute ([OutputCache]) on any controllers or action methods? Do you have it set up as a global filter in the global.asax file? Or do you think there may be some kind of SQL-based caching going on?
Looking at your overridden GetUser method, I see it should take 2 parameters: string username and bool isOnline. However, when you invoke it with Membership.GetUser().UserName, you are passing no parameters. Do you have another overridden overload of this method that also takes no parameters? What does it look like? Does it use System.Threading.CurrentPrincipal.Identity.Name to sniff out the current username when none is passed?
I wrote the following code to log in to my application using C# and LINQ. It connected to a SQL service oriented database that I have created in Visual Studio. The problem that I am having is one that I do not understand and am hoping that someone can help me about here. I have created two message boxed to try to see the output of my code buy I am not getting anything from it.
If anyone could help that would be great!
public bool UserLogin(string User, string Pass)
{
var Database = new ExampleDataSet();
var query = from Employee in Database.Employee
where (Employee.EmployeeID.ToString() == Employee.ToLower() && Employee.Password == Pass)
select Employee;
if (query.Count() != 0)
{
return true;
MessageBox.Show("You are logged in");
}
return false;
MessageBox.Show("You are not logged in");
}
private void cmdLogin_Click(object sender, EventArgs e)
{
string User = (txtUser.Text);
string Pass = (txtPass.Text);
UserLogin(User, Pass);
}
From the code you wrote, it seems that the problem is that you compare the string representation of an Employee with its EmployeeId property Employee.EmployeeID.ToString() == Employee.ToLower(). This line will always return false unless you override ToString() method of Employee class to return the property EmployeeId (which I presume you didn't).
Try this instead (assuming that parameter User contains the name of the user):
using(var dataSet = new ExampleDataSet())
{
var loggedIn = dataSet.Employee.Any(e=>e.UserName == User && e.Password == Pass);
var message = loggedIn ? "You are logged in" : "You are not logged in";
MessageBox.Show(message);
return loggedIn;
}
When you return, the function execution will stop, because it's done and will return the value to what it was called from. So anything after your return won't happen. Try putting MessageBox.Show before return:
MessageBox.Show("You are logged in");
return true;
And the same for the false version.
The Message boxes wont show as they are after the return statements - move your message boxes to before the returns to see them.
I have made changes in your code....Your if-else part is not valid......You are comparign employee.ID with employee itself..Try out with following code.....
public bool UserLogin(string User, string Pass)
{
var Database = new ExampleDataSet();
var query = from Employee in Database.Employee
where (Employee.EmployeeID.ToString().ToLower().Equals(User.ToLower())&& Employee.Password.ToString().ToLower().Equals(Pass.ToLower())
select Employee;
if (query.Count() != 0)
{
MessageBox.Show("You are logged in");
return true;
}
else
{
MessageBox.Show("You are not logged in");
return false;
}
}
private void cmdLogin_Click(object sender, EventArgs e)
{
string User = (txtUser.Text);
string Pass = (txtPass.Text);
UserLogin(User, Pass);
}
If you mean user = employeeId
Employee.EmployeeID.ToString() == user.ToLower()
if not :
Employee.EmployeeName.ToLower() == user.ToLower()
About the message box, you should know any statement after return will not be executed
Writing your own user authentication is not recommended. It is very difficult to do it right, and in most cases you can use one that is already provided by Windows or the dot net framework.
For example, your application should not store the users passwords in plain text. If your application or database is compromised, the attacker will not only gain full access to your application, but a list of passwords which it is likely the users have also used elsewhere.
If you need to store the users credentials, they should first be salted, and then hashed with a secure hashing algorithm. This prevents anyone who gains access to the database from learning users passwords.
To verify the password, you look up the salt in the database, append the password to it, hash the result, and then compare that with the stored value. If they are the same, then the user entered the correct password.
If you are writing an application that will be used in a windows domain, you can use Active Directory groups to control access to your application. On the simplest level, you can store your application in a folder which is only accessible by the authorised users.
You can also use groups to control access to the database the application connects to. If you are using SQL server, each group should be placed in a SQL database role, which is in turn granted the necessary permissions for that role.
From within the application, you can look up the users group membership, and use it to determine which forms / menu options to show, or exit the application if they are not authorised.
If you are writing an ASP.Net application, consider using MemberShip and Roles which are built in to the framework.
I'm trying to store a user's post into an access database through a web method. I want to store the logged-in user's username, user's post, and the post datetime.
So far, I can store an existing user post by hard coding. But I want to store posts by any logged-in users. I was told I need to get userID for username.
Thus, I've found and tried adding the following codes:
//GetUser() returns current user information
MembershipUser user = Membership.GetUser();
//Returns the UserID and converts to a string
string UserID = user.ProviderUserKey.ToString();
When I tried debugging with breakpoints, the first one was okay. But for the second one, VS 2010 said that "object reference not set to an instance of an object." How do I fix it?
VS suggested adding "new," which didn't work. It also suggested to catch NullReferenceException, but I don't know how to use the codes they provided:
public class EHClass
{
void ReadFile(int index)
{
// To run this code, substitute a valid path from your local machine
string path = #"UsersDB_in_App_Data";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
// Do something with buffer...
}
}
Can you give me suggestions of what I need to do, or an alternative way to go about getting userID for username?
You didn't indicate what type of MembershipUser you have, but the ProviderUserKey is totally dependent on the underlying data store.
For example, the sql membership provider stores this value as a GUID.
If there is a possibility that this property won't contain any useful data, then you need to test it for existence before accessing it:
//Returns the UserID and converts to a string
string UserID;
if ((myObject != null) && (myObject.ProviderUserKey != null)) {
UserId = myObject.ProviderUserKey.ToString();
} else {
UserId = String.Empty;
}
In addition, unless you are using WSE in a straight asmx web service, I don't think that the memebership provider will have any valid data to operate on.
If this is the case, you will probably need to switch to WCF or implement WSE (NOT recommended).
The exception you're getting means that either myObject (the current user) is null or myObject.ProviderUserKey is null. I'd suggest that when you get to the breakpoint after myObject is set you should inspect the value of myObject and see whether it is null.
Depending on what is actually null affects where you look for the problem. If myObject is null then you'll need to look at the code to get the current user, and check whether someone is actually logged in etc. etc. If ProviderUserKey is null, consider whether you need this ID or would be better off with just using the username directly, check whether the membership provider actually provides that property in any meaningful way.
instead you can use this code directly....
string UserID = MembershipUser.ProviderUserKey.ToString();