| 
				 三、程序代码 
由于在验证用户账号是否为已注册此账号时需要把XML文件中的数据读入到DataSet中,因此调用一个ReadXml()方法完成XML数据读取即可。例如: 
DataSet ds=new DataSet(); 
ds.ReadXml(@"..\..\Users.xml"); 
    上面的代码将Users.xml文件的数据读入到了名为ds的DataSet中。 
当通过Windows管理员账号登录时,要利用基于角色的安全性中Windwos验证策略判断当前用户是否为管理员角色,因此使用WindowsPrincipal类可以用来检查 Windows 用户的 Windows 组成员身份。然后利用前面介绍过的WindowsPrincipal类型中的IsInRole方法可以确定当前用户是否属于指定的 Windows 用户组。例如: 
  WindowsPrincipal WinPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal; 
        if (WinPrincipal.IsInRole(WindowsBuiltInRole.Administrator)) 
         {   
MessageBox.Show("您是管理员!"); 
             } 
上面的代码通过Thread对象的CurrentPrincipal属性获取当前线程的主体(Principal),然后使用IsInRole方法判断是否为管理员角色,如果是则弹出提示信息。 
下面首先给出Users类的实现源代码及注释: 
public class Users 
{ 
   public bool IsLogin(string strName, string strPassword) 
   {    // 用于判断账号是否存在于 XML文件中的方法 
       DataSet dsUsers = new DataSet(); 
       DataRow[] drRows; 
       bool ret = false; 
        try {    
// 将XML文件中记录的所有已注册的用户名和密码读入DataSet中 
        dsUsers.ReadXml(@"..\..\Users.xml"); 
        //在DataSet中搜索输入的用户名和密码信息,以判断此注册用户是否存在 
drRows = dsUsers.Tables[0].Select("name = '" +  
                        strName + "' and password = '" + strPassword + "'"); 
           if (drRows.Length > 0)  
            { 
//如果有返回行,表示存在此注册用户 
                ret = true; 
            } 
            else  
            { 
                ret = false; 
            } 
       } catch(FileNotFoundException e) 
        { 
 MessageBox.Show("Users.Xml 文件不存在。", "无法验证用户。", 
 MessageBoxButtons.OK, MessageBoxIcon.Warning); 
            Application.Exit(); 
        } 
       return ret; 
    } 
    public GenericPrincipal GetLogin(string strName, string strPassword) 
{   /* 返回封装GenericIdentity类型数据和用户角色名称的一般主体 
GenericPrincipal类型数据的方法*/        
  DataSet dsUsers = new DataSet(); 
        DataRow[] drRows = null; 
       try { 
// 将XML文件中记录的所有已注册的用户名和密码读入DataSet中 
            dsUsers.ReadXml(@"..\..\Users.xml"); 
/*通过在DataSet中搜索输入的用户名和密码,将完整的用户信息(包括用户 
角色)读入到drRows中*/ 
            drRows = dsUsers.Tables[0].Select("name = '" +  
                    strName + "' and password = '" + strPassword + "'"); 
       } catch( FileNotFoundException e) 
        { 
            MessageBox.Show("Users.Xml 文件不存在。","关闭中...", 
                  MessageBoxButtons.OK, MessageBoxIcon.Warning); 
            Application.Exit(); 
        } 
// 创建一个代表用户的GenericIdentity类型数据 
        GenericIdentity GenIdentity = new GenericIdentity(strName); 
// 将角色关系定义成字符数组 
        string[] Roles  = {Convert.ToString(drRows[0]["Role"]), ""}; 
/*通过封装GenericIdentity类型数据和用户角色名称创建一个一般主体 
        GenericPrincipal类型数据*/ 
        GenericPrincipal GenPrincipal =  
new GenericPrincipal(GenIdentity, Roles); 
        return GenPrincipal; 
    } 
    public bool IsAdministrator() 
{ 
//使用WindowsPrincipal类可以用来检查用户是否为管理员角色 
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); 
 WindowsPrincipal WinPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal; 
        if (WinPrincipal.IsInRole(WindowsBuiltInRole.Administrator))  
        { 
            return true; 
        } 
        else  
        { 
            return false; 
        } 
    } 
} 
下面是当用户提交输入的数据后,程序实现用户身份验证功能的源代码。 
    private void btnOK_Click(object sender, System.EventArgs e)  
    { 
        // 创建一个User类型的对象 
        Users objUser = new Users(); 
        GenericPrincipal GenPrincipal; 
        string strName = txtUserName.Text; 
        string strPassword = txtPassword.Text; 
        /*依据复选框是否选中而采取相应的验证策略,选中采用基于角色的安全性中 
Windwos验证策略*/ 
        if (chkAdministratorAccount.Checked)  
        { 
            if (objUser.IsAdministrator())  
            { 
                MessageBox.Show(Thread.CurrentPrincipal.Identity.Name +  
                    " 欢迎进入**系统!","登录成功", 
                    MessageBoxButtons.OK, MessageBoxIcon.Information); 
        //如果为管理员角色,则显示后台后台账号数据界面 
                frmMain Main = new frmMain(); 
                Main.ShowDialog(); 
        // 将登录界面隐藏 
                this.Close(); 
            } 
            else  
            { 
        /*通过intLoginAttempts来判断用户尝试登录次数,如果大于3次则程序强 
行退出*/ 
            intLoginAttempts += 1; 
MessageBox.Show("您并非管理员账号,请提供用户名和密码。", 
this.Text, 
                  MessageBoxButtons.OK,MessageBoxIcon.Exclamation); 
            } 
        } 
        else  
        { 
            // 判断输入的帐户是否在已注册帐户之列 
            if (objUser.IsLogin(strName, strPassword))  
            { 
                GenPrincipal = objUser.GetLogin(strName, strPassword); 
                Thread.CurrentPrincipal = GenPrincipal; 
            MessageBox.Show(Thread.CurrentPrincipal.Identity.Name + 
                    " 欢迎进入**系统!", "登录成功", 
            MessageBoxButtons.OK,MessageBoxIcon.Information); 
//如果为已注册帐户,则显示后台后台账号数据界面 
                frmMain Main = new frmMain(); 
                Main.ShowDialog(); 
// 将登录界面隐藏 
                this.Close(); 
            } 
            else  
            { 
                intLoginAttempts += 1; 
                if (intLoginAttempts >= 3)  
                { 
  
                    MessageBox.Show("多次输入错误,请稍候重试!", 
this.Text, 
                        MessageBoxButtons.OK,MessageBoxIcon.Exclamation); 
                    Application.Exit(); 
                } 
                else  
                { 
                    MessageBox.Show("无法找到该用户,请重试!",  
this.Text, 
                       MessageBoxButtons.OK,MessageBoxIcon.Exclamation); 
                } 
            } 
            } 
} 
当后台页面显示后,需判断用户是否为管理员角色或具有特定权限的用户(本例中具有特定权限的用户是老师),然后决定是否加载后台账户数据,源程序如下: 
  private void frmMain_Load(object sender, System.EventArgs e) { 
            if ((Thread.CurrentPrincipal.IsInRole("Teacher")) ||  
            (Thread.CurrentPrincipal.IsInRole(@"BuiltIn\Administrators")))  
        { 
            DataSet dsUsers = new DataSet(); 
            dsUsers.ReadXml(@"..\..\users.xml"); 
            dgUsers.CaptionText = "用户账号"; 
            dgUsers.DataSource = dsUsers.Tables[0]; 
        } 
        else  
        { 
            MessageBox.Show("您必须是老师或本地管理员账户 " + 
          "查看后台账户数据", "权限不够!", 
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
        } 
    } 
四、效果图 
编译代码,程序执行效果如图7、8、9所示。当输入已注册用户账号和密码时,系统提示成功登录信息,并判断当前用户为Teacher,加载后台账户信息数据。 
 
  
 
图7 登录界面图 
 
  
 
图8 登录成功提示信息图 
 
  
 
图9 后台数据显示页面图 
  
  
  			
				 |