2016-12-13 103 views
1

空我有WCF REST服務,它接受XML數據作爲輸入,並返回太一些數據。要實現基本認證,我使用ServiceAuthorizationManager。 CheckAccessCore方法調用兩次。首先,當我在RequestStream中寫入XML數據時,第二次調用GetResponse來獲取我的服務返回的數據。在第一次調用CheckAccessCore中的授權標頭是正確的,但是當它被第二次調用時(在GetResponse期間)授權標頭爲空。授權報頭是在第二呼叫

ServiceAuthorizationManager CheckAccessCore方法

protected override bool CheckAccessCore(OperationContext operationContext) 
    { 
     var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"]; 

     if (!string.IsNullOrEmpty(authHeader)) 
     { 
      var credentials = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6))).Split(':'); 
      var user = new 
      { 
       Name = credentials[0], 
       Password = credentials[1] 
      }; 

      if (user.Name == "test" && user.Password == "pass") 
      { 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 
     else 
     { 
      WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm =\"CreditData\""); 
      throw new WebFaultException(HttpStatusCode.Unauthorized); 
     } 
    } 

WCF的Web.config

<system.serviceModel> 
 
    <behaviors> 
 
     <endpointBehaviors> 
 
     <behavior name="RestBehavior"> 
 
      <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml"/> 
 
     </behavior> 
 
     </endpointBehaviors> 
 
     <serviceBehaviors> 
 
     <behavior> 
 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="True"/> 
 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
 
      <serviceAuthorization serviceAuthorizationManagerType="CreditDataService.Authorization.CreditDataAuthorizationManager, CreditDataService" /> 
 
     </behavior> 
 
     </serviceBehaviors> 
 
    </behaviors> 
 
    <services> 
 
     <service name="CreditDataService.Services.CreditData" behaviorConfiguration=""> 
 
     <endpoint name="REST" behaviorConfiguration="RestBehavior" binding="webHttpBinding" contract="CreditDataService.Contracts.ICreditData"/> 
 
     </service> 
 
    </services> 
 
    <protocolMapping> 
 
     <add binding="webHttpBinding" scheme="https"/> 
 
    </protocolMapping> 
 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/> 
 
</system.serviceModel>

客戶

private void button4_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:33016/Services/CreditData.svc"); 
      byte[] bytes = System.Text.Encoding.UTF8.GetBytes("<Request><Firstname>John</Firstname><Lastname>Doe</Lastname><Pid>123456789</Pid></Request>"); 
      request.ContentType = "application/x-www-form-urlencoded"; 
      request.ContentLength = bytes.Length; 
      request.Method = "POST"; 

      string credentials = "test:pass"; 
      string enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials)); 
      string auth = string.Format("{0} {1}", "Basic", enc); 

      request.Headers[HttpRequestHeader.Authorization] = auth; 

      Stream reqStream = request.GetRequestStream(); 
      reqStream.Write(bytes, 0, bytes.Length); 
      reqStream.Close(); 

      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
      if (response.StatusCode == HttpStatusCode.OK) 
      { 
       Stream respStream = response.GetResponseStream(); 
       string respStr = new StreamReader(respStream).ReadToEnd(); 
       MessageBox.Show(respStr); 
      } 
     } 
     catch (WebException ex) 
     { 
      if (ex.Response != null) 
      { 
       var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd(); 
       MessageBox.Show(resp); 
      } 

      MessageBox.Show(ex.Message); 
     } 
    } 

沒有ServiceAuthorizationManager它工作得很好。

回答

0

問題是Web服務的方法的UriTemplate。這是空的,當我打電話給服務時,發生只有斜槓重定向到相同的網址。例如當我發出請求「http://localhost/myservice.svc」它被重定向到「http://localhost/myservice.svc/」。這出現了第二個請求,並且這第二個請求的授權標頭爲空。當我添加UriTemplate問題解決。