Membership.GetUser() C# .NET - c#

I am trying to use either the UserName or (preferably) the user ID to determine what specific user is logged into my application. My intent, is to limit the amount of content that can be uploaded to my site based on the user. Whenever the user attempts to upload a document, I want to retrieve a count of all the documents they have currently uploaded. As a test run, I just added a label to my form to try and identify the user before writing a query:
// validate user. If they are not authenticated, do not let them upload files
if (!HttpContext.Current.User.Identity.IsAuthenticated || !HttpContext.Current.User.IsInRole("Administrator"))
{
uploadLabel.Visible = false;
user.Text = Membership.GetUser().UserName; // this line should output the username
mapUpload.Visible = false;
uploadButton.Visible = false;
}
I know the authentication logic works, because all other fields are not visible when logged in. Additionally, Membership.GetUser().UserName only has a value when the user IsAuthenticated; else, I get a null pointer exception. If the code is called, then Membership.GetUser().UserName appears to be setting the label to an empty text string.
Is there another way to get information for the current logged in user? As mentioned, my ultimate goal is be able to write a query with the information:
SELECT COUNT(DocumentID) FROM Documents WHERE UserID=#UserID
Thanks in advance for any assistance.
Bic

No need to use MembershipUser event to get currently logged in user we have another simple way to get currently logged in username you just define like this in your page
string userName = Page.User.Identity.Name;

Can't you replace
user.Text = Membership.GetUser().UserName;
with
user.Text= User.Identity.Name

Related

MVC logout all active sessions after same user login

I have c# mvc web application.There is simple login page according to email and password. Now I have a need like that:
When a user login to the system, all active sessions that same email address will logout.
How can I achieve this?
You can use Session.Abandon() or Clear() to abandon the current session, but if there are multiple people logged in with the same address, this will not address that.
You'd have to build that detection in; for instance, you could update a flag on the table that represents your users and then in the other user's sessions periodically check the table if they were re-logged in. OR when a user logs in, create a token in a database table with an expiration date; associate that token to a user in a cookie. When logged out or logging back in, you could invalidate the token associated to that email address, and each user, when they attempt to access the application, could be rejected by your application checking whether the token is expired.
The Abandon method should work (MSDN):
Session.Abandon();
If you want to remove a specific item from the session use (MSDN):
Session.Remove("YourItem");
If you just want to clear a value you can do:
Session["YourItem"] = null;
If you want to clear all keys do:
Session.Clear();
If none of these are working for you then something fishy is going on. I would check to see where you are assigning the value and verify that it is not getting reassigned after you clear the value.
Simple check do:
Session["YourKey"] = "Test"; // creates the key
Session.Remove("YourKey"); // removes the key
bool gone = (Session["YourKey"] == null); // tests that the remove worked

Storing Check Box Selection in Cookies

I have programmed a Remember Me check box to store the username and password in cookies if the box is checked. My problem is, that if they check it and then re-launch the application the username and password auto fill, but the checkbox does not stay checked.
I have not figured out a way to do this yet...
I will post my code below:
if (!IsPostBack)
{
if (Request.Cookies["UserName"] != null && Request.Cookies["Password"] != null)
{
userNameTxtBox.Text = Request.Cookies["UserName"].Value;
passwordTxtBox.Attributes["value"] = Request.Cookies["Password"].Value;
}
}
if (chkBoxRememberMe.Checked)
{
Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(30);
Response.Cookies["Password"].Expires = DateTime.Now.AddDays(30);
}
else
{
Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(-1);
Response.Cookies["Password"].Expires = DateTime.Now.AddDays(-1);
}
Response.Cookies["UserName"].Value = myUserName
string passwordEncrypted = Crypto.Sha256(myPassword);
Response.Cookies["Password"].Value = passwordEncrypted;
The above code works as it should. But I have a remember me check box that if it is checked I would like to save it to the cookies and leave it checked until the user unchecks it....
Any ideas?
If the checkbox should be checked by default any time the cookie is present, then I imagine you can just set its checked state here:
if (Request.Cookies["UserName"] != null && Request.Cookies["Password"] != null)
{
userNameTxtBox.Text = Request.Cookies["UserName"].Value;
passwordTxtBox.Attributes["value"] = Request.Cookies["Password"].Value;
chkBoxRememberMe.Checked = true; // <-- here
}
Note that there are probably a couple of problems you're overlooking here...
If you always check the checkbox by default when the cookie is present, you don't give the user any way to uncheck the checkbox. The user would need to manually delete the cookie from their browser, which isn't a very great user experience. (Not to mention many users won't be aware of how to do that.)
Storing a user's password in plain text is grossly irresponsible. Please stop doing that immediately. Instead, generate some kind of unique token to identify the user and store that token in the cookie. The server-side code would then validate the token against known tokens associated with known users. Never, ever store the user's password in plain text anywhere.
Not only is what you're doing terribly bad in terms of security, you're also reinventing the wheel.
ASP.Net already supports out of the box Forms authentication, a default membership provider, properly encrypted/hashed authentication cookies and even a logon control with a remember me checkbox!
You would add the control to your ASP.Net logon page with markup something like this:
<asp:Login ID="LoginControl1" runat="server" CreateUserUrl="Register.aspx"
VisibleWhenLoggedIn="False" TextLayout="TextOnTop" RememberMeSet="True">
(We've set the DisplayRememberMe property to true. This instructs the logon control to display the "Remember me next time" check box and the membership provider to send the persistent authentication cookie to the user's browser upon successful logon.)
Before you start trying that however you should probably read "Walkthrough: Creating a Web Site with Membership and User Login" on MSDN.

How to set the current users email address in ASP.NET Membership?

im trying to set the current users email from within asp.net
Membership.GetUser().Email = txtEmail.Text;
Membership.UpdateUser(Membership.GetUser(User.Identity.Name));
but the next time i read the current users Email it has not changed
i read it like this
Membership.GetUser().Email
The method Membership.GetUser() returns a new user instance. Your first line is changing the Email property, and then proceeds by throwing away that change. Your second line will fetch the user again, with the old user, and update it.
The documentation for Membership.UpdateUser contains an example of updating the email property. It all boils down to passing the same User instance from Membership.GetUser() to Membership.UpdateUser.
// GetUser() without parameter returns the current logged in user.
MembershipUser u = Membership.GetUser();
u.Email = email;
Membership.UpdateUser(u);
This will cause issues if you have a custom MembershipProvider that uses the email field for identification purposes (and you login with email+password), then the user would still have User.Identity.Name equal to the old email until next login (or they get a new Forms-cookie).
Something like:
MembershipUser u = Membership.GetUser(User.Identity.Name);
u.Email = email;
System.Web.Security.Membership.UpdateUser(u);
Looks like you aren't feeding in the current user name to get user.

How to allow Unauthenticated users to reset password?

Please see Update Below:
I am using ASP.NET SQL Membership Provider.
So far I am able to allow users to change their password but only if they are authenticated or logged into the application.
What I really need is for users to be able to get a link in an email. They can click this link and reset their password.
Example: Lets say a user forgets his or her password, they can visit a page which they can either enter security question and answer; or their email address on file. They will then get an email with a link to reset their password.
All I have so far is this: Which allows only authenticated users to reset their passwords:
I do not want to use the Recovery Control which generates a password.
public void ChangePassword_OnClick(object sender, EventArgs args)
{
MembershipUser user = Membership.GetUser(User.Identity.IsAuthenticated);
try
{
if (user.ChangePassword(OldPasswordTextbox.Text, PasswordTextbox.Text))
{
Msg.Text = "Password changed.";
}
else
{
Msg.Text = "Password change failed. Please re-enter your values and try again.";
}
}
catch (Exception e)
{
Msg.Text = "An exception occurred: " + Server.HtmlEncode(e.Message) + ".
try again.";
}
}
I can create the store procedure and the email using a String Builder but I do not know how to get the un-authenticated user to change password. Is there a way for the user to be Authenticated when they click the link. I am not sure how to even ask this.
Thanks for reading:
Update:
Okay I managed to get the password to Reset using this code:
protected void btnResetPassword_Click(object sender, EventArgs e)
{
string username = "ApplePie12";
MembershipUser currentUser = Membership.GetUser(username);
currentUser.ChangePassword(currentUser.ResetPassword(), txtResetPassword.Text);
}
Here is my plan:
Make this page public so that it is access by Un-Authenticated Users but only via email link.
Create a Stored Procedure that verifies a user Exists either by the UserName they enter or by the Security Question/Answer.
If they exists, they are sent a link containing a token/GUID
Lastly when they click the link they will land on this page asking them to change password. *The Link Expires as soon as it is used.
My only question is: Doing all of the above requires turning off using security Question/Answer in the Web Config file.
I really would love to have the Security question as an option for the user to either verify by email or security question. If this is not possible, I'll have to create some kind of account number or userid (not membership user id) as an alternative.
My answer is not specific to Membership Provider, but hopefully will point you in the right direction. Typically the way to approach this is to generate a very long random string, called a token. You send them a link that includes this token as a parameter, something like:
http://foo.bar/reset?token=asldkfj209jfpkjsaofiu029j3rjs-09djf09j1pjkfjsodifu091jkjslkhfao
Inside your application you keep track of tokens you have generated. If you receive a request containing that token, you authenticate it as if it was that user.
A couple notes:
The token generated should be random and effectively unguessable in a short period of time.
The token should only work for a short period of time after being generated, ideally shorter than the time required to guess it.
The token should only be usable once. Once a user has changed their password using it, remove it from the system.
Chris has given definitely the correct solution.
You can use the sql table for token management. the token may be UserId or Email that are unique. the link used for reset email like http://test.com/reset?id=sfksdfh-24204_23h7823.
The id in the url is encrypted Userid or Email as you like.
Fetch the detail from table on the basis of id in Url. if id contain in database. then reset the password for user. and remove that token from DB.

How can I set up ASP.NET login to allow the UserName or UserId to be retrieved later on in the session?

I'm trying to create a login system for my website, I've created a custom login.ascx and when the user clicks [ Login ] a div pops up with the contents of login.ascx.
Then after the user enters their credentials, they click on the Login button. They get validated and logged in using this code in the login click function:
if( Membership.ValidateUser( userName.Text, password.Text ) )
{
//Here is where I'm not sure what to do
}
else
{
LoginError.Visible = true;
}
So in the section where I'm not sure what to do, I would like the user to get logged in (Not sure if that means creating an authentication ticket or whatnot). What does is the next step to actually log the user in, I don't want them to get redirected anywhere since they are on the correct page already.
I would also like to be able to retrieve their user name or user id later on for use in my web services. So, for this should I do a Session.Add to create a new session value or is there some other way of storing the data that is preferred?
For authenticating the user,
FormsAuthenatication.SetAuthCookie(username, false/*true if you want to remember the user's login*/);
This logs the user in. You can later use
Page.User.Identity.Name
to retrieve username of the current user and
Page.User.Identity.IsAuthenticated
to check if the user is logged in.
There's no need to store it in Session. Just use:
FormsAuthentication.SetAuthCookie
to send an authentication ticket to the client. Then use HttpContext.Current.User.Identity to retrieve it later.
I find using the membership provider is useful, I would recommend it
Scott Guthrie posted great blog on this
http://weblogs.asp.net/scottgu/archive/2006/05/07/ASP.NET-2.0-Membership-and-Roles-Tutorial-Series.aspx

Categories