WP7 + WCF + IIS + HTTPS(传输)+基本身份验证

时间:2011-07-22 13:16:23

标签: wcf iis windows-phone-7 https

我已经阅读了很多关于使用WP7 + WCF(IIS 7)通过HTTPS进行基本身份验证的问题的帖子,但我仍然遇到麻烦......

如果我只使用没有BasicAuth的HTTPS传输,它就像魅力一样。但两种组合对我来说都不起作用......

也许你可以帮我识别我的失败......

我的ClientConfig:

<configuration>
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
                maxReceivedMessageSize="2147483647">
              <security mode="Transport" />
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint 
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
            contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
    </client>
</system.serviceModel>

我的服务配置:

    <?xml version="1.0"?>
<configuration>
  <appSettings/>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WP7.CustomUserNameValidator, WP7" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
      <basicHttpBinding>
        <binding maxReceivedMessageSize="2147483647"> 
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="TransportWithMessageCredential" >
            <transport clientCredentialType="Basic"/>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

我在服务中使用的CustomUserNameValidator:

namespace WP7
{
public class CustomUserNameValidator : UserNamePasswordValidator
    {
        // This method validates users. It allows in two users, 
        // test1 and test2 with passwords 1tset and 2tset respectively.
        // This code is for illustration purposes only and 
        // MUST NOT be used in a production environment because it 
        // is NOT secure.
        public override void Validate(string userName, string password)
        {

            if (null == userName || null == password)
            {
                throw new ArgumentNullException();
            }

            if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
            {
                throw new FaultException("Unknown Username or Incorrect Password");
            }
        }
    }
}

我的Wp7应用中的代码调用方法同步(使用以下解决方案:http://cisforcoder.wordpress.com/2010/12/01/how-to-implement-basic-http-authentication-in-wcf-on-windows-phone-7/#comment-174):

proxy = new ServiceReference1.Service1Client();
            proxy.Endpoint.Address = new System.ServiceModel.EndpointAddress(new Uri(Details.mySettings.EndpointAddress));

            proxy.PingServerCompleted += new EventHandler<ServiceReference1.PingServerCompletedEventArgs>(proxy_PingServerCompleted);

            var credentials = EncodeBasicAuthenticationCredentials("test1", "1tset");

            using (OperationContextScope scope =
                      new OperationContextScope(proxy.InnerChannel))
            {
                HttpRequestMessageProperty request = new HttpRequestMessageProperty();
                request.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " + credentials;

                OperationContext.Current.OutgoingMessageProperties.Add(
                                                   HttpRequestMessageProperty.Name, request);
                proxy.PingServerAsync(myServer);
            }

private string EncodeBasicAuthenticationCredentials(string username, string password)
        {
            //first concatenate the user name and password, separated with :
            string credentials = username + ":" + password;

            //Http uses ascii character encoding, WP7 doesn’t include
            // support for ascii encoding but it is easy enough to convert
            // since the first 128 characters of unicode are equivalent to ascii.
            // Any characters over 128 can’t be expressed in ascii so are replaced
            // by ?
            var asciiCredentials = (from c in credentials
                                    select c <= 0x7f ? (byte)c : (byte)'?').ToArray();

            //finally Base64 encode the result
            return Convert.ToBase64String(asciiCredentials);
        }

此外,我已将IIS虚拟目录中的“基本身份验证”设置设置为“已启用”。

每次我都有一些不同的错误例外: CommunicationException或SecurityException或其他什么......

有人可能会解决我的问题?

感谢。 杰森

1 个答案:

答案 0 :(得分:2)

客户端还需要指定clientCredentialType - 客户端配置中缺少该值。因此,客户端不期望必须发送凭据,但服务期待它们