基于Struts2、Annotation的细粒度权限管理

 

本文的目的是实现方法级的细粒度权限管理,通过Struts2 拦截器和Java的Annotation实现,具体实现方法如下:

1.数据表设计,并将实体Bean映射到数据库,本系统设计了权限组和具体权限表,由于两个表之间属于多对多关联,所以另有一个主键关联表。

权限组对应的实体Bean如下:

 

@Entity
public class PrivilegeGroup {
	private String groupid;
	private String name;
	private Set<SystemPrivilege> privileges = new HashSet<SystemPrivilege>();
	private Set<Employee> employees = new HashSet<Employee>();
	
	public PrivilegeGroup(){}
	
	public PrivilegeGroup(String groupid) {
		this.groupid = groupid;
	}
	@ManyToMany(mappedBy="groups", cascade=CascadeType.REFRESH)
	public Set<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}
	@Id @Column(length=36)
	public String getGroupid() {
		return groupid;
	}
	public void setGroupid(String groupid) {
		this.groupid = groupid;
	}
	@Column(length=20,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@ManyToMany(cascade=CascadeType.REFRESH,fetch=FetchType.EAGER)
	@JoinTable(name="ps", inverseJoinColumns={@JoinColumn(name="module", referencedColumnName="module"),
											  @JoinColumn(name="privilege", referencedColumnName="privilege")}
						 ,joinColumns=@JoinColumn(name="group_id"))
	public Set<SystemPrivilege> getPrivileges() {
		return privileges;
	}
	public void setPrivileges(Set<SystemPrivilege> privileges) {
		this.privileges = privileges;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((groupid == null) ? 0 : groupid.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final PrivilegeGroup other = (PrivilegeGroup) obj;
		if (groupid == null) {
			if (other.groupid != null)
				return false;
		} else if (!groupid.equals(other.groupid))
			return false;
		return true;
	}
}


具体权限实体Bean如下:

@Entity
public class SystemPrivilege {
	private SystemPrivilegePK id;
	/* 权限名称 */
	private String name;
	private Set<PrivilegeGroup> groups = new HashSet<PrivilegeGroup>();
	
	@ManyToMany(cascade=CascadeType.REFRESH, mappedBy="privileges")
	public Set<PrivilegeGroup> getGroups() {
		return groups;
	}
	public void setGroups(Set<PrivilegeGroup> groups) {
		this.groups = groups;
	}

	public SystemPrivilege(){}
	
	public SystemPrivilege(String module, String privilege, String name) {
		this.id = new SystemPrivilegePK(module, privilege);
		this.name = name;
	}
	
	public SystemPrivilege(SystemPrivilegePK id) {
		this.id = id;
	}
	
	@EmbeddedId
	public SystemPrivilegePK getId() {
		return id;
	}
	public void setId(SystemPrivilegePK id) {
		this.id = id;
	}
	@Column(length=20,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final SystemPrivilege other = (SystemPrivilege) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
}


主键关联实体Bean如下:

@Embeddable
public class SystemPrivilegePK implements Serializable{
	private static final long serialVersionUID = -5226216765297631665L;
	/* 模块名 */
	private String module;
	/* 权限值 */
	private String privilege;
	
	public SystemPrivilegePK(){}
	
	public SystemPrivilegePK(String module, String privilege) {
		this.module = module;
		this.privilege = privilege;
	}
	@Column(length=20, name="module")
	public String getModule() {
		return module;
	}
	public void setModule(String module) {
		this.module = module;
	}
	@Column(length=20, name="privilege")
	public String getPrivilege() {
		return privilege;
	}
	public void setPrivilege(String privilege) {
		this.privilege = privilege;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((module == null) ? 0 : module.hashCode());
		result = prime * result
				+ ((privilege == null) ? 0 : privilege.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final SystemPrivilegePK other = (SystemPrivilegePK) obj;
		if (module == null) {
			if (other.module != null)
				return false;
		} else if (!module.equals(other.module))
			return false;
		if (privilege == null) {
			if (other.privilege != null)
				return false;
		} else if (!privilege.equals(other.privilege))
			return false;
		return true;
	}
}


Employee实体Bean如下:

@Entity
public class Employee {
	/* 主键,20位*/
	private String username;
	/* 20位, 不能为null */
	private String password;
	/* 姓名 10位 不能为null */
	private String realname;
	/* 性别 不能为null */
	private Gender gender;
	/* 学历 10位 */
	private String degree;
	/* 身份证 必须提供 */
	private IDCard idCard;
	/* 毕业院校 20位 */
	private String school;
	/* 联系电话 20 */
	private String phone;
	/* 电子邮件 50 */
	private String email;
	/* 照片 41 */
	private String imageName;
	/* 员工在职状态 true为在职,false为离职 */
	private Boolean visible = true;
	private Department department;
	/* 拥有的权限 */
	private Set<PrivilegeGroup> groups = new HashSet<PrivilegeGroup>();
	
	@ManyToMany(cascade=CascadeType.REFRESH,fetch=FetchType.EAGER)
	@JoinTable(name="employee_role",joinColumns=@JoinColumn(name="username"),
			inverseJoinColumns=@JoinColumn(name="groupid"))
	public Set<PrivilegeGroup> getGroups() {
		return groups;
	}

	public void setGroups(Set<PrivilegeGroup> groups) {
		this.groups = groups;
	}
	/**
	 * 添加权限组
	 * @param group
	 */
	public void addPrivilegeGroup(PrivilegeGroup group){
		this.groups.add(group);
	}
	
	public Employee(){}
	
	public Employee(String username) {
		this.username = username;
	}

	@Transient
	public String getImagePath(){
		if(username != null && imageName != null) 
			return "/images/employee/" + username+"/" + imageName;
		return null;
	}
	
	@Id @Column(length=20)
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}
	@Column(length=20,nullable=false)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	@Column(length=10,nullable=false)
	public String getRealname() {
		return realname;
	}

	public void setRealname(String realname) {
		this.realname = realname;
	}
	@Enumerated(EnumType.STRING) @Column(length=5,nullable=false)
	public Gender getGender() {
		return gender;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}
	@Column(length=10)
	public String getDegree() {
		return degree;
	}

	public void setDegree(String degree) {
		this.degree = degree;
	}
	@OneToOne(cascade=CascadeType.ALL,optional=false)
	@JoinColumn(name="card_id")
	public IDCard getIdCard() {
		return idCard;
	}

	public void setIdCard(IDCard idCard) {
		this.idCard = idCard;
	}
	@Column(length=20)
	public String getSchool() {
		return school;
	}

	public void setSchool(String school) {
		this.school = school;
	}
	@Column(length=20)
	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
	@Column(length=50)
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	@Column(length=41)
	public String getImageName() {
		return imageName;
	}

	public void setImageName(String imageName) {
		this.imageName = imageName;
	}
	@Column(nullable=false)
	public Boolean getVisible() {
		return visible;
	}

	public void setVisible(Boolean visible) {
		this.visible = visible;
	}

	@ManyToOne(cascade=CascadeType.REFRESH)
	@JoinColumn(name="department_id")
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((username == null) ? 0 : username.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Employee other = (Employee) obj;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
}


2.管理员在系统后台管理系统中某个Employee设定所属权限组,该Employee就拥有了该权限组所定义的所以权限。

实现方法级的权限拦截,需要自定义Annotation,本系统中定义了一个Permission注解,具体如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Permission {
	/* 模块名 */
	String module();
	/* 权限值 */
	String privilege();
}


3.定义权限注解后,即可将其添加到Action的对应方法上:

@Permission(module="privilegeGroup", privilege="delete")
	public String delete(){
		groupService.delete((Serializable)groupDTO.getGroupid());
		request.setAttribute("message", "删除权限组成功");
		request.setAttribute("urladdress", SiteUrl.readUrl("control.privilegegroup.list"));
		return "message";
	}


4.然后需要自定义拦截器,对Action进行拦截,在拦截器中对用户是否有权限执行Action的对应方法进行判断:

public class PermissionInterceptor extends AbstractInterceptor {
	private static final long serialVersionUID = -1424613722721479288L;
	
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		HttpServletRequest request = (HttpServletRequest)invocation.getInvocationContext().get(StrutsStatics.HTTP_REQUEST);
		Employee employee = WebUtil.getEmployee(request);
		if(employee != null && validate(employee,invocation)){
			return invocation.invoke();
		}
		request.setAttribute("message", "你没有权限执行该操作");
		request.setAttribute("urladdress", SiteUrl.readUrl("control.center.right"));
		
		return "message";
	}
	public boolean validate(Employee employee,ActionInvocation invocation){
		String methodName = "execute";
		Method currentMethod = null;
		methodName = invocation.getProxy().getMethod();
		try{
			currentMethod = invocation.getProxy().getAction().getClass().getMethod(methodName, new Class[]{});
		}catch(Exception e){
			e.printStackTrace();
		}
		if(currentMethod != null && currentMethod.isAnnotationPresent(Permission.class)){
			Permission permission = currentMethod.getAnnotation(Permission.class);
			SystemPrivilege privilege = new SystemPrivilege(new SystemPrivilegePK(permission.module(),
					permission.privilege()));
			for(PrivilegeGroup group : employee.getGroups()){
				if(group.getPrivileges().contains(privilege))
					return true;
			}
			return false;
		}
		return true;
	}

}


5.在struts2配置文件中注册权限拦截器,并使用其对Action进行拦截:

<interceptors>
			<interceptor name="permissionInterceptor" class="com.hnust.web.interceptor.PermissionInterceptor"/>
			<interceptor-stack name="myInterceptor">
				<interceptor-ref name="permissionInterceptor"></interceptor-ref>
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>


 

<package name="privilegegroup" namespace="/control/privilegegroup" extends="default">
		<default-interceptor-ref name="myInterceptor"></default-interceptor-ref>
		<action name="list" class="com.hnust.web.action.privilege.PrivilegeGroupListAction">
			<result name="list">/WEB-INF/page/department/privilegegrouplist.jsp</result>
		</action>
		<action name="manage" class="com.hnust.web.action.privilege.PrivilegeGroupManageAction">
			<result name="add">/WEB-INF/page/department/addprivilegegroup.jsp</result>
			<result name="edit">/WEB-INF/page/department/editprivilegegroup.jsp</result>
		</action>
	</package>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值