2011-05-03 118 views
5

我一直在爲此搜索幾天。WCF .net 4.0 HTTP基本認證

我只是想使用基本HTTP身份驗證將用戶名/密碼傳遞到我的RESTful服務。其他的一切都起作用了!

這裏是我的web.config的樣子:

<?xml version="1.0"?> 
<configuration> 

    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 

    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"> 
     <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 
    </modules> 
    </system.webServer> 

    <system.serviceModel> 

    <bindings> 
     <wsHttpBinding> 
     <binding name=""> 
      <security mode="Message"> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 

    <standardEndpoints> 
     <webHttpEndpoint> 
     <!-- 
      Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
      via the attributes on the <standardEndpoint> element below 
     --> 
     <standardEndpoint name="" helpEnabled="true" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true"/> 
     </webHttpEndpoint> 
    </standardEndpoints> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ParkingPandaREST.CustomUserNameValidator, ParkingPandaREST" /> 
      </serviceCredentials>  
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 


    </system.serviceModel> 

</configuration> 

然後,我創建了一個具有以下一個CustomUserNameValidator類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace ParkingPandaREST 
{ 
    public class CustomUserNameValidator : System.IdentityModel.Selectors.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")) 
      { 
       // This throws an informative fault to the client. 
       throw new System.ServiceModel.FaultException("Unknown Username or Incorrect Password"); 
       // When you do not want to throw an infomative fault to the client, 
       // throw the following exception. 
       // throw new SecurityTokenException("Unknown Username or Incorrect Password"); 
      } 
     } 
    } 
} 

我只是在我的本地機器上運行的服務,試圖在CustomUserNameValidator類中創建一個斷點,但它永遠不會到達那裏。所以我現在不使用SSL,只是試圖讓用戶名/密碼被傳入。

回答

4

這是我想出的答案。它可能需要稍微調整一下,但它是完成工作所需的核心。

注:關閉基本身份驗證在IIS

  // Get the Header Authorization Value 
      string headerValue = operationContext.IncomingRequest.Headers[HttpRequestHeader.Authorization]; 
      headerValue = headerValue.Replace("Basic ", ""); 
      headerValue = DecodeBase64String(headerValue); 

      // Get Username and Password 
      string userName = headerValue.Substring(0, headerValue.IndexOf(":")); 
      string password = headerValue.Substring(headerValue.IndexOf(":") + 1, headerValue.Length - userName.Length - 1); 

      // Do Custom Authorization here with the userName and password 

.......

而且這裏是DecodeBase64String功能

public static string DecodeBase64String(string encodedData) 
    { 
     byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData); 
     string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes); 
     return returnValue; 
    } 

希望可以幫助一些人誰有同樣的問題 - 歡呼!

+3

相同的問題我建議使用Encoding.UTF8.GetString(encodedData),雖然 – 2011-08-03 08:27:12

+0

你把這個代碼在哪裏? – jao 2016-09-02 09:13:37

1

WCF 4中HTTP傳輸的默認綁定是basicHttpBinding。如果您將wsHttpBinding元素轉換爲basicHttpBinding元素並將其配置爲自定義驗證,那麼您的代碼應該執行。

+0

我只是試圖改變,仍然無法讓它擊中斷點。 我是否缺少其他東西? – Adam 2011-05-03 17:54:08

+0

可能是您的客戶端配置和服務配置不同步。此外,您需要配置IIS以允許HTTP基本身份驗證。 IIS配置將因版本而異,但這裏是IIS 7配置:http://technet.microsoft.com/en-us/library/cc772009(WS.10).aspx – 2011-05-03 18:03:27

+0

所以這不適用於我的本地開發人員計算機VS2010 - 剛剛擊中F5並將其置於調試模式? – Adam 2011-05-03 18:15:16

0

基本認證是一種HTTP協議。因此它是傳輸安全性,而不是消息安全性。你的配置應該包含這個片段:

<security mode="Transport"> 
    <transport clientCredentialType="Basic" /> 
</security> 

但是,即使你得到這個權利,你的自定義代碼可能不會被調用。你會在這個blog中找到關於這個問題的更多細節。

+0

爲了處理我的服務的基本身份驗證,我使用:http://altairiswebsecurity.codeplex.com/我將我的服務託管爲MVC控制器而不是WCF。 – 2011-05-03 19:09:14

+0

因此,對於WCF的全新版本,您無法正確執行基本的HTTP身份驗證......太糟糕了! – Adam 2011-05-03 19:26:50

+0

@Codo無法跟隨您的鏈接的博客:(我有我的自定義驗證程序沒有執行 – Dendei 2013-02-25 12:35:42