How can I set and get id and name in FormsAuthentication
Here only I set name
var user = db.usertable.Where(x => x.UserName == L.UserName && x.password == L.password).FirstOrDefault();
if (user == null)
{
ViewBag.Msg = "invalde user";
return View();
}
else
{
FormsAuthentication.SetAuthCookie(user.UserName, false);
return RedirectToAction("Index", "Home");
}
and here only I can get name by this code:
System.Web.HttpContext.Current.User.Identity.Name
How about can I get id user?
When user register in your app "/Account/Register", Identity automatically creates account for him, it would create few new tables in your DB, It would store your new user data in dbo.AspNetUsers.
You have to create Membership object which validates user credentials and manages user settings by user name. And call method ProviderUserKey to get user id.
Membership.GetUser(User.Identity.Name).ProviderUserKey
You can't change user id after creation, it's generated automatically.
Related
I'm told to make admin have a functionality to change other users password without knowing their original password. I wrote a code that changes and saves password successfully in database, but when I try to login as that user I can't.
UsersController:
public ActionResult ChangePassword()
{
return View();
}
[HttpPost]
public ActionResult ChangePassword(int id, ViewModels.ChangePasswordViewModel model)
{
if (!SessionControlService.CheckIsLoginStillTrue(_loginsService, HttpContext))
return RedirectToAction("Login", "Account");
if (!User.IsInAnyRoles("Admin", "PropertyManager"))
return RedirectToAction("Error", "Errors",
new { error = Facility.Web.Resources.Resources.ErrorNotHavePermission });
var user = _userService.GetUser(id);
if (user == null)
return RedirectToAction("Error", "Errors",
new { error = Facility.Web.Resources.Resources.ErrorURLNotExist });
user.Password = model.NewPassword;
_userService.UpdateUser(user);
return RedirectToAction("Details", new { id = id });
}
Why can't I use the changed password which is saved in the database to login?
How can I make this work?
In ASP.NET MVC5, password is hashed... you cannot save a plaintext password like that.
You need to use these two methods:
var manager = new ApplicationUserManager(...);
var token = manager.GeneratePasswordResetToken(userId)
manager.ResetPassword(userId, token, newPassword)
You could also try ApplicationUserManager.UpdatePassword(...), or RemovePassword(...) and AddPassword(...)
ApplicationUserManager is normally in IdentityConfig.cs
I am trying to redirect user to page based on their role. Below is the login code in a controller:
[HttpPost]
public ActionResult Login(User model)
{
// Lets first check if the Model is valid or not
if (ModelState.IsValid)
{
using (AuthenticationAppEntities1 entities = new AuthenticationAppEntities1())
{
string username = model.Username;
string password = model.Password;
// Now if our password was enctypted or hashed we would have done the
// same operation on the user entered password here, But for now
// since the password is in plain text lets just authenticate directly
bool userValid = entities.Users.Any(user => user.Username == username && user.Password == password);
// User found in the databases
if (userValid)
{
FormsAuthentication.SetAuthCookie(username, false);
if (Roles.IsUserInRole(model.Roles, "admin"))
{
return RedirectToAction("Home", "Authentication");
}
else
{
return RedirectToAction("HomeAdmin", "Authentication");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
As you can see in the code, I redirect users based on their roles, using a if. However, model.Roles contain a null value as the controller is getting only the username and password from the login page. Any simple idea how I get the role of the authenticated user? I thought of searching it through the username, but am not sure if this is the best solution.
You can get the User's roles and then compare it with 'admin' and then redirect accordingly.
Honestly, I'm not even sure how you're getting that to run in the first place. The method signature for Roles.IsUserInRole is:
Roles.IsUserInRole(string username, string role);
Passing model.Roles is neither a string, nor a username, if it was a string.
I would like an action link that says "set user default". There's a possibility the database does not already have the UserDetails stored for the user who clicks the link. If this is the case, I would like to direct the user to the Create view when they can save a new object.
If the UserDetails already exists for the user, I would like to direct the user to their Edit(id) page and load their existing UserDetails from the database.
Basically I need an ActionLink that points to a different view based on some information.
What is the preferred/standard way in MVC to accomplish this?
Existing Record
#Html.ActionLink("set user default", "Edit", "User")
Non-Existing Record
#Html.ActionLink("set user default", "Create", "User")
This was an attempt I made however it didn't work since EditOrCreate needs to be a view - ideally this scenario would not require the creation of another view.
public ActionResult EditOrCreate()
{
User user = Get(User.Identity.Name);
if (user != null)
Edit(user);
else
Create();
}
You can achieve that by having action link to SetUserDefault action method such as
#Html.ActionLink("set user default", "SetUserDefault", "User")
Inside the action method detect the user type and then redirect the user to the right action
public ActionResult SetUserDefault()
{
User currentUser = Get(User.Identity.Name);
if (currentUser != null)
return RedirectToAction("Edit", new { id = currentUser.Id });
else
return RedirectToAction("Create");
}
This code was Auto- generated by Visual studio
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Disassociate(string provider, string providerUserId)
{
string ownerAccount = OAuthWebSecurity.GetUserName(provider, providerUserId);
ManageMessageId? message = null;
// Only disassociate the account if the currently logged in user is the owner
if (ownerAccount == User.Identity.Name)
{
// Use a transaction to prevent the user from deleting their last login credential
using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
{
bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
if (hasLocalAccount || OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name).Count > 1)
{
OAuthWebSecurity.DeleteAccount(provider, providerUserId);
scope.Complete();
message = ManageMessageId.RemoveLoginSuccess;
}
}
}
return RedirectToAction("Manage", new { Message = message });
}
Why do we use Disassociate action in AccountController of Mvc?
The Disassociate action is used for removing a linked account (Google, Facebook, Microsoft, etc) from a user.
In the default MVC5 AccountController, its only usage is on the Manage Accounts page where it only shows up if the user has a local password or if the user has more than one linked account.
I'm just wondering where, in MVC, the responsibility for determining where to redirect belongs. I think it's the controller, but I'm not sure.
In the Create action of a WorkshopItem I'm creating a new WorkshopItem from the ViewModel passed in, then saving it to the database. Part of the ViewModel is a SelectedCustomerId and CustomerName, if the SelectedCustomerId is empty and the name is empty I get the default customer entity and associate it with the item. If the Id is empty but the name is not then the user has searched for a customer but no matches were found, so I take the value and create a new customer record and attach it.
[NHibernateActionFilter]
[HttpPost]
public ActionResult Create(WorkshopItemCreateViewModel model)
{
try
{
Customer customer = null;
if (model.SelectedCustomerId == new Guid() &&
!string.IsNullOrWhiteSpace(model.CustomerName))
customer = CreateNewCustomer(model.CustomerName);
else if (model.SelectedCustomerId == new Guid() &&
string.IsNullOrWhiteSpace(model.CustomerName))
{
// Assign the System Valued customer if no customer was selected.
var id = Guid.Parse(ConfigurationManager.AppSettings["ValuedCustomerId"]);
customer = Session.QueryOver<Customer>()
.Where(c => c.Id == id)
.SingleOrDefault();
}
// other stuff
return RedirectToAction("Index");
This is working fine, but now I want to also RedirectToAction depending on whether a customer record was created or not because if a customer was created it only has a Name and I'd like to redirect to the Edit action on the Customer Controller passing the CustomerId (which I think I can do). My question is really whether this is valid to do in MVC or should this be a responsibility elsewhere?
This would look like this:
[NHibernateActionFilter]
[HttpPost]
public ActionResult Create(WorkshopItemCreateViewModel model)
{
try
{
Customer customer = null;
bool newCustomer = false;
if (model.SelectedCustomerId == new Guid() &&
!string.IsNullOrWhiteSpace(model.CustomerName))
{
customer = CreateNewCustomer(model.CustomerName);
newCustomer = true;
}
else if (model.SelectedCustomerId == new Guid() &&
string.IsNullOrWhiteSpace(model.CustomerName))
{
// Assign the System Valued customer if no customer was selected.
var id = Guid.Parse(ConfigurationManager.AppSettings["ValuedCustomerId"]);
customer = Session.QueryOver<Customer>()
.Where(c => c.Id == id)
.SingleOrDefault();
}
// other stuff
if (newCustomer)
return RedirectToAction("Edit", "Customer", new {id=customer.Id});
else
return RedirectToAction("Index");
Absolutely, the controller maintains responsibility of returning content and redirecting to the appropriate actions. You can think of the controller as almost a traffic cop, directing things where to go and sending the right stuff to the appropriate places. An example from your code above might look something like this:
if (model.SelectedCustomerId == new Guid() && !string.IsNullOrWhiteSpace(model.CustomerName))
customer = CreateNewCustomer(model.CustomerName);
return RedirectToAction("Edit", new {id = customer.Id});
else if (model.SelectedCustomerId == new Guid() && string.IsNullOrWhiteSpace(model.CustomerName)){
// Assign the System Valued customer if no customer was selected.
var id = Guid.Parse(ConfigurationManager.AppSettings["ValuedCustomerId"]);
customer = Session.QueryOver<Customer>().Where(c => c.Id == id).SingleOrDefault();
return RedirectToAction("SomeOtherMethod");
}
// other stuff
return RedirectToAction("Index");