分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

ASP.NET MVC Form验证

发布时间:2023-09-06 01:18责任编辑:沈小雨关键词:.NETMVC

一、前言

  关于表单验证,园子里已经有不少的文章,相信Web开发人员也都基本写过,最近在一个个人项目中刚好用到,在这里与大家分享一下。本来想从用户注册开始写起,但发现东西比较多,涉及到界面、前端验证、前端加密、后台解密、用户密码Hash、权限验证等等,文章写起来可能会很长,所以这里主要介绍的是登录验证和权限控制部分,有兴趣的朋友欢迎一起交流。

  一般验证方式有Windows验证和表单验证,web项目用得更多的是表单验证。原理很简单,简单地说就是利用浏览器的cookie,将验证令牌存储在客户端浏览器上,cookie每次会随请求发送到服务器,服务器验证这个令牌。通常一个系统的用户会分为多种角色:匿名用户、普通用户和管理员;这里面又可以再细分,例如用户可以是普通用户或Vip用户,管理员可以是普通管理员或超级管理员等。在项目中,我们有的页面可能只允许管理员查看,有的只允许登录用户查看,这就是角色区分(Roles);某些特别情况下,有些页面可能只允许叫“张三”名字的人查看,这就是用户区分(Users)。

  我们先看一下最后要实现的效果:

  1.这是在Action级别的控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
publicclassHome1Controller : Controller
{
//匿名访问
publicActionResult Index()
{
returnView();
}
//登录用户访问
[RequestAuthorize]
publicActionResult Index2()
{
returnView();
}
//登录用户,张三才能访问
[RequestAuthorize(Users="张三")]
publicActionResult Index3()
{
returnView();
}
//管理员访问
[RequestAuthorize(Roles="Admin")]
publicActionResult Index4()
{
returnView();
}
}

  2.这是在Controller级别的控制。当然,如果某个Action需要匿名访问,也是允许的,因为控制级别上,Action优先级大于Controller。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Controller级别的权限控制
[RequestAuthorize(User="张三")]
publicclassHome2Controller : Controller
{
//登录用户访问
publicActionResult Index()
{
returnView();
}
//允许匿名访问
[AllowAnonymous]
publicActionResult Index2()
{
returnView();
}
}

  3.Area级别的控制。有时候我们会把一些模块做成分区,当然这里也可以在Area的Controller和Action进行标记。

  从上面可以看到,我们需要在各个地方进行标记权限,如果把Roles和Users硬写在程序中,不是很好的做法。我希望能更简单一点,在配置文件进行说明。例如如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xmlversion="1.0" encoding="utf-8" ?>
<!--
1.这里可以把权限控制转移到配置文件,这样就不用在程序中写roles和users了
2.如果程序也写了,那么将覆盖配置文件的。
3.action级别的优先级 > controller级别 > Area级别
-->
<root>
<!--area级别-->
<areaname="Admin">
<roles>Admin</roles>
</area>
<!--controller级别-->
<controllername="Home2">
<user>张三</user>
</controller>
<!--action级别-->
<controllername="Home1">
<actionname="Inde3">
<users>张三</users>
</action>
<actionname="Index4">
<roles>Admin</roles>
</action>
</controller>
</root>

  写在配置文件里,是为了方便管理,如果程序里也写了,将覆盖配置文件的。ok,下面进入正题。

二、主要接口

  先看两个主要用到的接口。

  IPrincipal定义了用户对象的基本功能,接口定义如下:

1
2
3
4
5
6
7
publicinterfaceIPrincipal
{
//标识对象
IIdentity Identity {get; }
//判断当前角色是否属于指定的角色
boolIsInRole(stringrole);
}

  它有两个主要成员,IsInRole用于判断当前对象是否属于指定角色的,IIdentity定义了标识对象信息。HttpContext的User属性就是IPrincipal类型的。

  IIdentity定义了标识对象的基本功能,接口定义如下:

1
2
3
4
5
6
7
8
9
publicinterfaceIIdentity
{
//身份验证类型
stringAuthenticationType {get; }
//是否验证通过
boolIsAuthenticated {get; }
//用户名
stringName {get; }
}

  IIdentity包含了一些用户信息,但有时候我们需要存储更多信息,例如用户ID、用户角色等,这些信息会被序列到cookie中加密保存,验证通过时可以解码再反序列化获得,状态得以保存。例如定义一个UserData。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
publicclassUserData : IUserData
{
publiclongUserID {get;set; }
publicstringUserName {get;set; }
publicstringUserRole {get;set; }
publicboolIsInRole(stringrole)
{
if(string.IsNullOrEmpty(role))
{
returntrue;
}
returnrole.Split(‘,‘).Any(item => item.Equals(this.UserRole, StringComparison.OrdinalIgnoreCase));
}
publicboolIsInUser(stringuser)
{
if(string.IsNullOrEmpty(user))
{
returntrue;
}
returnuser.Split(‘,‘).Any(item => item.Equals(this.UserName, StringComparison.OrdinalIgnoreCase));
}
}

  UserData实现了IUserData接口,该接口定义了两个方法:IsInRole和IsInUser,分别用于判断当前用户角色和用户名是否符合要求。该接口定义如下:

1
2
3
4
5
publicinterfaceIUserData
{
boolIsInRole(stringrole);
boolIsInUser(stringuser);
}

  接下来定义一个Principal实现IPrincipal接口,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
publicclassPrincipal : IPrincipal
{
publicIIdentity Identity{get;privateset;}
publicIUserData UserData{get;set;}
我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved