解决方案

CKEditor与CKFinder学习--安全的使用CKFinder与权限控制

seo靠我 2023-09-23 18:09:59

0 前言

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

上一篇博客介绍了一种方法就是直接屏蔽掉浏览服务器的按钮,这样用户就只能上传,通过上传后再引用。不过尽管把按钮屏蔽了,但是链接的路径依然存在。

通过访问

http://127.0.0SEO靠我.1:8080/ckdemo/assets/ckfinder/ckfinder.html

用户依然可以访问到文件浏览的页面

所以本文的第一个就是介绍如何不让用户访问http://127.0.0.1:808SEO靠我0/ckdemo/assets/ckfinder/ckfinder.html页面。

不让用户访问上面的页面,可以有很多种方法,可以参考之前的Shiro进行拦截,然而本文今天介绍使用SpringMVC的拦SEO靠我截器对其进行拦截。

1 通过拦截器阻止直接访问

1.1 定义拦截器

实现HandlerInterceptor接口

package com.gwc.cktest.intercepter;import java.SEO靠我util.Enumeration;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttSEO靠我pServletResponse; import javax.servlet.http.HttpSession;import org.apache.commons.lang3.StriSEO靠我ngUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LoSEO靠我gFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.spriSEO靠我ngframework.web.servlet.ModelAndView;public class CkfinderInterceepter implements HandlerInterceptorSEO靠我 {private static final Log logger = LogFactory.getLog(CkfinderInterceepter.class);@Overridepublic voSEO靠我id afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)thSEO靠我rows Exception {logger.info("==========走到了 afterCompletion() 方法");}@Overridepublic void postHandle(HSEO靠我ttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView model)throws ExcepSEO靠我tion {logger.info("==========走到了 postHandle() 方法");}// 返回值,表示我们是否需要将当前的请求拦截下来// 如果返回false,请求将被终止,如果为SEO靠我true,请求将被放行// Object arg2 表示的是被拦截的请求的目标对象@Overridepublic boolean preHandle(HttpServletRequest requesSEO靠我t, HttpServletResponse response, Object arg2) throws Exception {logger.info("==========走到了 preHandleSEO靠我() 方法"+"==========");logger.info("==========进行拦截==========");return false;}}

1.2 配置拦截器和拦截规则

在SpringMVCSEO靠我的配置文件中进行拦截器的配置和拦截规则的设定

<mvc:interceptors><mvc:interceptor><!-- 拦截规则 --><mvc:mapping path="/**/ckfindeSEO靠我r.html" /><!-- 拦截器 --><bean class="com.gwc.cktest.intercepter.CkfinderInterceepter"></bean></mvc:intSEO靠我erceptor></mvc:interceptors>

因为我们需要拦截的是

http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html

所以我们SEO靠我的拦截规则设置为/**/ckfinder.html

1.3 效果

没有配置拦截器

配置拦截器之后

这种方式有点类似CSDN写博客了,只允许上传图片或者引用其他在线图片,不能浏览

2 细粒度的权限控制

细粒度的权限SEO靠我控制中,我们将不会全部拦截对http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html的请求,而是进行有条件的拦截,条件就是ckfinder权SEO靠我限中的角色session对应的key为CKFinder_UserRole,我们在拦截器中需要查看session中是否有有CKFinder_UserRole再决定放行与否。在用户登录的时候往sessioSEO靠我n中写CKFinder_UserRole。

具体流程图如下。

先来配置资源访问的访问控制(ACL),这部分在ckfinder.xml中进行配置。

2.1 配置ckfinder.xml

首先阅读一下ckfindSEO靠我er的开发者文档

http://docs.cksource.com/CKFinder_2.x/Developers_Guide/Java/Configuration/Access_Control

它介绍了SEO靠我访问控制,主要是通过配置accessControls来控制用户的权限的<!-- The session variable name that CKFinder must use to SEO靠我retrieve the "role" of the current user. The "role", can be used in the "accessControls" SEO靠我 settings (bellow). --><userRoleSessionVar>CKFinder_UserRole</userRoleSessionVar><accessSEO靠我Controls><accessControl><role>*</role><resourceType>Images</resourceType><folder>/Logos</folder><folSEO靠我derView>true</folderView><folderCreate>true</folderCreate><folderRename>true</folderRename><folderDeSEO靠我lete>true</folderDelete><fileView>true</fileView><fileUpload>false</fileUpload><fileRename>false</fiSEO靠我leRename><fileDelete>false</fileDelete></accessControl></accessControls>

所有的权限都在accessControls标签中,具体的SEO靠我权限被配置在一个个accessControl中

其中第一个role标签代表的是角色,与其称作角色不如称为key为CKFinder_UserRole的session,在userRoleSessionVarSEO靠我可以配置。

你可以配置自己喜欢的session使其key为CKFinder_UserRole的value为你喜欢的任何字符串,不过最好能见名知意,*表示是所有的用户都可以访问。

其他标签也很好理解resoSEO靠我urceType表示资源类型,以folder开头的是对文件夹的操作权限,以file开头的是对文的操作权限。

2.1.1 权限配置

现在我们配置两种权限,一个是admin,权限最大,什么权限都有,另一个是uSEO靠我ser权限,他只能查看根目录下的Images资源,而且对文件夹有只读操作和创建操作,对文件具有查看和上传操作。

<userRoleSessionVar>CKFinder_UserRole</userRoSEO靠我leSessionVar><accessControls><accessControl><role>admin</role><resourceType>*</resourceType><folder>SEO靠我/</folder><folderView>true</folderView><folderCreate>true</folderCreate><folderRename>true</folderReSEO靠我name><folderDelete>true</folderDelete><fileView>true</fileView><fileUpload>true</fileUpload><fileRenSEO靠我ame>true</fileRename><fileDelete>true</fileDelete></accessControl><accessControl><role>user</role><rSEO靠我esourceType>Images</resourceType><folder>/</folder><folderView>true</folderView><folderCreate>true</SEO靠我folderCreate><folderRename>false</folderRename><folderDelete>false</folderDelete><fileView>true</filSEO靠我eView><fileUpload>true</fileUpload><fileRename>false</fileRename><fileDelete>false</fileDelete></accSEO靠我essControl></accessControls>

2.2 拦截器实现

将上面的拦截器进行修改,只改preHandle方法,如果session中有CKFinder_UserRole则放行,否则拦截请SEO靠我求。

// 返回值,表示我们是否需要将当前的请求拦截下来// 如果返回false,请求将被终止,如果为true,请求将被放行// Object arg2 表示的是被拦截的请求的目标对象@OverrideSEO靠我public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throSEO靠我ws Exception {logger.info("==========走到了 preHandle() 方法"+"==========");HttpSession session = requestSEO靠我.getSession();String user = (String) session.getAttribute("CKFinder_UserRole");if (StringUtils.isNotSEO靠我Empty(user)) {logger.info("==========session中的CKFinder_UserRole:"+user+"==========");return true;}loSEO靠我gger.info("==========session中没有CKFinder_UserRole进行拦截==========");return false;}

2.3 登录时写session

@RequeSEO靠我stMapping(value = "/admin.html", method = RequestMethod.POST)@ResponseBodypublic String ckAdmin(HttpSEO靠我ServletRequest request, String userId) {logger.info("==========" + userId + "登陆了" + "==========");HtSEO靠我tpSession session=request.getSession();// 这里的逻辑很简单,如果是admin就将session中CKFinder_UserRole设为admin,其他的设置为SEO靠我userif (userId.equals("admin")) {session.setAttribute("CKFinder_UserRole", "admin");} else {session.SEO靠我setAttribute("CKFinder_UserRole", "user");}logger.info("==========" + "session 设置成功" + "==========")SEO靠我;return "session 设置成功";}

退出时清空session

@RequestMapping(value = "/logout.html", method = RequestMethod.PSEO靠我OST)@ResponseBodypublic String ckLogout(HttpServletRequest request) {HttpSession session = request.gSEO靠我etSession();Enumeration<?> e = session.getAttributeNames();while (e.hasMoreElements()) {String sessiSEO靠我onName = (String) e.nextElement();logger.info("==========存在的session有:" + sessionName + ":"+session.gSEO靠我etAttribute(sessionName)+"==========");session.removeAttribute(sessionName);}logger.info("==========SEO靠我" + "session 移除成功" + "==========");return "session 移除成功";}

2.4 演示

2.4.1 没有session

当用户没有登录,也就是说session中还SEO靠我什么都没有的时候

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

http://127.0.0.1:8080/ckdemo/assets/ckfinder/ckfinder.html也是无法访问的。

这是日志信息

2.4.2SEO靠我 session中CKFinder_UserRole为user

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

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

2.4.3 session中CKFinder_UserRole为admin

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

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

ckfinder的SEO靠我安全使用就写到这里。

示例地址

https://github.com/peer44/ckeditor

参考文献

http://docs.cksource.com/CKFinder_2.x/DevelopersSEO靠我_Guide/Java/Configuration/Access_Control

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2