三、程序代码
由于在验证用户账号是否为已注册此账号时需要把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 后台数据显示页面图
|