1 粗粒度的权限控制 (过滤器有前后顺序)
web.xml文件配置
<filter>
<filter-name>PrivilegeFilter</filter-name>
<filter-class>cn.yue.shop.web.filter.PrivilegeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrivilegeFilter</filter-name>
<url-pattern>/control/*</url-pattern>
</filter-mapping>
/**
* Copyright (C) 2015
*
* FileName:PrivilegeFilter.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-6-4
*/
// Package Information
package cn.yue.shop.web.filter;
import org.apache.velocity.app.Velocity;
import cn.yue.shop.web.constant.Constants;
import cn.yue.shop.web.model.Employee;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义权限过滤器 (实现粗粒度的权限拦截)
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-6-4
*
*/
public class PrivilegeFilter implements Filter {
/**
* 初始化方法
*
* @param arg0
* @throws ServletException
*/
@Override
public void init(FilterConfig config) throws ServletException {
// velocity初始化
Properties prop = new Properties();
prop.put("runtime.log", config.getServletContext().getRealPath("/WEB-INF/log/velocity.log"));
prop.put("file.resource.loader.path", config.getServletContext().getRealPath("/WEB-INF/vm"));
prop.put("input.encoding", "UTF-8");
prop.put("output.encoding", "UTF-8");
Velocity.init(prop);
}
/**
* 执行过滤方法
*/
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
Employee employee = (Employee) request.getSession().getAttribute(Constants.EMPLOYEE);
if (null == employee) {// 如果员工没有登录
// 重定向
HttpServletResponse response = (HttpServletResponse) res;
response.sendRedirect("/employee/loginUI.action");
} else {
chain.doFilter(req, res);
}
}
/**
* 执行过滤后释放过滤器前所作操作
*/
@Override
public void destroy() {
}
}
2 修改struts核心拦截器,实现细粒度权限拦载
web.xml文件配置
<filter>
<filter-name>struts2</filter-name>
<filter-class>cn.yue.shop.web.filter.PrivilegePrepareAndExecuteFilter</filter-class>
</filter>
<!-- 让Struts2的核心Filter拦截所有请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/**
* Copyright (C) 2015
*
* FileName:PrivilegePrepareAndExecuteFilter.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-6-4
*/
// Package Information
package cn.yue.shop.web.filter;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionProxyFactory;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.config.Configuration;
import cn.yue.shop.web.controller.Permission;
import cn.yue.shop.web.model.Employee;
import cn.yue.shop.web.model.PrivilegeGroup;
import cn.yue.shop.web.model.SystemPrivilege;
import cn.yue.shop.web.model.SystemPrivilegePk;
import cn.yue.shop.web.utils.ForwardUrl;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 重写struts2核心拦截器的方法,实现权限拦截
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-6-4
*
*/
public class PrivilegePrepareAndExecuteFilter extends StrutsPrepareAndExecuteFilter {
private Dispatcher dispatcher;
private FilterConfig filterConfig;
private HttpServletRequest request;
private HttpServletResponse response;
private ActionMapping mapping;
/** 命名空间 **/
private String namespace;
/** action方法名 **/
private String name;
private String method;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
}
@Override
protected void postInit(Dispatcher dispatcher, FilterConfig filterConfig) {
this.dispatcher = dispatcher;
this.filterConfig = filterConfig;
super.postInit(dispatcher, filterConfig);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
// 取得url请求路径
String uri = request.getRequestURI();
System.out.println(uri);
mapping = prepare.findActionMapping(request, response, true);
if (mapping != null) {
System.out.println("nameSpace is: " + mapping.getNamespace() + " name is : " + mapping.getName());
System.out.println("method is: " + mapping.getMethod());
this.namespace = mapping.getNamespace();
this.method = mapping.getName();
this.name = mapping.getName();
// if (request.getRequestURI().contains("services")) {
if (mapping.getNamespace().startsWith("/services")) {
chain.doFilter(request, response);
return;
}
if (mapping.getNamespace().startsWith("/control/")) {// 只对办公平台中的action进行校验
System.out.println("需要直行权限检查!");
// 如果没有权限则跳转到默认页面!validate(request, mapping.getMethod())
if (!validate()) {
mapping.setNamespace("/control/center");
mapping.setName("msg");
req.setAttribute("message", "您没有执行该操作的权限");
req.setAttribute("urlAddress", ForwardUrl.getForwardURL("control.center.right"));
execute.executeAction(request, response, mapping);
return;
}
}
}
super.doFilter(req, res, chain);
}
/**
* 获取用户当前执行的方法
*
* @return
*/
@SuppressWarnings("unchecked")
private Method getCurrentMethod() {
try {
// 取得方法名
ServletContext context = filterConfig.getServletContext();
Map<String, Object> extraContext = dispatcher.createContextMap(request, response, mapping, context);
Configuration config = dispatcher.getConfigurationManager().getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);
@SuppressWarnings("rawtypes")
Class classzz = proxy.getInvocation().getAction().getClass();
if (!classzz.equals(ActionSupport.class)) {
return classzz.getMethod(method);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null;
}
/**
* 检查用户权限
*
* @param request
* @param method
* @return
*/
private boolean validate() {
// 取得当前用户执行的方法
Method methodz = getCurrentMethod();
// 取得方法的注解,检查用户是否有此权限
if (methodz != null && methodz.isAnnotationPresent(Permission.class)) {
Permission permission = methodz.getAnnotation(Permission.class);// 得到方法上的注解
System.out.println("方法上的注解为: " + permission.module() + " : " + permission.privilege());
// 下面是得到执行方法需要的权限
SystemPrivilege methodPrivilege = new SystemPrivilege(new SystemPrivilegePk(permission.module(), permission.privilege()));
System.out.println("执行方法所需要的权限: " + methodPrivilege.toString());
Employee employee = (Employee) request.getSession().getAttribute("employee");
for (PrivilegeGroup group : employee.getGroups()) {
if (group.getPrivileges().contains(methodPrivilege)) {
return true;
}
}
return false;
}
return true;
}
}
3 自定义注解
/**
* Copyright (C) 2015
*
* FileName:Permission.java
*
* Author:<a href="mailto:[email protected]">Retacn</a>
*
* CreateTime: 2015-6-4
*/
// Package Information
package cn.yue.shop.web.controller;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义权限控制注解
*
* @version
*
* @Description:
*
* @author <a href="mailto:[email protected]">Retacn</a>
*
* @since 2015-6-4
*
*/
// 注解 保留阶段(CLASS编译成class后仍存在 SOURCE编译后不存在 RUNTIME运行时)
@Retention(value = RetentionPolicy.RUNTIME)
// 注解的标注位置(类 方法 属性)
@Target(value = ElementType.METHOD)
public @interface Permission {
/** 模块名 **/
String module();
/** 权限值 **/
String privilege();
}
4 action方法中设置权限,示例代码如下
/**
* 列表显示部门
*
* @return
* @throws Exception
*/
// 配置权限
@Permission(module = "department", privilege = "view")
public String list() throws Exception {
pageView = new PageView<Department>(15, getPage());
// 开始索引
int position = (pageView.getCurrentPage() - 1) * pageView.getMaxResult();
QueryResult<Department> results = departmentService.getScrollData(position,//
pageView.getMaxResult() //
);
pageView.setQueryResult(results);
return SUCCESS;
}
5 数据库保存权限/权限组
6 人员添加权限组