在Asp.net上搭建ws服務並進行使用者的驗證是非常簡單的。Asp.net的身分識別驗證有三種,分別是Windows|Forms|Passport,其中又以Forms驗證用的最多,也最靈活。普通的Aspx使用者驗證和授權訪問沒有什麼區別, Forms驗證方式給予使用者的授權提供了很好的支援,我們可以在一個login.asmx中驗證使用者的身份,並將此身份發送回用戶端的cookie,之後使用者在訪問這個web應用就會連同這個身份cookie以其發送到服務端。服務端上的授權設定就可以根據不同目錄對不同使用者的訪問授權進行控制。
下面通過一個執行個體來看一看怎樣在Flash+asp.net WS中實現基於角色的使用者驗證和授權訪問。
1、 目錄結構
claw 根目錄
default.aspx 預設訪問頁
default.build Nant編譯檔案
Global.asax
Global.asax.cs 處理Application_AuthorizeRequest事件
login.asmx
login.asmx.cs ws服務,使用者登入
web.config 應用程式設定檔
admin 子目錄,授權訪問目錄
web.config 應用程式設定檔
admin.asmx 授權訪問的ws服務
admin.asmx.cs
bin 子目錄,放置編譯後的dll檔案
2、 身分識別驗證:
在這個例子中,admin目錄被授權給admin使用者組訪問。使用者的身分識別驗證主要是通過兩級目錄下web.config檔案中的<authorization> </ authorization>小節進行設定(當然。也可以通過<location>小節進行設定),在根目錄下的web.config設定時將 <authentication >小節設定如下,定義該應用程式採用Forms設定:
<authentication mode="Forms" >
<forms name=".AKS_Claw" loginUrl="./default.aspx" timeout="1" path="/" />
</authentication>
<authorization>小節設定,容許匿名使用者存取:
<authorization>
<allow users="*" />
</authorization>
admin目錄下的,主要用來放置匿名訪問,因為Forms驗證不支援Roles屬性,因此使用者角色的授權在Global.asax中完成:
<configuration>
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
下面撰寫WS服務login.asmx的代碼:
/* ======================================================================
C# Source File -- Created with SAPIEN Technologies Primalcode 3.0
NAME: login.asmx.cs
AUTHOR: JimLee , Dxl School
DATE : 2004-10-19
COMMENT: 檢查使用者的登入
====================================================================== */
using System;
using System.Web;
using System.Web.Security;
using System.Web.Services;
using System.Security.Principal;
namespace AKS.Claw{
[WebService(Namespace="http://www.AKS2046.com/ws/",Description="檢查使用者的登入,並且儲存到用戶端",Name="login") ]
public class login:WebService{
public login(){}
[WebMethod(Description="檢查使用者登入")]
public bool checkUser(string uName,string uPW){
bool t=false;
if (confirm(uName,uPW)){
WriteUserTicket(uName,uPW);
t=true;
}
return t;
}
[WebMethod (Description="檢查使用者登入是否admin角色")]
public bool showRoles(){
string tstr="";
tstr=Context.User.Identity.ToString();
return Context.User.IsInRole("admin");
}
private void WriteUserTicket(string uName,string uPW){
string userRoles=UserToRole(uName);
FormsAuthenticationTicket tk=new FormsAuthenticationTicket(1,uName,DateTime.Now,DateTime.Now.AddMinutes(1),false,userRoles,"/");
string Hashtk=FormsAuthentication.Encrypt(tk);
HttpCookie UserCookie=new HttpCookie(FormsAuthentication.FormsCookieName,Hashtk);
Context.Response.Cookies.Add(UserCookie);
}
private bool confirm(string uName,string uPW){
return ((uName=="JimLee")&&(uPW=="123456"));
}
private string UserToRole(string uName){
string tStr="user";
if (uName=="JimLee") tStr="admin";
return tStr;
}
}
}
在這裡,偷懶了:帳號驗證方法confirm和規則設定都在代碼中寫入程式碼了。赫赫。
3、 授權訪問
在web.config中我們並沒有設定使用者的驗證,只是在admin中禁止匿名訪問,事實上,我是要讓admin使用者組的使用者才能訪問admin目錄下的服務。再強調一遍:Forms驗證不支援Roles屬性,因此,通過GenericPrincipal使用者物件的IsInRole方法判斷使用者是否admin使用者組之後再進行操作,當然,你可以把授權驗證放到方法層級。在這裡,我把這一過程放在應用程式的Application_AuthorizeRequest事件中,不需要再每個方法中進行編碼:
如下:
/* ======================================================================
C# Source File -- Created with SAPIEN Technologies Primalcode 3.0
NAME: Global.asax.cs
AUTHOR: JimLee , Dxl School
DATE : 2004-10-19
COMMENT: <comment>
====================================================================== */
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Security.Principal;
namespace AKS.Claw
{
public class Global : System.Web.HttpApplication
{
public Global(){}
protected void Application_AuthorizeRequest(object Sender,System.EventArgs e){
HttpApplication App=(HttpApplication)Sender;
HttpContext Ctx=App.Context;
if (Ctx.Request.IsAuthenticated==true){
FormsIdentity Id=(FormsIdentity)Ctx.User.Identity;
FormsAuthenticationTicket tk=Id.Ticket;
string[] Roles=tk.UserData.Split(',');
Ctx.User=new GenericPrincipal(Id,Roles);
if (Ctx.Request.Path.Split('/')[2]=="admin"){
if (Ctx.User.IsInRole("admin")==false){
Ctx.Response.Redirect("../default.aspx");
}
}
}
}
}
}
4、 編寫授權訪問的admin目錄下的WS服務admin.asmx:
/* ======================================================================
C# Source File -- Created with SAPIEN Technologies Primalcode 3.0
NAME: admin.asmx.cs
AUTHOR: JimLee , Dxl School
DATE : 2004-10-19
COMMENT:
====================================================================== */
using System;
using System.Web;
using System.Web.Services;
namespace AKS.Claw{
[WebService(Namespace="http://www.AKS2046.com/ws/",Description="管理員操作",Name="admin") ]
public class admin:WebService{
public admin(){}
[WebMethod]
public string test(){
return "test";
}
}
}
5、 Nant .build檔案
注意,admin目錄下的檔案編譯之後要放到根目錄下的bin目錄下。
<?xml version="1.0" encoding="gb2312" ?>
<project name="AKS_Claw_v1.0" default="run">
<property name="basename" value="AKS_Claw_v1.0"/>
<property name="debug" value="true"/>
<target name="clean">
<delete>
<fileset>
<include name="bin\${basename}-??.exe"/>
<include name="bin\*.dll" />
<include name="bin\*.pdb" />
</fileset>
</delete>
</target>
<target name="build" depends="clean">
<csc target="library" output="bin\Global.asax.dll" debug="${debug}">
<sources>
<include name="Global.asax.cs" />
</sources>
</csc>
<csc target="library" output="bin\admin.asmx.dll" debug="${debug}">
<sources>
<include name="admin\admin.asmx.cs" />
</sources>
</csc>
<csc target="library" output="bin\login.asmx.dll" debug="${debug}">
<sources>
<include name="login.asmx.cs" />
</sources>
</csc>
<csc target="library" output="bin\function.dll" debug="${debug}">
<sources>
<include name="function.cs" />
</sources>
</csc>
<csc target="exe" output="bin\${basename}-cs.exe" debug="${debug}">
<sources>
<include name="tMain.cs"/>
</sources>
<references>
<include name="bin\function.dll" />
</references>
</csc>
</target>
<target name="run" depends="build">
<exec program="bin\${basename}-cs.exe" basedir="."/>
</target>
</project>
然後,就可以用Nant編譯測試了。