SimpleMembership,MVC4,AuthorizeAttribute和Roles (注:这是一个提问标题,无需回答)

11
我试图在我的MVC4控制器中添加授权属性,只要是简单的[Authorize][Authorize(Users="myuser")]都可以正常工作,但是一旦我添加了任何类型的角色过滤,例如[Authorize(Roles="admin")],它就会失败。然后我开始收到像以下这样的错误:

'/' 应用程序中的服务器错误。

在建立到 SQL Server 的连接时出现与网络相关的或特定于实例的错误。找不到服务器,也无法访问。请验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。(提供程序:SQL Network Interfaces,错误: 26 - 没有找到指定的服务器/实例)

说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,了解有关该错误以及代码中其发源位置的详细信息。

SQLExpress 数据库文件自动创建错误:

连接字符串指定了一个本地 Sql Server Express 实例,使用应用程序 App_Data 目录中的数据库位置。提供程序尝试自动创建应用程序服务数据库,因为提供程序确定该数据库不存在。必须满足以下配置要求,才能成功检查应用程序服务数据库的存在并自动创建应用程序服务数据库:

如果应用程序在 Windows 7 或 Windows Server 2008R2 上运行,则需要特殊的配置步骤才能启用提供程序数据库的自动创建。有关更多信息,请访问:http://go.microsoft.com/fwlink/?LinkId=160102。如果应用程序的 App_Data 目录尚不存在,则 Web 服务器帐户必须具有对应用程序目录的读取和写入访问权限。这是必要的,因为如果它不存在,Web 服务器帐户将自动创建 App_Data 目录。如果应用程序的 App_Data 目录已经存在,则 Web 服务器帐户只需要对应用程序的 App_Data 目录具有读取和写入访问权限。这是必要的,因为当 Web 服务器帐户尝试验证 Sql Server Express 数据库是否已经存在于应用程序的 App_Data 目录中时,将会出现错误。撤销 Web 服务器帐户对 App_Data 目录的读取访问权限将防止提供程序正确地确定 Sql Server Express 数据库是否已经存在。这将导致提供程序尝试创建已经存在的数据库的副本时出错。由于 Web 服务器帐户的凭据用于创建新数据库,因此需要写入访问权限。必须在计算机上安装 Sql Server Express。Web 服务器帐户的进程标识必须具有本地用户配置文件。有关如何为机器和域帐户创建本地用户配置文件的详细信息,请参阅自述文件。

源错误:

在当前的Web请求执行期间,发生了一个未处理的异常。可以使用下面的异常堆栈跟踪信息来确定异常的起源和位置。
堆栈跟踪:

[SqlException (0x80131904): 在连接到 SQL Server 时发生网络或特定实例的错误。找不到服务器,或服务器无法访问。请验证实例名称是否正确,并验证 SQL Server 是否配置为允许远程连接。(提供程序: SQL Network Interfaces, error: 26 - 找不到指定的服务器/实例)]
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 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& connection) +5311874
System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) +143
System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource
1 retry) +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 features, 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

我真的不确定这里发生了什么。如果我移除授权属性的角色部分,那么至少阻止未经授权的用户是可以正常工作的,但如果我必须将管理员用户硬编码到应用程序中,这样也没有意义!

你有什么想法吗?如何使它正常工作?

谢谢。


你确定角色/组的拼写是正确的吗? - user751651
5个回答

15

我已经找到了解决方案(尽管我确信有更好的方法)。首先,SimpleMembership使用的数据库没有足够早地初始化,所以我把这行代码移到了:

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

将该行代码添加到Global.asax文件并确保尽早运行。该行代码可以在Filters-> InitializeSimpleMembershipAttribute.cs中找到,大约在第41行。

编辑:看起来下面这部分不是必需的...

其次,在可能涉及成员资格的任何类中都需要添加[InitializeSimpleMembership]属性 - 对我来说,所有类都是如此,因此我添加了以下行:

filters.Add(new InitializeSimpleMembershipAttribute());

将其添加到app_start文件夹中的FilterConfig.cs文件中。

这两个简单的更改似乎已经解决了它。我相信我可以对MVC4中包含的SimpleMembership工作原理进行一些改进,因为它看起来写得不是很好(硬编码连接字符串等!),因此通过首先使SimpleMembership良好编写,可能可以解决这些问题!


1
+1 谢谢你。你的解决方案解决了我的问题。同时,我还为其他遇到这个问题的人找到了这篇文章:https://dev59.com/HWct5IYBdhLWcg3wNq6v?rq=1 - Neil Thompson
嘿,@Dylan,这对我有用,干杯!我已经为此苦苦挣扎了几天。 - Randi Ratnayake

6

您不需要移动第一行。我测试了只添加过滤器的情况。

filters.Add(new InitializeSimpleMembershipAttribute());

如果您正在创建一个需要登录的网站,您可以将其放在一个控制器上,而不必在所有控制器上都添加此功能。


2

由MVC 4的Internet模板生成的InitializeSimpleMembershipAttrribute旨在为未使用表单身份验证的开发人员提供SimpleMembership数据库的惰性加载。如果您正在使用表单身份验证,则建议删除此过滤器并直接初始化它。这篇文章描述了如何执行此操作:article describes how to do this.


2
在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;

1
检查 InitializeSimpleMembershipAttribute 的使用, web.config 的 SimpleProviders 设置,还可以考虑将 InitializeSimpleMembershipAttribute 设为授权过滤器(特别是当使用 Authorize(Roles="any") 时)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接