I'm creating a new asp.net MVC3 app in which in user table I do not wish to have user name but only user id (long) and email (string).
What I would like to understand is normally when I use membership provider with normal db structure, I get the username value in db as the User.Identity.Name.
Could someone please tell me what changes I need to do as I will not have any username in my db to ensure that my email address becomes my User.Identity.Name
Thanks
Arnab
Answer: found out... its FormsAuthentication.SetAuthCookie that decides which value goes to user.identity.name
The value User.Identity.Name typically comes from the "username" you provide the login form. This is stored by the LogOnModel class within the AccountModels model.
To set your email address as User.Identity.Name, you must provide your email address in the username field of the login form. Then use your membership provider to authenticate the user based on the provided email address.
found out... its FormsAuthentication.SetAuthCookie that decides which value goes to user.identity.name
Related
I am trying to implement a way for users to change their email in AspNetCore so on the Account Management screen I have the change function that will call GenerateChangeEmailTokenAsync on the user manager, then sends the email with the link containing the Token and UserId.
My problem is how do I allow the link the change the email address to the new address since ChangeEmailAsync requires the new email address be entered.
What is the best practice way of implementing this functionality? I do not want to send over the new email address in the email link but also do not want to make them type the email again. Hopefully someone has done this, I cannot find it anywhere only, and it should be very simple.
I know it is late answering this, but I was looking for it myself before, and thought I leave the answer here for others.
The GenerateChangeEmailTokenAsync method takes the new email as part in the hash of the token.
Next you create a link that contains the token, the new email and the old email
var token = await _userManager.GenerateChangeEmailTokenAsync(user, model.NewEmail);
var resetLink = Url.Action("ChangeEmailToken", "account", new {token = token, oldEmail = user.Email, newEmail = model.newEmail }, protocol: HttpContext.Request.Scheme);
Next you send this link to the user in an email.
When clicked, the user hits the method named in the link (here "ChangeEmailToken" on AccountController:
[AllowAnonymous]
[HttpGet]
public async Task<IActionResult> ChangeEmailToken([FromQuery] string token, [FromQuery] string oldEmail, [FromQuery] string newEmail)
Next you need to verify the token, and -if succesful- update the email address.
var result = await _userManager.ChangeEmailAsync(user, newEmail, token);
The normal flow is to let the user update profile as usual.
If the user updated their email address then that new email address needs to be verified.
That is when you generate the token with GenerateChangeEmailTokenAsync.
You send that token as a link to the new email address.
When the user clicks the link in the new email it takes them back to you site which automatically confirms the token and verifies the new email address.
I am using the standard MVC template from VS 2013 and using logins with External Ids, ie Google, Facebook, etc.
In AccountController.ExternalLoginCallback, it calls SignInManager.ExternalSignInAsync and the result can be one of SignInStatus.Success, .LockedOut, .RequiresVerification, and .Failure.
I have been able to make it return LockedOut by putting a time later than now in column LockoutEndDateUtc of dbo.AspNetUsers.
When or how does it return RequiresVerification?
I want to use this identity framework but with a bit of customization.
If you are using Two-Factor Authentication, then login will return SignInStatus.RequiresVerification for the user to enter the verification code.
See Two-factor authentication using SMS and email with ASP.NET Identity
ExternalSignInAsync return RequiresVerification if :
dbo.ASpnetUsers has for user set to true TwoFactorEnabled and EmailConfirmed and user email should be confirmed, email not be empty or null.
I'm using WebMatrix WebSecurity for my application's Forms Authentication.
The user needs to be able to change his username, without being logged out.
I supposed calling WebSecurity.Logout(), followed by WebSecurity.Login() would do the trick, but Login() requires a password. Of course, I cannot provide this password as it is hashed in the DB.
How can I make this requirement work?
EDIT:
Below are a few suggestions on how to fix the issue of changing the username.
However, my actual problem was that the cookie still holds the old username. I found the following instructions on how to handle that:
http://omaralzabir.com/how_to_change_user_name_in_asp_net_2_0_membership_provider/
So this is how I able to change the user name. This all happens inside a post action method for updating all kinds of user data.
First I check to see if the user name already exists. "info" is a model object coming from the view.
if (WebSecurity.CurrentUserName != info.UserName &&
this.userRepository.Find(info.UserName) != null)
{
ModelState.AddModelError("", "This email is already taken.");
return View();
}
Then I update the database.
UserProfile user = this.userRepository.Find(info.UserId);
user.UserName = info.UserName;
this.userRepository.SaveUser(user);
Then here is the magic part. You have to reset the authorization cookie.
FormsAuthentication.SetAuthCookie(user.UserName, false);
I hope that helps someone out there.
Since WebMatrix WebSecurity is done via UserId, not Username, just change the data in the table you are storing your userdata in, and then redirect them to a new page. You don't need to log them out and back in, I believe the new username will be picked up immediately.
You can do the following steps
Get the UserDetails by UserId or UserName
Change the UserName
Now update the user data by calling the SimpleMembershipProvider.UpdateUser.
More details here
I am using the default ASP.NET MVC Membership Provider and I would like to allow user's to modify their email after they have created their account. I do not want users to be able to use a duplicate email.
How do I allow a user to modify their email and check that the email is not in use elsewhere in the database? I am not sure of the best way to do this type of check when using the default Membership Provider.
note - I know the Membership Provider itself performs this check when a user attempts to register their email address, I do not know how to perform this check at a later time (due to noobness).
note 2 - I only know of this method of accessing the user's email, is this the proper way to be accessing it?
MembershipUser useremail = Membership.GetUser(User.Identity.Name);
ViewBag.Email = useremail.Email;
You can search for an existing username by that email:
String userName = MembershipProvider.GetUserNameByEmail(email)
If no match is found, userName will be null. See here for more info on this.
Also, if your MembershipProvider has RequiresUniqueEmail = true then this check should already be performed for you - as per this page.
I am creating my own website and blog and I want for first time just me in database (my name and password) and maybe later some registration for others but first log in just for me and administration with authorization. I don´t want to use Membership from MS. I want try to create my own from start so I am looking for guide for beginners but I found big guides with roles, rights. I want just small example with check username, password in database with log on data.
Thanks for help
Libor
Even if you don't want to use the membership and role provider data store you can still utilize the authentication. Trust me, it's a lot easier than building your own. Here's how it works:
We'll say you already have your user storage setup for retrieving the username and their password. For the sake of simplicity I'm going to pretend you have a static class called DataLayer that contains your data retrieval methods for pulling info from the database (or whatever storage you use).
First you need a way to let the user log in. So set up a page with username and password fields. Then in the action method that the page posts to set up a quick if statement:
if (DataLayer.UserExists(userModel.Username))
{
User userFromDB = DataLayer.GetUser(userModel.Username);
if (userFromDB.Password == userModel.Password)
{
FormsAuthentication.SetAuthCookie(userFromDB.Username, checkBoxRememberMe.Checked);
//Use userFromDB as the username to authenticate because it will
//preserve capitalization of their username the way they entered it
//into the database; that way, if they registered as "Bob" but they
//type in "bob" in the login field, they will still be authenticated
//as "Bob" so their comments on your blogs will show their name
//the way they intended it to.
return "Successfully logged in!";
}
}
return "Invalid username or password.";
Now that they are authenticated you can just use Page.User.Identity.IsAuthenticated in your code to find out if they are logged in. LIke this:
if (User.Identity.IsAuthenticated)
{
DataLayer.PostBlogComment(User.Identity.Name, commentBody);
//Then in your controller that renders blog comments you would obviously
//have some logic to get the user from storage by the username, then pull
//their avatar and any other useful information to display along side the
//blog comment. This is just an example.
}
In addition, you can lock out entire action methods or even whole controllers to users that are authenticated through the forms authentication provider. All you have to do is add tags like these to your action methods/controllers:
[Authorize]
public ActionResult SomeActionMethod()
{
return View();
}
The [Authorize] attribute will prevent users that are not logged in from accessing that action method and it will redirect them to your login page. You can use this same attribute to filter out roles if you are using the built in roles provider.
[Authorize(Roles="Admin, SalesReps")]
public ActionResult SomeActionMethod()
{
return View();
}
These attributes can also be added above the controller class to apply it's logic to the entire controller.
EDIT: To log a user out all you need to do is call FormsAuthentication.SignOut();
Hey #Bibo, good for not choosing the Membership providers. I think a UserService or similar which provides methods for creating, authenticating users and some few more methods should be enough. As a suggestion, use password hashing and a password salt for the user´s password. Here is a good link to look at. Also have a look at this answer I gave some time ago.
Good luck!
EDIT: The rememberMe parameter should be named keepMeSignedIn instead.
This article on forms authentication gives you loads of info for creating your own simple security system, especially the bit about FormsAuthenticationTicket.
http://support.microsoft.com/kb/301240