代码之家  ›  专栏  ›  技术社区  ›  Joshy

未将凭据传递给WCF服务,导致401

  •  7
  • Joshy  · 技术社区  · 11 年前

    我在这个问题上很紧张,我有一个WCF服务,我可以通过浏览器调用它,它工作得很好,当我用下面的方法从web应用程序调用它时,我得到一个 (401)未经授权 错误而且该服务不会被呼叫。更重要的是,当我从指向开发服务器(IIS7)的本地机器(使用IIS Express的调试模式)运行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:13569 452ms ServiceGetSingle-通过登录:MYLANDOMAIN\MYLANUSERNAME

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

    代码如下所示:

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

    即使我将网站的AppPool设置为我的域帐户,它仍然没有授权我访问WCF服务,但同样:它对浏览器有效。太奇怪了!

    5 回复  |  直到 11 年前
        1
  •  1
  •   Kit    11 年前

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

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

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

        2
  •  1
  •   Ryan Bennett    11 年前

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

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

        3
  •  1
  •   Luiz Felipe    11 年前

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

    此外,您可以更改这行代码

    request.Credentials = CredentialCache.DefaultCredentials;
    

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

    看看它是否有效。此外,您需要在web服务器上创建带有“MyPassword”的帐户“MyUserName”才能使其工作。

        4
  •  1
  •   Jason    11 年前

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

        5
  •  1
  •   Mike    11 年前

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