在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编译测试了。
posted on 2006-08-20 01:37  榻榻米  阅读(416)  评论(0)    收藏  举报