2014-01-06 55 views
1

我有一個自我託管的WCF服務,具有簡單的用戶名/密碼驗證。在託管服務conosle應用程序代碼中的「安全」部分是:Windows Phone 8 BasicHttpBinding安全

BasicHttpBinding b = new BasicHttpBinding(); 
b.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; 
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; 
//add endpoint 
selfHost.AddServiceEndpoint(typeof(ISettings), b, "SettingsService"); 

//add creditential check 
selfHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; 
selfHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomValidator(); 

但我不能弄清楚如何在我的Windows手機上使用的用戶名/密碼creditentials做的,這是我有這麼遠:

BasicHttpBinding httpBinding = new BasicHttpBinding(); 
httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; 

sc = new SettingsClient(httpBinding, new EndpointAddress("http://" + addressField.Text + "/IC/SettingsService")); 
sc.ClientCredentials.UserName.UserName = "test"; 
sc.ClientCredentials.UserName.Password = "test123"; 

總是返回401錯誤。另外我沒有任何特殊的配置在我的XML文件。

+0

是託管在IIS或IIS Express/WebDev? – Cybermaxs

+0

它是自己託管的。 – Squeazer

回答

0

行,所以我想通了這一點,我有好幾個問題:

  1. 我是從另一個項目乳寧自託管服務,但我有App.configfile在同一項目作爲我的服務。不知道它必須在你運行服務的同一個項目中,對我來說很愚蠢。

  2. 我現在有我的xml文件中的所有配置,但我可以把它放在代碼中,它仍然可以工作。

  3. 參照這個LINK,它描述瞭如何在WP7上進行身份驗證(適用於WP8)。

  4. 確保在更改服務中的某些內容時更新服務參考。

客戶端代碼:

private void Click(object sender, RoutedEventArgs e) { 
     ServiceClient sc = new ServiceClient(); 
     using (OperationContextScope scope = new OperationContextScope(sc.InnerChannel)) { 
      HttpRequestMessageProperty request = new HttpRequestMessageProperty(); 
      request.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " + EncodeBasicAuthenticationCredentials("test", "test123"); 
      OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, request); 
      sc.setPushUriAsync(pushChannel.ChannelUri.ToString()); 
      } 

} 

private string EncodeBasicAuthenticationCredentials(string username, string password) { 
    string credentials = username + ":" + password; 
    var asciiCredentials = (from c in credentials 
          select c <= 0x7f ? (byte)c : (byte)'?').ToArray(); 

    return Convert.ToBase64String(asciiCredentials); 
} 

客戶端配置文件:

<configuration> 
    <system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="BasicHttpBinding_ISettings" maxBufferSize="2147483647" 
        maxReceivedMessageSize="2147483647"> 
        <security mode="TransportCredentialOnly" /> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://MACHINE_IP_ADDR:8045/MyService/" binding="basicHttpBinding" 
       bindingConfiguration="BasicHttpBinding_ISettings" contract="SettingsServiceReference.ISettings" 
       name="BasicHttpBinding_ISettings" /> 
     </client> 
    </system.serviceModel> 
</configuration> 

服務器配置文件:

<configuration> 
    <system.serviceModel> 
    <services> 
     <service behaviorConfiguration="ValidatorServiceBehaviour" 
       name="WCFServiceLibrary.SettingsService"> 
     <endpoint binding="basicHttpBinding" 
        bindingConfiguration="ValidatorBinding" 
        contract="WCFServiceLibrary.ISettings" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8045/MyService/" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ValidatorServiceBehaviour"> 
      <serviceDebug httpsHelpPageEnabled="true" 
         includeExceptionDetailInFaults="true" /> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" 
            customUserNamePasswordValidatorType="UserValidator.Validator, UserValidator" /> 
      </serviceCredentials> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 

    <bindings> 
     <basicHttpBinding> 
     <binding name="ValidatorBinding"> 
      <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Basic"/> 
      </security> 
     </binding> 

     </basicHttpBinding> 
    </bindings> 

    </system.serviceModel> 
</configuration> 

驗證器只是一個標準UserNamePasswordValidator

+0

如果有人知道更好的方法來做到這一點,沒有編碼的用戶名/密碼和手動設置標題,請添加您的答案。 – Squeazer

1

你可以做這樣的事情:

客戶端配置文件:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpsBinding_ITestService"> 
       <security mode="TransportWithMessageCredential" /> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="https://test/TestService.svc" 
      binding="basicHttpBinding" bindingConfiguration="BasicHttpsBinding_ITestService" 
      contract="ITestService" name="BasicHttpsBinding_ITestService" /> 
    </client> 
</system.serviceModel> 

客戶端代碼:

var client = new TestServiceClient("BasicHttpsBinding_ITestService"); 
client.ClientCredentials.UserName.UserName = "User name"; 
client.ClientCredentials.UserName.Password = "password";