带数据库的Web服务:SqlException

时间:2011-05-29 11:28:56

标签: sql-server database web-services sqlexception

我写了一个与SQL Server'08数据库一起使用的Web服务

当我尝试调用Web方法时,我得到了这个:

System.Data.SqlClient.SqlException: Login failed for user 'IIS APPPOOL\ASP.NET v4.0'.
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
   at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
   at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
   at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
   at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user)
   at System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe()
   at System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode()
   at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
   at System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at route.Logic..ctor() in C:\Users\Ilya\Documents\Visual Studio 2010\Projects\MobitourLibrary\route\Logic.cs:line 20
   at Service..ctor() in c:\inetpub\wwwroot\RouteGen\App_Code\Service.cs:line 14

问题出在哪里? 其他win表单应用程序使用相同的DB工作正常,为什么WS没有?

3 个答案:

答案 0 :(得分:3)

Web服务将在WinForms应用程序的不同用户帐户下运行。 WinForms应用程序将使用登录用户的用户帐户进行操作,而Web服务将是ASP.NET使用的帐户。

您需要在SQL Server中设置该帐户并为其授予相关权限。

基本上,您需要将登录添加到服务器,并将该登录作为用户添加到需要它的每个数据库。

以下是您在SQL Server Management Studio中的分步说明:

  • 在对象资源管理器中,打开SQL Server树并进入安全性 - &gt;登录分支
  • 右键单击“登录”并选择“新登录...”
  • 接下来登录名称,点击“搜索”
  • 点击“高级”以获取“选择用户或组”对话框
  • 点击“立即查找”
  • 滚动对话框底部的列表,找到相关用户并双击它。对话框将关闭。
  • 按“好的”。对话框将关闭。
  • 返回“登录 - 新建”对话框,按“确定”

您现在有了新的登录信息。

现在,在数据库中创建用户。

  • 打开树的数据库分支。
  • 打开您需要的特定数据库的分支,然后是安全性 - >用户分支。
  • 右键单击“用户”并选择“新用户...”
  • 写一个用户名(它不必与登录名匹配,但通常也是如此)
  • 在“登录名”旁边按“...”按钮
  • 按“选择登录对话框”中的“浏览”
  • 在“浏览对象”对话框中检查所需的登录名。
  • 按“确定”。对话框将关闭
  • 按“确定”。选择登录对话框将关闭。
  • 选择“此用户拥有的架构” - 通常为“db_owner”
  • 选择数据库角色成员资格 - 通常它将是DBA创建的特定角色,如果不是,则db_datareader&amp; db_datawriter权限。如果您遇到问题,请选择db_owner然后使用您的DBA来更正权限(您不希望为ASP.NET进程分配数据库所有者权限,除非您真的必须,这是一个等待发生的安全漏洞)
  • 按“确定”关闭“数据库用户新建”对话框。

现在应该都很好。

您可以更改Web服务中的连接字符串,以使其使用特定帐户连接到SQL Server。

答案 1 :(得分:2)

Colin Mackay为您的问题提供了详细的解答。这是我的两分钱。

如果您的环境中设置了Active Directory域,我会建议在您的连接中包含user idpassword。相反,我建议如下:

  1. 创建一个域帐户MyDomain\webservice,其中 MyDomain 是活动目录域, webservice 将是该域中的Windows用户帐户。在SQL中,为此新域帐户用户提供访问数据库的适当权限。

  2. Internet Information Services (IIS) Manager中,将应用程序池更改为在此服务帐户下运行。如果您运行的是IIS 7.5,则可以执行以下步骤:

  3. IIS中,展开您的<server name>节点,然后点击Application Pools

  4. 最好创建一个新的Application Pool,这样就不会干扰可能使用应用程序池ASP.NET v4.0的其他应用程序的功能。

  5. 创建类似于ASP.NET v4.0应用程序池的新应用程序池(比如说WebServiceAppPool),除了新应用程序池将使用新的标识创建了域帐户MyDomain\webservice,而不是通常的 ApplicationPoolIdentity

  6. 在部署了Web服务的虚拟目录/站点的Advanced Settings选项中,更改应用程序池属性以使用新创建的应用程序池{{1 }}

  7. 我相信这个设置更安全,并且它还可以避免在连接字符串中硬编码用户ID和密码。

    希望有所帮助。

答案 2 :(得分:0)

该消息清楚地表明:登录失败 .....用户(IIS APPPOOL\ASP.NET v4.0尝试连接数据库时没有权限。

不知道任何其他细节,我假设这是一个在IIS中托管的ASP.NET Web应用程序/ Web服务,并且您很可能有一个连接字符串到打开了Integrated Security=SSPI设置的数据库 - 因此,当前用户(这里是IIS apppool用户)尝试连接到数据库 - 而不能。

因此,更改连接字符串(请参阅http://www.connectionstrings.com上的大量示例)以指定可以连接的特定数据库用户:

server=YourServer;database=YourDatabase;User ID=SomeValidUser;Pwd=Top$ecret