|
2#
楼主 |
发表于 2018-4-26 17:07:10
|
只看该作者
(3)认证与会话管理:
认证实际上就是一个验证凭证的过程,因此我们对登录密码有着严格的规定:密码要求长度在8位以上并
且包含字母,数字,符号两种以上的组合。并将密码加密后再进行数据库的存储。为防止一些暴力破解手段,
又出于用户体验的考虑,本系统采用用户登录时默认不进行验证码的输入,但密码三次输入失败后需要进行验
证码的输入,连续五次输入错误后,该用户的ip地址将被封,可以在一段时间后自动解封或者后台管理员手动
解封。涉及到系统资金有关的操作,例如投标,我们还需要用户设置并提供支付密码,而提现等操作我们还配
备短信验证码功能。以此来增强验证的可靠性。
当用户登录完成后,在服务器端会创建一个新的会话(Session),会话中保存着用户的状态和相关信息,
服务器端维护所有在线用户的Session,而浏览器则是将SessionId加密后保存在cookie中,这里就出现了前面提
到了“cookie劫持“问题,本系统通过将cookie中植入HttpOnly成功解决该问题。本系统还给Session设置了一个
有效时间,来保证在有效时间后Session将自动销毁,以防止Session长连接所带来的安全隐患。在web.xml文件
中添加以下代码:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
(4)访问控制:
访问控制实际上就是建立用户和权限之间的对应关系,本系统采用的是“基于角色的访问控制”,根据相应功能
模块的划分相应的权限,并将相应的权限分配给不同的角色,再将角色分配给用户,用户就拥有了该角色所持
有的权限。具体的设计与实现分析请见1.2 Annotation和Struts2拦截器实现基于角色的垂直权限管理。
1.2 Annotation和Struts2拦截器实现基于角色的垂直权限管理
1.2.1 模块的设计
以下是本系统的垂直权限管理模块的物理模型设计:
图1-2 权限管理模块物理模型
管理员与角色之间是多对多的关系,这样可以实现为一个管理员分配多个角色进行管理,而角色与权限之间也
是多对多的关系,权限是根据功能模块进行划分的,使得角色可以进行细粒度的权限分配。
4.3.2 模块的代码实现
首先声明一个注解类,该注解类是自定义的,根据我们需要的实现的功能进行相应注解的定义,使得在之后需要
注释的方法上使用相应注解,代码如下:
复制代码
- @Retention(RetentionPolicy.RUNTIME) //注解的存活时间,整个运行时都存活
- @Target(ElementType.METHOD) //此注解表示只能在方法上面有效
- public @interface Permission {
- /** 模块名 **/
- String model();
- /** 权限值 **/
- String privilegeValue();
- /*用于区分当前页面是dialog还是navTab*/
- String targetType();
- }
- 然后定义相应的拦截器类,并在struts2的配置文件struts.xml中进行拦截器的配置,为相应需要的类进行拦截验证,定义拦截器部分的核心代码如下:
- /**
- * 校验控制在方法上的拦截
- */
- @SuppressWarnings("unchecked")
- public boolean validate(Admin admin, ActionInvocation invocation, List<Role> roleList,
- Map session) {
- String methodName= "execute"; //定义默认的访问方法
- Method currentMethod = null;
- methodName = invocation.getProxy().getMethod(); //通过actionProxy,得到当前正在执行的方法名
- try {
- //利用反射,通过方法名称得到具体的方法
- currentMethod = invocation.getProxy().getAction().getClass().getMethod(methodName, new Class[] {});
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (currentMethod != null && currentMethod.isAnnotationPresent(Permission.class)) {
- //得到方法上的Permission注解
- Permission permission = currentMethod.getAnnotation(Permission.class);
- //通过Permission注解构造出系统权限
- Systemprivilege privilege = new Systemprivilege(new SystemprivilegeId(permission.privilegeValue(), permission.model()));
- session.put("targetType", permission.targetType());
- //迭代用户所具有的具体权限,如果包含,返回true
- for (Role role : roleList) {
- RolePrivilege rolePrivilege = new RolePrivilege(privilege, role);
- if (role.getRolePrivileges().contains(rolePrivilege)) {
- return true;
- }
- }
- return false;
- }
- return true;
- }
复制代码
复制代码
本系统需要向权限表中添加相应的功能模块,为了有一个比较细的粒度,模块将根据功能进行划分,而权限则根
据按钮来进行细分:
图1-3 数据库截图
在定义了相应的权限后,我们需要在相应的执行方法体上面进行注释,使得拦截器进行拦截验证时能根据注释获
取该执行方法体的模块和权限类型:
@Permission(model="recharge", privilegeValue="recharge" ,targetType="dialog")
4.3.3 模块的实现效果
首先添加相应的员工:
然后新增相应的角色,填写角色名称并勾取相应的权限:
然后新增相应的用户,勾选该用户相应的角色,可以选择多个角色,并且选择相应用户对应的员工:
|
|