ASP.NET MVC 3 с использованием аутентификации
-
26-09-2019 - |
Вопрос
Как я могу сохранить что-то с использованием формальных возможностей? Я не хочу хранить useriD через URL-адрес.
Например, теперь у меня есть этот код:
//UserController class:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (repository.ValidateUser(model.Login, model.Password))
{
FormsAuthentication.SetAuthCookie(model.Login, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Project", "Index");
}
}
else
{
ModelState.AddModelError("", "Incorrect name or password.");
}
}
return View(model);
}
ProjectController
сорт:
public ViewResult Index()
{
return View(repository.GetUserProjects(
this.ControllerContext.HttpContext.User.Identity.Name));
}
ProjectRepository
:
ProjectsContext context = new ProjectsContext();
UsersContext uCnt = new UsersContext();
public IEnumerable<Project> GetUserProjects(String username)
{
if (String.IsNullOrEmpty(username))
throw new ArgumentNullException("username", "Login is empty");
return this.uCnt.Users
.FirstOrDefault(u => u.Login == username)
.Projects
.ToList();
}
ProjectController и ProjectRepository не выглядит как хороший код ... Может быть, кто-то может дать посоветую, как хранить userid без использования URL? Я думаю, что лучший способ сделать это сохранить идентификаторы на авторизации, я думаю. Я не найду никаких свойств пользователя.
Уполномоченный
Я прошу прощения, но я забыл сказать, что я использую MVC-3 с видом на бритву. И что UserID не является строкой (user.identity.name - это строка), это может быть GUID или, может быть, мой собственный объект ...
Решение
Сохраните идентификатор пользователя в свойстве UserData билета FindaUshenticenticenticenticenticenticenticenticanceenticance Pubreiance, когда пользователь входит в систему:
string userData = userID.ToString();
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.Email,
DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
createPersistentCookie, userData);
string hashedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashedTicket);
HttpContext.Current.Response.Cookies.Add(cookie);
Вы можете прочитать его обратно в методе PostauthenticateRequest в Global.Asax:
HttpCookie formsCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (formsCookie != null)
{
FormsAuthenticationTicket auth = FormsAuthentication.Decrypt(formsCookie.Value);
Guid userID = new Guid(auth.UserData);
var principal = new CustomPrincipal(Roles.Provider.Name, new GenericIdentity(auth.Name), userID);
Context.User = Thread.CurrentPrincipal = principal;
}
Обратите внимание, что в этом случае CustomPrincipal вытекает из рольпреспипала (хотя, если вы не используете роли, я думаю, вам нужно вытекать от GenericPrincipal), и просто добавляет свойство UserID и перегружает конструктор.
Теперь, где вам нужен userid в вашем приложении, вы можете сделать это:
if(HttpContext.Current.Request.IsAuthenticated)
Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID;
Другие советы
Почему бы сначала не сделайте все ваши звонки авторизации через интерфейс. Таким образом, весь ваш код, который использует аутентификацию, не нужно беспокоиться о том, как проводится логин, или как сохраняется ввод и т. Д.
public interface IAuthorization
{
bool ValidateUser(LoginUser u, string password);
LoginUser GetCurrentUser();
void LogIn(LoginUser user);
void LogOut();
IIdentity GetCurrentUserIdentity();
}
Неадресация для IIIDETITY GETCurrentUseristretity может быть любым способом, которым вам нравится, но обычно рассматривается как звонок для «httpContext.Current.user.identity»
public class Authorization : IAuthorization
{
/// <summary>
/// Get the IIdentity for the current logged in user
/// </summary>
/// <returns>IIdentity</returns>
public virtual IIdentity GetCurrentUserIdentity()
{
return HttpContext.Current.User.Identity;
}
/// <summary>
/// Log the user in
/// </summary>
/// <param name="user">User details</param>
public void LogIn(LoginUser user)
{
InvalidCredentialsOnNullUser(user);
FormsAuthentication.SetAuthCookie(user.Name, false);
}
/// <summary>
/// Log the user out
/// </summary>
public void LogOut()
{
FormsAuthentication.SignOut();
}
private static void InvalidCredentialsOnNullUser(LoginUser user)
{
if (user == null)
{
throw new InvalidCredentialException("That user doesn't exist or is not valid.");
}
}
// other methods....
}
Класс LoginUser, который вы видите, это информация о том, что получено о пользователю членства. Это обычно делается через членствоProvider, но, конечно, может быть сделано другими способами.
public class LoginUser
{
public string Name;
public Guid Key;
public string EmailAddress;
public bool IsApproved;
public bool IsLockedOut;
public DateTime CreationDate;
public DateTime? LastLoginDate;
public DateTime? LastPasswordChangedDate;
}
Я не уверен, что я правильно понимаю вопрос, но если вы относитесь к способу извлечения, кто текущий пользователь не передает его через URL (например, http: // localhost / контроллер / действие? Имя пользователя = rame0) Тогда вы можете посмотреть на использование Thread.CurrentPrincipal.identity.name или httpcontext.current.user
Однако есть тонкие различия между ними. Смотреть здесь Больше подробностей.
С использованием FormsAuthentication
Вы можете хранить имя пользователя в User.Identity.Name
имущество. Вот простой пример того, что вы, вероятно, ищете. (Используя то же самое SetAuth
Вы уже используете)
public ViewResult Index() {
return View(repository.GetUserProjects(this.User.Identity.Name));
}
Это не требует от вас, чтобы пройти имя пользователя через параметр QueryString.