思路是加一个拦截器,对除登录接口的所有请求进行拦截。拦截到请求后,查询当前用户都拥有哪些url的权限(这个需要权限表有url字段),然后与当前请求的url对比,如果相同则说明有权限,否则没有。
首先配置拦截器
1、创建拦截器类,及重要参数:
public class PermissionInterceptor implements HandlerInterceptor {
private List<String> excludeUrls;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
public List<String> getExcludeUrls() {
return excludeUrls;
}
public void setExcludeUrls(List<String> excludeUrls) {
this.excludeUrls = excludeUrls;
}
}
2、打开spring-mvc.xml
文件,在里面加上拦截器配置:
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.xxx.interceptor.PermissionInterceptor">
<property name="excludeUrls">
<list>
<value>loginController.do?login</value>
<value>loginController.do?logout</value>
</list>
</property>
</bean>
</mvc:interceptor>
然后开始写代码
主要逻辑代码如下:
public class PermissionInterceptor implements HandlerInterceptor {
@Autowired
private SystemService systemService;
@Resource
private ClientManager clientManager;
private List<String> excludeUrls;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//通过转换,获取用户的请求URL地址
String requestPath = ResourceUtil.getAuthRequsetPath(request);
//针对拦截器排除URLS,进行排除
if (excludeUrls.contains(requestPath)) {
return true;
}
Client client = clientManager.getClient(ContextHolderUtils.getSession().getId());
TSUser currLoginUser = client != null ? client.getUser() : null;
if (currLoginUser != null ) {
String loginUserName = currLoginUser.getUserName();
String loginUserId = currLoginUser.getId();
// 如果是管理员,则无需校验权限
if("admin".equals(loginUserName)){
return true;
}
// 取请求url问号前的部分
String requestPathPrefix = StringUtils.split(requestPath, '?')[0];
if (systemService.loginUserIsHasUrlAuth(requestPathPrefix, loginUserId)) {
return true;
}
forwardTimeOut(request, response);
return false;
} else {
forwardTimeOut(request, response);
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
/**
* 跳转: 登录超时页面
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
private void forwardTimeOut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect(request.getSession().getServletContext().getContextPath()+"/webpage/login/timeout.jsp");
}
public List<String> getExcludeUrls() {
return excludeUrls;
}
public void setExcludeUrls(List<String> excludeUrls) {
this.excludeUrls = excludeUrls;
}
}
获取requestPath方法代码:
public static String getAuthRequsetPath(HttpServletRequest request) {
String queryString = request.getQueryString();
String requestPath = request.getRequestURI();
if (StringUtils.isNotEmpty(queryString)) {
requestPath += "?" + queryString;
}
if (requestPath.indexOf("&") > -1) {/
requestPath = requestPath.substring(0, requestPath.indexOf("&"));
}
if (requestPath.indexOf("=") != -1) {
if (requestPath.indexOf(".do") != -1) {
requestPath = requestPath.substring(0, requestPath.indexOf(".do") + 3);
}
else {
requestPath = requestPath.substring(0, requestPath.indexOf("?"));
}
}
requestPath = requestPath.substring(request.getContextPath().length() + 1);
return requestPath;
}
loginUserIsHasUrlAuth()方法代码:
public boolean loginUserIsHasUrlAuth(String requestPathPrefix, String userid) {
String functionurlLike = requestPathPrefix + "%";
String sql = "SELECT count(*) FROM t_function f, t_role_function rf,t_role_user ru " +
" WHERE f.id=rf.functionId AND rf.roleId=ru.roleId AND " +
"ru.userId=? AND f.functionUrl like ?";
Long authSize = this.getCountForJdbcParam(sql, userid, functionurlLike);
return authSize > 0;
}
这样就可以了。