关于权限管理的设计技巧
首先是关于数据库的设计,一个是角色表,一个是权限表,因为一个角色可以对应多个权限,一个权限可以对应多个角色,所以,权限表和角色表示多对多的关系
(权限表的设计技巧,设计的url路径是具体的方法的路径)
权限分配的流程===》
1、首先是先进入登录界面,输入账号密码
2、进行身份验证
/**
* 登录
* @return
*/
public String login() throws Exception {
System.out.println(model.getLoginName());
User user=userService.findByLoginNameAndPassward(model.getLoginName(),model.getPassword());
System.out.println(user);
if(user==null)
{
//显示错误信息,然后返回loginUI
addFieldError("login", "用户名和密码不正确");
return "loginUI";
}else{
//登录成功添加一个session、
ActionContext.getContext().getSession().put("user", user);
return "toindex";
}
}
/**
* 验证登录名和密码的方法
* @param name
* @param password
* @return
*/
public User findByLoginNameAndPassward(String name, String password) {
// TODO Auto-generated method stub
return (User) getSession().createQuery(//
"FROM User u WHERE u.loginName=? AND u.password=? ")//
.setParameter(0, name)//
.setParameter(1, password)//
.uniqueResult();
}
//用hql查询的结果是一个Collection的集合结果
3、登录成功之后保存当前的session
//登录成功添加一个session、
ActionContext.getContext().getSession().put("user", user);
、、、
4、登录成功之后进入index。jsp
然后重定向到action
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<% response.sendRedirect(request.getContextPath()+"/home_index.action"); String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>
4.获取所有权限的列表(展示的是顶级的列表)
//准备数据
List<Privilege> privilegeTopList=privilegeService.findTopList();
ActionContext.getContext().put("privilegeTopList",privilegeTopList);
System.out.println("------------->已经准备数据<-----------------");
return "left";
<%-- 显示一级菜单 --%>
<s:iterator value="#privilegeTopList">
<!-- 判断当前的用户是否有权限,有的话才显示相应的功能
#session.user是可以直接在Map里面获取当前的session
#session.user.roles----》role.privilege
ognl表达式里面可以实现方法-->
<s:if test="#session.user.hasPrivilegeByName(name)">
<div onClick="menuClick(this);" class="level1Style">
<img src="style/images/MenuIcon/${id}.gif" class="Icon" />
${name}
</div>
<ul style="" class="MenuLevel2" id="aa">
<%-- 显示二级菜单 --%>
<s:iterator value="children">
<s:if test="#session.user.hasPrivilegeByName(name)">
<li class="level2">
<div class="level2Style">
<img src="style/images/MenuIcon/menu_arrow_single.gif" />
<a target="right" href="${pageContext.request.contextPath}${url}.action"> ${name}</a>
</div>
</li>
</s:if>
</s:iterator>
</ul>
</li>
</s:if>
</s:iterator>
在Javabean中要添加相关的方法(对迭代的权限一个一个对比)
User.java
public boolean hasPrivilegeByName(String name)
{
//超级管理员拥有所有的权限
if(isAdmin())
{
return true;
}
//普通用户判断是否有这一个权限
for(Role role:roles)
{
for(Privilege privilege:role.getPrivilege())
{
if(privilege.getName().equals(name))
{
return true;
}
}
}
return false;
}
//得到当前的登录名,判断是否问超级管理员
public boolean isAdmin()
{
return "admin".equals(loginName);
}
=========================================
自定义拦截器,对没有登录的用户不允许访问(直接过滤)
//自定义拦截器(implements Interceptor 实现拦截器接口)
public class CheckPrivilegeIntercetor implements Interceptor {
public void destroy() {
}
public void init() {
}
public String intercept(ActionInvocation invocation) throws Exception {
// System.out.println(“———> 之前”);
// String result = invocation.invoke(); // 放行
// System.out.println(“———> 之后”);
// return result;
// 从session里面获取用户信息
User user = (User) ActionContext.getContext().getSession().get("user"); // 当前登录用户
//得到根目录
String namespace = invocation.getProxy().getNamespace();
String actionName = invocation.getProxy().getActionName();
String privUrl = namespace + actionName; // 对应的权限URL
System.out.println("==========================================");
System.out.println(privUrl);
// 在网址输入路径,如果未登录
if (user == null) {
if (privUrl.startsWith("/user_login")) {
// "/user_loginUI"
// 如果是去登录,就放行
return invocation.invoke();
} else {
// 如果不是去登录,就转到登录页面
return "loginUI";
}
}
// 如果已登录,就判断权限
else {
if (user.hasPrivilegeByUrl(privUrl)) {
// 如果有权限,就放行
return invocation.invoke();
} else {
// 如果没有权限,就转到提示页面
return "noPrivilegeError";
}
}
}
}
/**
* 判断本用户是否有指定URL的权限
*
* @param privUrl
* @return
*/
public boolean hasPrivilegeByUrl(String privUrl) {
// 超级管理有所有的权限
if (isAdmin()) {
return true;
}
// >> 去掉后面的参数
int pos = privUrl.indexOf("?");
if (pos > -1) {
//截取子字符串
privUrl = privUrl.substring(0, pos);
}
// >> 去掉UI后缀
if (privUrl.endsWith("UI")) {
privUrl = privUrl.substring(0, privUrl.length() - 2);
}
//先找出所有不重复的权限,看看这些权限是否在集合里面
// 如果本URL不需要控制,则登录用户就可以使用
Collection<String> allPrivilegeUrls = (Collection<String>) ActionContext.getContext().getApplication().get("allPrivilegeUrls");
(判断集合中是否包含该字符串)
if (!allPrivilegeUrls.contains(privUrl)) {
return true;
} else {
// 普通用户要判断是否含有这个权限
for (Role role : roles) {
for (Privilege priv : role.getPrivilege()) {
if (privUrl.equals(priv.getUrl())) {
return true;
}
}
}
return false;
}
}
======================================
在web.xml中配置拦截器
<interceptors>
<!-- 声明拦截器 -->
<interceptor name="checkPrivilege" class="com.itcast.oa.util.CheckPrivilegeIntercetor"></interceptor>
<!-- 重新定义默认的拦截器栈(把自定义的拦截器放在默认拦截器的最外面) -->
<interceptor-stack name="defaultStack">
<interceptor-ref name="checkPrivilege"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>