Аутентификация на основе ролей в новом интернет-шаблоне MVC 4 с использованием simplemembership

Мне нравится новая функция simplemembership в интернет-шаблоне MVC 4 со ссылками на OAuth для внешнего входа в VS 2012 RTM. По большей части функция аутентификации работает. Однако, даже потратив на это более 8 часов, я не могу реализовать авторизацию на основе ролей для работы на моих контроллерах. SimpleMembership оказывается совсем не простым.

Я искал stackoverflow, гуглил и читал последнюю версию от John Galloway, попробовал много предложений, но до сих пор не получил смог решить эту проблему. Все началось с получения ошибки подключения Sql, и я не мог понять, почему, когда строка подключения и все остальное были в порядке. Потребовалось много часов, чтобы выяснить, что именно класс Roles вызывает проблему.

Атрибут [Authorize] на контроллерах работает, как и раньше, для базовой аутентификации. Но каждый раз, когда я пытаюсь использовать роли, возникает ошибка подключения sql (потому что он возвращается к старому DefaultRolesProvider, который пытается подключиться к файлу aspnetdb SqlExpress по умолчанию и терпит неудачу). Так что-то вроде:

[Authorize(Roles="admin")]

не работает. Это сработает, если я вернусь к старым поставщикам членства на asp.net, но тогда я потеряю простые таблицы базы данных, подтверждение и восстановление баз токенов, более безопасное хеширование паролей и, что более важно, внешние логины через OAuth.

Единственное, что работает внутри кода и бритвенных представлений, - это

User.IsInRole("admin")

что подходит для пунктов меню и тому подобного, но очень громоздко для реализации внутри каждого отдельного действия в контроллере (и мне не нравится, что он проверяет только одну роль за раз).

Буду очень признателен за любые рекомендации по решению этой проблемы.


person Ahmed    schedule 04.09.2012    source источник


Ответы (2)


Нашел ответ здесь Mehdi Golchin, который, кажется, заботится о:

[Authorize(Roles="admin,editor,publisher")]

Если я также добавлю это к домашнему контроллеру:

 [InitializeSimpleMembership]

Поскольку этот атрибут находится на контроллере учетных записей, база данных SimpleMembership инициализируется только после первого использования контроллера учетных записей, например входа / регистрации. Даже когда текущий пользователь входит в систему с помощью файла cookie, база данных не инициализируется и выдает ошибку. Одним из решений является установка этого атрибута на домашний контроллер, который вызывается при запуске моего веб-сайта. Но тогда его нужно разместить на каждом контроллере, потому что я проверяю роли и отображаю разные пункты меню в зависимости от роли.

Это плохой дизайн, поскольку база данных должна быть инициализирована в App_Start, а не при первом использовании.

Я пытался поставить

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

в Global.asax Application_Start(), и он заботится о проверке ролей в пунктах меню с помощью User.IsInRole("admin"), но затем выдает ошибку в любом контроллере с атрибутом [Authorize(Roles="admin")], даже если применяется дополнительный атрибут [InitializeSimpleMembership].

Итак, прямо сейчас решение состоит в том, чтобы поместить `[InitializeSimpleMembership] на все контроллеры, поскольку пользователь может изначально попасть на любую страницу, используя внешние ссылки.

Он все еще не может понять, как инициализировать класс SimpleRolesProvider, чтобы выполнять больше функций управления ролями, а не просто User.IsInRole().

Эти вещи лучше работают на сайте веб-страниц веб-матрицы, и, очевидно, перенос MVC не завершен. Он конфликтует и путается с поставщиками членства asp.net по умолчанию.

ИЗМЕНИТЬ ОК. Я не думал, что фильтр [InitializeSimpleMembership] можно применить глобально, поместив эту строку в FilterConfig.cs в папке App_Start:

filters.Add(new InitializeSimpleMembershipAttribute());

Это решит эту проблему. Теперь нужно решение для инициализации SimpleRolesProvider, иначе мне придется написать свой собственный поставщик ролей.

ОБНОВЛЕНИЕ:

Это сообщение Скотта Аллена решило все мои проблемы.

Включив это в web.config:

<roleManager enabled="true" defaultProvider="simple">
  <providers>
    <clear/>
    <add name="simple" type="WebMatrix.WebData.SimpleRoleProvider,               WebMatrix.WebData"/>
  </providers>      
</roleManager>
<membership defaultProvider="simple">
  <providers>
    <clear/>
    <add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider,                          WebMatrix.WebData"/>
  </providers>
</membership>

все методы классов Roles и Membership становятся доступными и могут быть инициализированы в коде следующим образом:

var roles = (SimpleRoleProvider) Roles.Provider;
var membership = (SimpleMembershipProvider) Membership.Provider;
person Ahmed    schedule 04.09.2012
comment
Следует отметить, что приведенное выше содержимое конфигурации должно находиться в разделе ‹system.web›. - person BladeLeaf; 02.01.2013
comment
Спасибо, Ахмед, ты спас меня от красивой головной боли! - person s0nica; 24.01.2013
comment
Спасибо, сэр. Вы не представляете, насколько это мне помогло. - person programad; 31.01.2013
comment
Для аутентификации на основе ролей, например, при использовании [Authorize(Roles="Admin")], если пользователь вошел в систему, но WebSecurity не инициализирован, вы получите ошибку, поскольку фильтры авторизации запускаются первыми. Сделайте InitializeSimpleMembershipAttribute IAuthorizationFilter, см. сообщение - person edteke; 16.10.2013

Была такая же проблема, когда я перемещал свое веб-приложение с VS2010 / MVC3 на VS2012 / MVC4.

И не смог заставить [InitializeSimpleMembership] работать.

Выяснилось, что добавление этого в ваш web.config помогает:

  <appSettings>
    <add key="enableSimpleMembership" value="false" />
  </appSettings>

И все работает нормально, как и раньше.

person keun    schedule 28.02.2013