接觸WebService沒多久,一個令我困擾的問題就是怎麼樣給自己開發的WebService加上身份認證的功能,因為我不想什麼亂七八糟的人使用我的服務,因為這個WebService可能存在一些有關個人隱私的資訊,除了授權的人之外,閑雜人等一律要拒之門外。這個對於Windows應用程式來說易如反掌的功能在WebService上應該如何?呢?
具體如何?者一功能有許多方法,在CodeGuru的Build Secure Web Services With SOAP Headers and Extensions文章中使用了一種不錯的方法,可以大體上解決我的問題,但是在Quotes2實現裡每次都需要驗證一次使用者名稱和密碼,而Quote3實現的方法假如使用HTTP GET和HTTP POST好像又會失效,總是感覺美中不足,有沒有一種方法可以對WebService的任何調用方式都有效呢?經過多方尋找資料,終於找到一個可行的方法:利用Session。假如你編寫過Web應用程式的話,對於Session肯定不陌生,對於需要保持狀態的程式而言,Session和Application是必不可少的,比如那些論壇和留言版等等。我們這裡就要利用相同的機制實現使用者認證。
首先我給WebService添加一個名為Login的方法:
[WebMethod (EnableSession = true)]
public string Login(string userName, string password)
{
if (userName == "username" && password == "password")
{
Session["login"] = 1;
return "welcome";
}
else
return "login failed";
}
這裡僅僅是一個樣本,因此我簡化了使用者的認證過程,Login方法很簡單,它所作的工作就是在使用者身分識別驗證通過之後將Session["login"]置為1表示使用者通過驗證,否則返回"login failed"的錯誤資訊。這裡的實現和一般的WebMethod沒有什麼區別,除了多了一個屬性EnableSession = true之外。這是我們實現認證功能的關鍵所在,在這個WebService中,所有的方法都必須使用這個屬性加以標記。
好了,伺服器端的工作就查不多了(這麼簡單,不可思議吧),為了檢驗我們這個方法是否有效,我們再添加一個方法驗證一下:[WebMethod (EnableSession = true)]
public string GetStatus()
{
if (Convert.ToInt32(Session["login"]) == 1)
return "Thank you.";
else
return "Please Login first.";
}
現在我們來編寫一個用戶端驗證一下到底這個方法是否有效,建立一個控制台程式TestCon,添加這個程式的Web引用,並把引用檔案夾重新命名為login,編寫如下代碼:using System;
using System.Data;
using System.Data.SqlClient;
using TestCon.login;
class MainEntryPoint
{
static void Main(string[] args)
{
LoginService ls = new LoginService();
Console.WriteLine(ls.Login("username", "password"));
Console.ReadLine();
Console.WriteLine(ls.GetStatus());
}
}
Ctrl+F5運行程式,程式運行結果如下:
呵呵,結果好像不對,使用者名稱和密碼都沒錯,調用GetStatus為什麼失敗了呢?想想這這結果是理所當然的,Session儲存資料是靠cookie實現的,我們這個是一個普通的控制台程式,它又沒什麼地方存放cookie資訊,自然不能正確使用了。假如用一個asp程式測試的話,認證功能已經實現,不信你試一下!
但是我們要在普通的應用程式中實現使用者認證,難道就沒有辦法了麼,當然有了,既然程式沒地方存放cookie,那我們給它一個不就完了嘛,好,我們改寫程式如下:using System;
using System.Data;
using System.Data.SqlClient;
using System.Net;
using TestCon.login;
class MainEntryPoint
{
static void Main(string[] args)
{
LoginService ls = new LoginService();
CookieContainer cc = new CookieContainer();
ls.CookieContainer = cc;
Console.WriteLine(ls.Login("username", "password"));
Console.ReadLine();
Console.WriteLine(ls.GetStatus());
}
}
再Ctrl+F5,變:
哈,這下對了吧,功夫不負有心人,這下你想用我的WebService就沒那麼容易了吧,搞定,呵呵!