一. 需求
手写MVC框架基础上增加如下功能
1)定义注解@Security(有value属性,接收String数组),该注解用于添加在Controller类或者Handler方法上,表明哪些用户拥有访问该Handler方法的权限(注解配置用户名)
2)访问Handler时,用户名直接以参数名username紧跟在请求的url后面即可,比如http://localhost:8080/demo/handle01?username=zhangsan
3)程序要进行验证,有访问权限则放行,没有访问权限在页面上输出
二. 程序功能设计
(一) 定义注解@Security进行用户访问Handler权限鉴别,鉴别方式,拥有权限的用户名配置在注解中,用户访问时通过GET方式携带用户名,该用户名与注解中的用户名进行比对,相同则放行,不相同则禁止访问,并在页面输出禁止访问信息。
(二) 权限鉴别的注解注解@Security,可以放到某个Controller类上,也可以放到某个Handler方法上,也可以哪里都不放。具体鉴权规则如下:
1、如果某个Controller类上放了@Security,该Controller类的某个Handler方法上没放,则根据Controller类上的@Security配置的用户名鉴别哪些用户可以访问。
2、如果某个Handler方法上放了@Security,该Handler方法所从属的Controller类没放,则根据Handler方法上的@Security配置的用户名鉴别哪些用户可以访问。
3、如果某个Controller类与其内的某个Handler方法上都放了@Security,则分别识别这两个@Security注解内是否都配置了要访问的用户名,只有两个@Security都配置了要访问的用户名才放行。
4、如果某个Controller类与其内的某个Handler方法上都没有放@Security注解,则表示任何用户都可以访问,无权限限制。
(三)有权限的用户名可自行配置在注解属性中,也可以使用注解属性的默认值。
(四)用户访问某个URL时,如有权限则放行,无权限则无法访问到对应的Handler,并在页面显示禁止访问的提示。
三.程序设计思路
(一) 思路分析
-
一个URL唯一对应一个Controller 以及一个Handler
-
权限鉴别的@Security注解只存在于Controller与Handler上
-
在初始化阶段,在IOC容器初始化结束时统一记录URL与对应的Controller 、Handler上的@Security注解值及相互映射关系
-
每个URL及对应的@Security注解值以及与对应的Controller 、Handler映射关系封装成一个对象,并将该对象塞进一个集合中
-
在访问某条URL时,从URL携带的访问地址及用户名在初始化的集合中进行遍历比对,符合规则的放行。
(二)具体流程设计
-
准备阶段
(1)创建@Security注解类
(2)创建类型为:UserSecurity的pojo,用来封装初始化时的URL、类上的注解权限配置用户名、方法上的注解权限配置用户名。使这三个属性封装在同一个UserSecurity中形成映射关系。
-
初始化阶段
(1)在IOC容器初始化结束后,在initHandlerMapping()处理器映射器中初始化权限及对应的URL的封装,并将每一个封装好的对象存入MAP集合中。
-
等待访问阶段
(1)在访问阶段,在doPost方法里获取访问的URL及要访问的用户名
(2)用request里获取的url 与 初始化时的MAP集合进行比对,找到符合的某个封装对象,再用request里携带的用户名与封装对象中的类上注解用户名与方法上注解用户名进行分别比对。通过权限鉴别规则返回比对结果,是否放行。
(三)程序测试
-
第一种类型测试连接:
说明:Controller类上绑定了权限,handle01 、handle012上绑定了权限,handle03上未绑定权限。所有权限的配置采取的注解默认值{admin,pc}
http://localhost:8080/demo/handle01 (能访问的用户:admin , pc)
http://localhost:8080/demo/handle02 (能访问的用户:admin , pc)
http://localhost:8080/demo/handle03 (能访问的用户:admin , pc)
-
第二种类型测试连接:
说明:Controller类上绑定了权限,handle01 、handle012、handle03上都绑定了权限,所有权限的配置如下:
Controller类上配置了能访问的用户为:({"zhangsan","lisi"})
handle01上配置了能访问的用户为:({"wangwu","zhaoliu"})
handle012上配置了能访问的用户为:({"lvbu","diaochan"})
handle013上配置了能访问的用户为:({"zhangsan","diaochan"})
http://localhost:8080/other/handle01 (能访问的用户:无)
http://localhost:8080/other/handle02 (能访问的用户:无)
http://localhost:8080/other/handle03 (能访问的用户:zhangsan)
-
第三种类型测试连接:
说明:Controller类上未绑定权限注解,handle02 、handle013上绑定了权限,handle01上未绑定权限。所有权限的配置如下:
handle012上配置了能访问的用户为:({"lvbu","diaochan"})
handle013上配置了能访问的用户为:({"zhangsan","diaochan"})
http://localhost:8080/three/handle01 (能访问的用户:所有用户)
http://localhost:8080/three/handle02 (能访问的用户:lvbu , diaochan )
http://localhost:8080/three/handle03 (能访问的用户:zhangsan , diaochan)