Razbezhkin
@Razbezhkin
программист, преподаватель

Как переделать аутентификацию в asp.net mvc3?

Здравствуйте!

при использовании стандартной системы аутентификации в asp.net mvc3 в контексте конроллера доступно стовойства User, которое реализует интерфейс System.Security.Principal.IPrincipal.

Все бы хорошо, но в этом контексте доступно только имя пользователя через User.Identity.Name, а вот, например, UserId или чего то подобного увы — нет.


Можно переопределить MembershipProvider, перегрузить метод GetUser(), который вернет объект типа MembershipUser, который, в свою очередь, будет содержать стандартное свойство ProviderUserKey — именно тот идентификатор, который мне и нужен.


Таким образом, для получения userid нужно будет вызвать

System.Web.Security.Membership.GetUser().ProviderUserKey


Вопрос:

1. Каков жизненный цикл объекта, возвращаемого свойством User (тот, который доступен в классе контроллера)?

2. можно ли как то этот жизненный цикл переделать, чтобы после аутентификации контроллеровское свойство User возвращало что-то, что содержало бы UserId, а возможно, что-то еще? (в методе описанном в предыдущих двух абзацах меня смущает то, что метод GetUser() выполняет «большую» работу по извлечению UserId по его имени, причем каждый раз, когда его нужно получить, хочеться получить userid один раз при аутентификации и использовать везде без лишних затрат.)


Спасибо за внимание.
  • Вопрос задан
  • 3882 просмотра
Решения вопроса 1
@lair
Идем в исходники.

    public IPrincipal User
    {
      get
      {
        if (this.HttpContext != null)
          return this.HttpContext.User;
        else
          return (IPrincipal) null;
      }
    }


Здесь, в общем-то ответ сразу на оба вопроса. Вот типичный пример того, что с этим делают.

Другое дело, что я вам искренне не советую так делать, а советую пользоваться сразу Windows Identity Foundation, в которой любая необходимая вам вещь хранится в так называемых claim, привязанных к текущему принципалу.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@lair
Формировать контекст безопасности при каждом http запросе мне кажется неразумным с точки зрения производительности.

Зато разумно с точки зрения безопасности. Можно кэшировать.

Альтернативный вариант — использовать Session_Start в Global.asax. Если ли в этом случае противопоказания?

Да. в какой-то момент получите устаревшие данные.
Ответ написан
Razbezhkin
@Razbezhkin Автор вопроса
программист, преподаватель
Спасибо.
С использованием WIF я пока решил повременить.
Если смотреть в сторону использования IPrincipal, то в нем нет места для UserID, но можно сделать собственный класс, реализующий IPrincipal, который будет содержать необходимые свойства, или можно хранить в сессии пользователя дополнительный объект для хранения этих сведений.

Вот тут возникает интересный (для меня) момент: в какой момент эту информацию сохранть в сессии или в HttpContext. Если аутентификация выполняется методом Form, то на странице ввода логина и пароля, но есть еще один интересный момент: пользователь может попросить «запомнить» его, чтобы не вводить в следующий раз логин и пароль, при этом пользователь в следующей сессии будет залогиненым, хотя никакой проверки подлинности произведено не будет и даже пользователя может уже не быть такого на сайте.

В каком месте в этом случае лучше всего формировать контекстную информацию пользователя?
Ответ написан
Razbezhkin
@Razbezhkin Автор вопроса
программист, преподаватель
authenticate меня смущает тем, что он выполняется при каждом http запросе. Формировать контекст безопасности при каждом http запросе мне кажется неразумным с точки зрения производительности.

Альтернативный вариант — использовать Session_Start в Global.asax. Если ли в этом случае противопоказания?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы