在REST架構的WCF服務中,它不像一般的WCF服務綁定,有配套的安全模式,實現起來那麼簡單。REST WCF服務只能在傳輸層加密,而一般的WCF 服務可以在訊息層加密。因此 REST WCF服務啟用ASP.NET相容模式後,它的安全是由ASP.NET來保證的。本篇文章主要介紹在 REST WCF 中如何?最簡單的 Username 驗證。
在SOAP協議的WCF中,可以通過SOAPHeader(MessageHeader)來實現使用者名稱密碼的傳輸,早在WebService時代我們就這麼用過了。在REST WCF中,我們可以利用 HttpHeader 來完成這一目標。 (你可不會想在每個服務契約裡加上使用者和密碼的參數吧...)
首先在服務中加入如下方法用於校正,Header的資訊:如果 Header 中 Authorization 的字串不是"fangxing/123" 那麼就將返回 405 MethodNotAllowed 的錯誤。這個字串的內容可以自訂,反正服務端根據某種規則檢查這個字串。
private bool CheckAuthorization()<br />{<br /> var ctx = WebOperationContext.Current;<br /> var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization];<br /> if (string.IsNullOrEmpty(auth) || auth != "fangxing/123")<br /> {<br /> ctx.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed;<br /> return false;<br /> }<br /> return true;<br />}
然後在每一個服務契約的實現中,都去調用它。
[WebGet(UriTemplate = "All")]
public List<Task> GetTask()
{
if (!CheckAuthorization())
return null;
return GetData();
}
[WebGet(UriTemplate = "{taskId}")]
public Task GetTaskById(string taskId)
{
if (!CheckAuthorization())
return null;
return GetData().FirstOrDefault(t => t.Id==taskId);
}
現在的服務,如果直接通過瀏覽器訪問,將得到 405 MethodNotAllowed 的錯誤:
用戶端只要相應的驗證信加到 RequestHeader 中去,就可以訪問了。用戶端可以使用單例模式設計 Client 對象。
這樣就不用每次調用都去加驗證資訊了。
var url = "http://localhost:3433/TaskService/All";<br />var client = new HttpClient();<br />client.DefaultHeaders.Add("Authorization", "fangxing/123");<br />var resp = client.Get(url);
* 這裡使用的是 Microsoft.Http.HttpClient (WCF REST Starter Kit) 而非 System.Net.WebClient
回頭看服務端代碼,每個服務實現中都需要加上 CheckAuthorization() 是不是很煩?
OK,我們知道這個 REST WCF服務是承載在一個Web Application上的, 通過往 RouteTable 中註冊 WebServiceHostFactory 來啟用服務物件的。 那麼只要對這個 WebServiceHostFactory 做些“手腳”,就可以實現服務端驗證的統一攔截,代碼如下。(一般的 WCF 也可以利用此方法對 MessageHeader 進行攔截校正)
public class SecureWebServiceHostFactory : WebServiceHostFactory<br /> {<br /> protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)<br /> {<br /> var host = base.CreateServiceHost(serviceType, baseAddresses);<br /> host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();<br /> return host;<br /> }</p><p> public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)<br /> {<br /> var host = base.CreateServiceHost(constructorString, baseAddresses);<br /> host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();<br /> return host;<br /> }<br /> }</p><p> public class MyServiceAuthorizationManager : ServiceAuthorizationManager<br /> {<br /> protected override bool CheckAccessCore(OperationContext operationContext)<br /> {<br /> var ctx = WebOperationContext.Current;<br /> var auth = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization];<br /> if (string.IsNullOrEmpty(auth) || auth != "fangxing/123")<br /> {<br /> ctx.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed;<br /> return false;<br /> }<br /> return true;<br /> }<br /> }
RegisterRoutes 裡的工廠類也需要相應的修改下:
var securewebServiceHostFactory = new SecureWebServiceHostFactory();<br />RouteTable.Routes.Add(new ServiceRoute("TaskService",<br /> securewebServiceHostFactory, typeof(TaskService)));
這樣服務端代碼就可以去掉 CheckAuthorization() 而把驗證工作都交給 SecureWebServiceHostFactory 了。
這種驗證方式,其實也是現在 Windows Auzer Access Control 的原型。 只不過這個 Authoriztion 的服務是專門的Services罷了。
1. 用戶端先從發布令牌的服務擷取令牌; 2. 用戶端拿著令牌提交到現在的服務; 3.服務端將用戶端令牌拿到發布令牌的服務上校正。
源碼下載:http://download.csdn.net/download/fangxinggood/3686322
【REST WCF系列】
RESTful WCF Services (1) (入門)
RESTful WCF Services (2) (實現增,刪,改,查)
RESTful WCF Services (3) (Raw Stream)
RESTful WCF Services (4) (Basic Security)
RESTful WCF Services (執行個體) (並發同步服務 SyncService)