【问题标题】:SQL Security with a WCF Service使用 WCF 服务的 SQL 安全性
【发布时间】:2013-09-23 20:54:52
【问题描述】:

我一直在开发 WCF 服务,该服务调用 Web 服务,然后调用 sql 服务器。在同一解决方案中进行测试时,一切正常。现在,我已经在 IIS 上托管了 WCF 服务,并且正在尝试从 asp.net Web 应用程序进行服务调用。 IIS 服务目前托管在我的本地计算机上。在 SQL Server Management Studio 中连接时,我使用 Windows 身份验证。当我调用 Web 服务时,在调用 SQL 时出现以下错误,因此我假设它不喜欢凭据:

Login failed for user 'MYDOMAIN\MYMACHINENAME$'.

这是我调用 Web 服务的代码。如您所见,我已尝试明确传递我的凭据:

var providerService = new ProviderServices.ProviderService();
providerService.Credentials = new NetworkCredential("myusername", "mypassword", "mydomain");
providerService.UseDefaultCredentials = false;

providerService.CheckProviderExclusion(PPLUser.CurrentProgram.ProgramLabel, ps.No, ps.ProviderName, ps.SocialSecurityNo);

这里是异常的内部文本:

用户“PCGUS\BON-0010882$”登录失败。在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection,Action'1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布尔调用者HasConnectionLock,布尔异步关闭) 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean & dataReady) 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(布尔 enlistOK) 在 System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo,字符串 newPassword,SecureString newSecurePassword,布尔型 ignoreSniOpenTimeout,TimeoutTimer 超时,布尔型 withFailover) 在 System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo,字符串 newPassword,SecureString newSecurePassword,布尔重定向用户实例,SqlConnectionString connectionOptions,SqlCredential 凭据,TimeoutTimer 超时) 在 System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer 超时,SqlConnectionString 连接选项,SqlCredential 凭据,字符串 newPassword,SecureString newSecurePassword,布尔重定向用户实例) 在 System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity 身份,SqlConnectionString connectionOptions,SqlCredential 凭据,对象 providerInfo,字符串 newPassword,SecureString newSecurePassword,布尔重定向用户实例,SqlConnectionString userConnectionOptions,SessionData reconnectSessionData) 在 System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions 选项,DbConnectionPoolKey poolKey,对象 poolGroupProviderInfo,DbConnectionPool 池,DbConnection owningConnection,DbConnectionOptions userOptions) 在 System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool 池,DbConnection owningObject,DbConnectionOptions 选项,DbConnectionPoolKey poolKey,DbConnectionOptions 用户选项) 在 System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject,DbConnectionOptions userOptions,DbConnectionInternal oldConnection) 在 System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject,DbConnectionOptions userOptions,DbConnectionInternal oldConnection) 在 System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,UInt32 waitForMultipleObjectsTimeout,布尔allowCreate,布尔onlyOneCheckConnection,DbConnectionOptions userOptions,DbConnectionInternal& 连接) 在 System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,TaskCompletionSource'1 重试,DbConnectionOptions userOptions,DbConnectionInternal& 连接) 在 System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection,TaskCompletionSource'1 重试,DbConnectionOptions userOptions,DbConnectionInternal oldConnection,DbConnectionInternal& 连接) 在 System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection,DbConnectionFactory connectionFactory,TaskCompletionSource'1 重试,DbConnectionOptions userOptions) 在 System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource'1 重试) 在 System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource'1 重试) 在 System.Data.SqlClient.SqlConnection.Open() 在 System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser 用户) 在 System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe() 在 System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode() 在 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式查询) 在 System.Data.Linq.DataQuery'1.System.Linq.IQueryProvider.Execute[S](表达式表达式) 在 System.Linq.Queryable.SingleOrDefault[TSource](IQueryable'1 源) 在 ProviderExclusionChecker.DataAccess.PCG_Proxy.CheckProviderExclusion(String programName, String providerID, String providerName, String providerSSN) 在 c:\TFS\PPL_Services\ProviderExclusionChecker\ProviderExclusionChecker\PCG Proxy.cs:line 72 在 ProviderExclusionChecker.ServicesApplication.ProviderService.CheckProviderExclusion(String programName, String providerID, String providerName, String providerSSN) 在 c:\TFS\PPL_Services\ProviderExclusionChecker\ProviderExclusionChecker.ServicesApplication\ProviderService.svc.cs:line 21 在 SyncInvokeCheckProviderExclusion(对象,对象 [],对象 []) 在 System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象实例,对象 [] 输入,对象 [] 和输出) 在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin (MessageRpc& rpc) 在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) 在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) 在 System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)System.Data.SqlClient.SqlException

如何配置服务来验证我的 sql server 连接?

【问题讨论】:

  • 1) 在 SQL Server 上为MYDOMAIN\MYMACHINENAME$ 提供登录名,2) 在有权登录 SQL Server 的帐户下运行应用程序池,或 3) 在 SQL Server 上为您的帐户创建一个帐户服务并在连接字符串中使用该帐户和密码。
  • 我会选择 #3 并为该服务创建一个 SQL 帐户,并只为其提供 WCF 服务所需的权限。
  • 问题是,我的机器凭据与 sql server 相同(Windows 活动目录凭据)。我还没有查看应用程序池 - 可能设置为其他内容。我会试试的。

标签: wcf service credentials


【解决方案1】:

这里有几个层,每个层都可以选择它发送到下一层的身份验证。

您的 WCF 服务正在使用 Windows 凭据调用 Web 服务。假设这有效:

  • 调用来自 IIS,根据 IIS 设置,这些凭据被使用或丢失。例如,如果 IIS 是匿名的,那么它只会丢失。
  • 然后它会访问应用程序池,其中 web.config 中的设置确定是否使用凭据。
  • 然后它访问数据库,其中连接字符串确定使用哪些凭据。

还有一个“双跳”问题,默认情况下,服务无法传递在使用之前重新传递的凭据。不确定这是否会影响您。

【讨论】:

    【解决方案2】:

    我可能会迟到,但我正在寻找相同的解决方案。然而,我找到了自己。 你可以试试: 1. 运行 inetmgr。 2. 转到应用程序池 3. 搜索您的应用程序指向的应用程序池。 4.检查身份列 5. 您可以通过右键单击属性来修改标识列的值。 6.确保身份用户应该有windows身份验证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      • 2013-09-25
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      相关资源
      最近更新 更多