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")