Хранить / назначать роли аутентифицированных пользователей - PullRequest
54 голосов
/ 01 декабря 2009

Я обновляю сайт для использования MVC и ищу лучший способ настройки аутентификации.

На данный момент у меня работает вход в систему из Active Directory: проверка имени пользователя и пароля, а затем установка файла cookie Auth.

Как сохранить информацию о роли пользователя во время входа в систему, чтобы мои контроллеры могли видеть эти роли при перемещении пользователя по сайту?

[Authorize(Roles = "admin")]

У меня нет проблем с получением списка ролей из Active Directory. Я просто не знаю, где их разместить, чтобы контроллеры их увидели.

Ответы [ 5 ]

125 голосов
/ 01 декабря 2009

Роли добавляются к IPrincipal HttpContext. Вы можете создать GenericPrincipal , проанализировать список ролей в конструкторе и установить его как HttpContext.User. GenericPrincipal будет доступен через User.IsInRole("role") или атрибут [Authorize(Roles="role")]

Один из способов сделать это (в C #) - добавить свои роли в виде строки через запятую в параметре пользовательских данных при создании билета для аутентификации

string roles = "Admin,Member";
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
  1,
  userId,  //user id
  DateTime.Now,
  DateTime.Now.AddMinutes(20),  // expiry
  false,  //do not remember
  roles, 
  "/");
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
                                   FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(cookie);

Затем получите доступ к списку ролей из билета аутентификации и создайте GenericPrincipal из вашего Global.asax.cs

protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
  HttpCookie authCookie = 
                Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null) {
      FormsAuthenticationTicket authTicket = 
                                  FormsAuthentication.Decrypt(authCookie.Value);
      string[] roles = authTicket.UserData.Split(new Char[] { ',' });
      GenericPrincipal userPrincipal =
                       new GenericPrincipal(new GenericIdentity(authTicket.Name),roles);
      Context.User = userPrincipal;
    }
  }
6 голосов
/ 01 декабря 2009

Когда вы аутентифицируете своего пользователя, вы генерируете новый экземпляр GenericPrincipal. Конструктор принимает массив строк, которые являются ролями для пользователя. Теперь установите HttpContext.Current.User равным универсальному принципалу и запишите файл cookie аутентификации, и это должно сделать это.

5 голосов
/ 19 ноября 2013

Для тех из вас, кто использует MVC 4 или Greater, вам понадобится совет Ярослава Валишко при использовании ответа Дэвида Гленна:

«Я протестировал его в ASP.NET MVC 4 и предлагаю вместо этого использовать Application_PostAuthenticateRequest. В противном случае общий принципал будет переопределен». - Ярослав Валишко 7 сентября в 16: 18

Итак, как указано выше, все, что вам нужно сделать, это заменить имя метода Application_AuthenticateRequest на Application_PostAuthenticateRequest, чтобы заставить это работать. Работал как шарм для меня! Если бы мне разрешили объявить голосование Ярославу и Давиду, я бы.

3 голосов
/ 07 июля 2011

Я бы просто хотел создать поставщика ролей. Пример здесь:

http://www.danharman.net/2011/06/23/asp-net-mvc-3-custom-membership-provider-with-repository-injection/

1 голос
/ 01 декабря 2009

Не могли бы вы добавить диспетчер ролей хранилища авторизации или найти (например, в Codeplex) или записать другого поставщика ролей, который работает с Active Directory для получить информацию о группах?

Это избавит вас от необходимости аутентификации пользователя, получения его ролей и последующей повторной передачи этой информации в конструктор, и все это произойдет автоматически для вас как части фреймворка.

...