【问题标题】:Not passing Credentials to WCF Service resulting in a 401未将凭据传递给 WCF 服务导致 401
【发布时间】:2013-10-06 21:38:42
【问题描述】:

我在这个问题上大吃一惊,我有一个 WCF 服务,我可以通过浏览器调用它,它工作正常,当我使用以下方法从 Web 应用程序调用它时,我得到一个 ( 401) 未经授权的错误。并且该服务不会被调用。更重要的是,当我从本地机器(使用 IIS Express 的调试模式)指向我的开发服务器(IIS7)运行我的 Web 应用程序时,它可以工作,但是当我将我的 Web 应用程序部署到开发服务器并将其指向开发服务器服务时因 401 错误而失败。我认为这与 IIS7 有关,但我不能 100% 确定,帮助会非常有用。

我已经在网上寻找答案,但到目前为止我找到的最好的答案是this

我的服务调用如下:

var request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/json; charset=utf-8";
request.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
request.Credentials = CredentialCache.DefaultCredentials;

WebResponse responce = request.GetResponse();
Stream reader = responce.GetResponseStream();

var sReader = new StreamReader(reader);
string outResult = sReader.ReadToEnd();
sReader.Close();

var result = (T) JsonConvert.DeserializeObject(outResult, typeof (T));
return result;

我的服务配置如下:

  <service name="RGMPServices.Householding.Services.AccountService" behaviorConfiguration="Default">
    <endpoint address="" kind="webHttpEndpoint" endpointConfiguration="SecuredHttpEndpointBinding" contract="RGMPServices.Householding.Contracts.IAccountService" />
  </service>

  <service name="RGMPServices.Householding.Services.HouseholdService" behaviorConfiguration="Default">
    <endpoint address="" kind="webHttpEndpoint" endpointConfiguration="SecuredHttpEndpointBinding" contract="RGMPServices.Householding.Contracts.IHouseholdService" />
  </service>

  <service name="RGMPServices.Householding.Services.UserService" behaviorConfiguration="Default">
    <endpoint address="" kind="webHttpEndpoint" endpointConfiguration="SecuredHttpEndpointBinding" contract="RGMPServices.Householding.Contracts.IUserService" />
  </service>
</services>

<behaviors>
  <endpointBehaviors>
    <behavior name="webBehaviour">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="Default">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

<standardEndpoints>
  <webHttpEndpoint>
    <standardEndpoint name="SecuredHttpEndpointBinding" helpEnabled="true" automaticFormatSelectionEnabled="true">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" />
      </security>
    </standardEndpoint>
  </webHttpEndpoint>
</standardEndpoints>

我已经在客户端服务调用上记录了一些日志,就在我调用服务之前,响应是:

调试 2013-10-01 13:15:13,569 452ms ServiceGetSingle - 通过登录:MYLANDOMAIN\MYLANUSERNAME

错误 2013-10-01 13:15:13,631 514ms ServiceGetSingle - 使用用户凭据登录调用 ServiceGetSingle 时出错:MYLANDOMAIN\MYLANUSERNAME System.Net.WebException:远程服务器返回错误:(401)未经授权。 在 System.Net.HttpWebRequest.GetResponse() 在 Householding.Common.ServiceHelper.ServiceGetSingle[T](String url)

代码如下:

logger.Debug("Passing Login: "
    + System.Security.Principal.WindowsIdentity.GetCurrent().Name)

即使我将网站的 AppPool 设置为我的域帐户,它仍然没有授权我访问 WCF 服务,但同样:它适用于浏览器。好诡异!

【问题讨论】:

标签: c# wcf iis-7 impersonation


【解决方案1】:

在使用Integrated Windows Authentication (IWA) 和Kerberos 时,您似乎是双跳问题的受害者。第一跳是从您的浏览器到 Web 应用程序;第二个跃点是从您的 Web 应用程序到 WCF 服务。

这里有一些资源可以更全面地解释这个问题,并可能提供解决方案:

您可以将 Active Directory 配置为支持 Kerberos delegation(通常基础架构人员不喜欢这样),或者您可以关闭模​​拟并为 Web 应用程序和 IIS 应用程序池使用“服务”帐户,该帐户可以通过以下方式进行身份验证代表最终用户的 WCF 服务。

【讨论】:

    【解决方案2】:

    开发服务器上的默认凭据是什么?尝试在那里做一个日志,看看你得到了什么。

    这是我怀疑的:在本地运行,凭据是您的 Windows 凭据。当您从 dev 调用开发服务器时,凭据将是网站运行的任何帐户。如果该特定帐户没有访问权限,那么它就会崩溃。

    【讨论】:

    • 是您从开发服务器运行应用程序时的日志吗?
    【解决方案3】:

    他们之前怎么说,这看起来像是一个冒名顶替问题。 您是否尝试使用“运行方式”启动客户端程序来更改凭据?

    另外你可以改变这行代码

    request.Credentials = CredentialCache.DefaultCredentials;
    

    request.Credentials = new NetworkCredential("MyUsername", "MyPassword");
    

    然后看看它是否有效。此外,您还需要在网络服务器上使用“MyPassword”创建帐户“MyUserName”以使其正常工作。

    【讨论】:

      【解决方案4】:

      当经过身份验证的用户无权访问托管 WCF 服务的物理路径时,可能会导致这些错误。在开发服务器上,打开 IIS 管理器并导航到服务的虚拟目录。在操作栏的右侧,单击“基本设置”。在“物理路径”文本框下方,单击“连接为...”。选择“特定用户”并尝试将其设置为您知道对开发服务器上的物理文件夹具有权限的用户帐户。通常,这将是一个密码不会过期的服务帐户。

      【讨论】:

        【解决方案5】:

        从浏览器运行时,浏览器会发送您的身份验证凭据。此外,iis express 将以登录用户身份运行,因此这也会发送您的凭据。 Iis 不同,它将作为本地帐户运行。即使您在前端 iis 上进行了身份验证,也不会传递到后端。 Windows 模拟令牌在允许的跃点数方面受到限制,通常为 0。这样做是为了防止您正在做的事情。 如果您希望前端身份验证流向后端,那么您可能应该自己进行身份验证并在通过的过程中获取用户/传递。或者,如果您自己进行身份验证,您可以创建一个模拟令牌,允许跳转到另一台机器,它应该可以工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-14
          • 2012-08-19
          • 1970-01-01
          • 2010-11-28
          相关资源
          最近更新 更多