0 前言
上一篇博客中说了ckeditor与ckfinder整合之后进行图文混排的时候通过浏览服务器按钮可以浏览服务器上的所有资源,文件,图片,该用户上传的,非该用户上传的,不仅可以查看,还可以删除、重命名等。所以不是很安全。


所以本文的第一个就是介绍如何不让用户访问http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html页面。
不让用户访问上面的页面,可以有很多种方法,可以参考之前的Shiro进行拦截,然而本文今天介绍使用SpringMVC的拦截器对其进行拦截。
1 通过拦截器阻止直接访问
1.1 定义拦截器
实现HandlerInterceptor接口
package com.gwc.cktest.intercepter; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class CkfinderInterceepter implements HandlerInterceptor {
private static final Log logger = LogFactory.getLog(CkfinderInterceepter.class); @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { logger.info("==========走到了 afterCompletion() 方法"); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView model) throws Exception { logger.info("==========走到了 postHandle() 方法"); } // 返回值,表示我们是否需要将当前的请求拦截下来 // 如果返回false,请求将被终止,如果为true,请求将被放行 // Object arg2 表示的是被拦截的请求的目标对象 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { logger.info("==========走到了 preHandle() 方法"+"=========="); logger.info("==========进行拦截=========="); return false; } }
1.2 配置拦截器和拦截规则
在SpringMVC的配置文件中进行拦截器的配置和拦截规则的设定
<mvc:interceptors> <mvc:interceptor>
<mvc:mapping path="//ckfinder.html" />
<bean class="com.gwc.cktest.intercepter.CkfinderInterceepter">
bean>
mvc:interceptor>
mvc:interceptors>
1.3 效果
没有配置拦截器

配置拦截器之后

2 细粒度的权限控制

先来配置资源访问的访问控制(ACL),这部分在ckfinder.xml中进行配置。
2.1 配置ckfinder.xml
<userRoleSessionVar>CKFinder_UserRole
userRoleSessionVar> <accessControls> <accessControl> <role>*
role> <resourceType>Images
resourceType> <folder>/Logos
folder> <folderView>true
folderView> <folderCreate>true
folderCreate> <folderRename>true
folderRename> <folderDelete>true
folderDelete> <fileView>true
fileView> <fileUpload>false
fileUpload> <fileRename>false
fileRename> <fileDelete>false
fileDelete>
accessControl>
accessControls>
2.1.1 权限配置
现在我们配置两种权限,一个是admin,权限最大,什么权限都有,另一个是user权限,他只能查看根目录下的Images资源,而且对文件夹有只读操作和创建操作,对文件具有查看和上传操作。
<userRoleSessionVar>CKFinder_UserRole
userRoleSessionVar> <accessControls> <accessControl> <role>admin
role> <resourceType>*
resourceType> <folder>/
folder> <folderView>true
folderView> <folderCreate>true
folderCreate> <folderRename>true
folderRename> <folderDelete>true
folderDelete> <fileView>true
fileView> <fileUpload>true
fileUpload> <fileRename>true
fileRename> <fileDelete>true
fileDelete>
accessControl> <accessControl> <role>user
role> <resourceType>Images
resourceType> <folder>/
folder> <folderView>true
folderView> <folderCreate>true
folderCreate> <folderRename>false
folderRename> <folderDelete>false
folderDelete> <fileView>true
fileView> <fileUpload>true
fileUpload> <fileRename>false
fileRename> <fileDelete>false
fileDelete>
accessControl>
accessControls>
2.2 拦截器实现
将上面的拦截器进行修改,只改preHandle方法,如果session中有CKFinder_UserRole则放行,否则拦截请求。
// 返回值,表示我们是否需要将当前的请求拦截下来 // 如果返回false,请求将被终止,如果为true,请求将被放行 // Object arg2 表示的是被拦截的请求的目标对象 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { logger.info("==========走到了 preHandle() 方法"+"=========="); HttpSession session = request.getSession(); String user = (String) session.getAttribute("CKFinder_UserRole"); if (StringUtils.isNotEmpty(user)) { logger.info("==========session中的CKFinder_UserRole:"+user+"=========="); return true; } logger.info("==========session中没有CKFinder_UserRole进行拦截=========="); return false; }
2.3 登录时写session
@RequestMapping(value = "/admin.html", method = RequestMethod.POST) @ResponseBody public String ckAdmin(HttpServletRequest request, String userId) { logger.info("==========" + userId + "登陆了" + "=========="); HttpSession session=request.getSession(); // 这里的逻辑很简单,如果是admin就将session中CKFinder_UserRole设为admin,其他的设置为user if (userId.equals("admin")) { session.setAttribute("CKFinder_UserRole", "admin"); } else { session.setAttribute("CKFinder_UserRole", "user"); } logger.info("==========" + "session 设置成功" + "=========="); return "session 设置成功"; }
退出时清空session
@RequestMapping(value = "/logout.html", method = RequestMethod.POST) @ResponseBody public String ckLogout(HttpServletRequest request) { HttpSession session = request.getSession(); Enumeration
e = session.getAttributeNames(); while (e.hasMoreElements()) { String sessionName = (String) e.nextElement(); logger.info("==========存在的session有:" + sessionName + ":"+session.getAttribute(sessionName)+"=========="); session.removeAttribute(sessionName); } logger.info("==========" + "session 移除成功" + "=========="); return "session 移除成功"; }
2.4 演示
2.4.1 没有session
当用户没有登录,也就是说session中还什么都没有的时候

用户通过浏览服务器什么也干不了

http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html也是无法访问的。
这是日志信息

2.4.2 session中CKFinder_UserRole为user

这个时候用户只能浏览,上传,不能删除照片,重命名照片

当然,通过http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html直接访问,用户只能看到Images文件夹,对文件夹也只能读和创建操作

2.4.3 session中CKFinder_UserRole为admin

这个时候用户可以进行所有的操作

当然,通过http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html直接访问可以看到其他的文件夹,且具有删除操作

ckfinder的安全使用就写到这里。
示例地址
https://github.com/peer44/ckeditor
参考文献
http://docs.cksource.com/CKFinder_2.x/Developers_Guide/Java/Configuration/Access_Control
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207473.html原文链接:https://javaforall.net
