SimpleMembership, MVC4, AuthorizeAttribute и роли

Я пытаюсь добавить атрибуты авторизации к некоторым из моих контроллеров MVC4, и они работают нормально до тех пор, пока его план [Authorize] или [Authorize(Users="myuser")], но второй, который я добавляю в любом виде фильтрации роли, он разваливается, например, [Authorize(Roles="admin")]. Затем я начинаю получать ошибки, например:

Ошибка сервера в приложении "/".

Произошла ошибка, связанная с сетью или конкретным экземпляром, в то время как установление соединения с SQL Server. Сервер не найден или был недоступен. Проверьте правильность имени экземпляра и SQL Server настроен для удаленного подключения. (поставщик: SQL Сетевые интерфейсы, ошибка: 26 - Ошибка локализации сервера/экземпляра Указано)

Описание: Необработанное исключение произошло во время выполнения текущий веб-запрос. Просмотрите трассировку стека информацию об ошибке и где она возникла в коде.

Ошибка автоматического создания файла базы данных SQLExpress:

Строка подключения указывает локальный экземпляр Sql Server Express используя расположение базы данных в каталоге приложения App_Data. Поставщик попытался автоматически создать приложение базы данных служб, поскольку поставщик определил, что база данных не существует. Необходимы следующие требования к конфигурации успешно проверить наличие приложений базы данных и автоматически создать базу данных служб приложений:

Если приложение работает на Windows 7 или Windows Server 2008R2, необходимы специальные шаги настройки, чтобы создание базы данных поставщика. Дополнительная информация доступна at: http://go.microsoft.com/fwlink/?LinkId=160102. Если Каталог приложений App_Data еще не существует, сеть серверная учетная запись должна иметь доступ на чтение и запись к каталог. Это необходимо, потому что учетная запись веб-сервера будет автоматически создайте каталог App_Data, если он еще не существовать. Если каталог приложения App_Data уже существует, веб-сайт серверу требуется только чтение и запись на приложение App_Data. Это необходимо, потому что сеть сервер будет пытаться проверить, что Sql Server Express база данных уже существует в каталоге приложения App_Data. Отмена доступа для чтения в каталоге App_Data с веб-сервера учетная запись будет препятствовать правильному определению провайдера, если База данных Sql Server Express уже существует. Это приведет к ошибке когда поставщик пытается создать дубликат уже существующая база данных. Доступ к записи требуется, поскольку веб-сервер учетные данные используются при создании новой базы данных. SQL Сервер Express должен быть установлен на машине. Идентификатор процесса для учетной записи веб-сервера должен быть локальный профиль пользователя. См. readme для получения подробных сведений о том, как создать локальный профиль пользователя для как учетные записи машин и доменов.

Ошибка источника:

Необработанное исключение было создано во время выполнения текущий веб-запрос. Информация о происхождении и местонахождении исключение может быть идентифицировано с использованием трассы стека исключений ниже.

Трассировка стека:

[SqlException (0x80131904): связанный с сетью или конкретный экземпляр произошла ошибка при установлении соединения с SQL Server. сервер не найден или недоступен. Убедитесь, что экземпляр имя правильное и что SQL Server настроен на разрешение удаленного соединения. (поставщик: сетевые интерфейсы SQL, ошибка: 26 - ошибка Определение местоположения сервера/экземпляра)]
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction) +5295167 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +242
System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover) +5307115
System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover) +145
System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) +920
System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) +307
System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions) +434
System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) +5309659
System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) +38
System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource
1 retry, DbConnectionOptions userOptions, DbConnectionInternal & соединение) +5311874
System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection externalConnection, DbConnectionFactory connectionFactory, TaskCompletionSource 1 retry, DbConnectionOptions userOptions) +143
System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource
1 повторить попытку) +83 System.Data.SqlClient.SqlConnection.Open() +96
System.Web.Management.SqlServices.GetSqlConnection(String server, String user, String password, Boolean trusted, String connectionString) +76

[HttpException (0x80004005): невозможно подключиться к SQL Server базы данных.]
System.Web.Management.SqlServices.GetSqlConnection(String server, String user, String password, Boolean trusted, String connectionString) +131
System.Web.Management.SqlServices.SetupApplicationServices(String server, String user, String password, Boolean trusted, String connectionString, String database, String dbFileName, SqlFeatures функции, Boolean install) +89
System.Web.Management.SqlServices.Install(String database, String dbFileName, String connectionString) +27
System.Web.DataAccess.SqlConnectionHelper.CreateMdfFile(String fullFileName, String dataDir, String connectionString) +386

Информация о версии: Microsoft.NET Framework Версия: 4.0.30319; Версия ASP.NET: 4.0.30319.17929

Im действительно не уверен, что происходит здесь. Опять же, если я удалю бит роли атрибута authorize, то он отлично работает (насколько это возможно, если остановить неавторизованных пользователей), но это не хорошо, если мне нужно жестко закодировать пользователей admin в приложении!

Любая идея, что происходит здесь, и как я могу заставить ее работать правильно?

Спасибо,

Ответ 1

Я нашел решение (хотя я уверен, что это лучший способ сделать это). Во-первых, база данных, используемая SimpleMembership, не инициализирована достаточно рано, поэтому я переместил строку:

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

в файл Global.asax и убедитесь, что он запущен как можно раньше. Строку кода можно найти в разделе Фильтры → InitializeSimpleMembershipAttribute.cs, вокруг строки 41

Изменить: кажется, что следующий бит не нужен...

Во-вторых, атрибут [InitializeSimpleMembership] должен быть добавлен в любой класс, где членство может быть проблемой - для меня это все, поэтому я добавил строку:

filters.Add(new InitializeSimpleMembershipAttribute());

в файл FilterConfig.cs в папке app_start.

Эти два простых изменения, похоже, исправили это. Я уверен, что есть некоторые улучшения, которые я мог бы внести в общие работы с материалом SimpleMembership, включенным в MVC4, хотя это не очень хорошо написано (жестко закодированные строки подключения и т.д.!), Поэтому может быть, что эти проблемы могут быть устранены путем создания SimpleMembership хорошо написано в первую очередь!

Ответ 2

Вам не нужно перемещать первую строку. Я тестировал, просто добавив фильтр

filters.Add(new InitializeSimpleMembershipAttribute());

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

Ответ 3

InitializeSimpleMembershipAttrribute, сгенерированный шаблоном Интернета для MVC 4, был разработан для ленивой загрузки базы данных SimpleMembership в том случае, если разработчик не использует проверку подлинности форм. Если вы используете проверку подлинности форм, рекомендуется удалить этот фильтр и инициализировать его напрямую. Эта статья описывает, как это сделать.

Ответ 4

В MVC4 мне удалось добавить аннотацию к моему домашнему контроллеру, и эта ошибка перестала появляться:

[InitializeSimpleMembership]

Также необходимо было импортировать вверху по мере необходимости:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.AspNet;
using Microsoft.Web.WebPages.OAuth;
using WebMatrix.WebData;

Ответ 5

Проверьте настройки InitializeSimpleMembershipAttribute, настройки web.config для SimpleProviders и также можете рассмотреть возможность создания InitializeSimpleMembershipAttribute фильтра авторизации при использовании Authorize(Roles="any")