JFinal-layui 極速開發企業應用管理系統,是以 JFinal+layui 為核心的企業應用項目架構,利用 JFinal 的特性與 layui 完美結合,達到快速啟動項目的目的。讓開發更簡單高效,即使你不會前端layui,也能輕鬆掌握使用。
JFinal-layui v1.4.2 新增XSS、CSRF防禦和代碼生成器,加強web安全和提升開發效率!在工作中發現,一些公司在給客戶開發系統的時候,都很容易忽略了web安全的內容,或者根本不考慮web安全漏洞,所以這樣開發出來的系統本身就是存在很大的安全隱患,只要稍微有點技術的人員就能進行XSS攻擊和CSRF跨站請求偽造!因為本人有過一段難忘的web安全漏洞修復的經歷,所以把積累的一些經驗應用到JFinal-layui中,讓系統更加安全可靠!
v1.4.2更新內容詳情:
一、XSS攻擊防禦
JFinal-layui主要是對XSS的存儲型攻擊進行防禦,把用戶輸入的數據都進行XSS過濾,避免對系統造成不良影響。利用JFInal的Handler來實現,重寫HttpServletRequestWrapper非常簡單。
1、自定義XssHttpServletRequestWrapper類,重寫getParameter:
/** * xss過濾處理 * @author QinHaiLin * @date 2020-02-13 */ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper{ public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } /** * 重寫並過濾getParameter方法 */ @Override public String getParameter(String name) { return getBasicHtmlandimage(super.getParameter(name)); } /** * 重寫並過濾getParameterValues方法 */ @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); if (null == values){ return null; } for (int i = 0; i < values.length; i++) { values[i] = getBasicHtmlandimage(values[i]); } return values; } /** * 重寫並過濾getParameterMap方法 */ @Override public Map getParameterMap() { Map paraMap = super.getParameterMap(); // 對於paraMap為空的直接return if (null == paraMap || paraMap.isEmpty()) { return paraMap; } //super.getParameterMap()不允許任何修改,所以只能做深拷貝 Map paraMapCopy = new HashMap(); //實際上putAll只對基本類型深拷貝有效,如果是自定義類型,則要找其他辦法 paraMapCopy.putAll(paraMap); for (Map.Entry entry : paraMapCopy.entrySet()) { String[] values = entry.getValue(); if (null == values) { continue; } String[] newValues = new String[values.length]; for (int i = 0; i < values.length; i++) { newValues[i] = getBasicHtmlandimage(values[i]); } entry.setValue(newValues); } return paraMapCopy; } private static String getBasicHtmlandimage(String html) { if (html == null) return null; return Jsoup.clean(html, Whitelist.basicWithImages()); } }
2、新建XssHandler攔截器:
/** * xss攔截器 * @author QinHaiLin * */ public class XssHandler extends Handler { // 排除的url,使用的target.startsWith匹配的 private String excludePattern; /** * 忽略列表,使用正則排除url * @param exclude */ public XssHandler(String excludePattern) { this.excludePattern = excludePattern; } @Override public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) { java.util.regex.Pattern pattern = Pattern.compile(excludePattern); //帶.表示非action請求,忽略(其實不太嚴謹,如果是偽靜態,比如.html會被錯誤地排除);匹配excludePattern的,忽略 if (target.indexOf(".") == -1 && !(!StringUtil.isBlank(excludePattern) && pattern.matcher(target).find() ) ){ request = new XssHttpServletRequestWrapper(request); } next.handle(target, request, response, isHandled); } }
3、在MainConfig裡面配置XssHandler攔截器,那麼對XSS的存儲型攻擊就可以進行有效的防禦了。
/** * 配置全局處理器 */ @Override public void configHandler(Handlers me) { /** 配置druid監控 **/ me.add(DruidKit.getDruidStatViewHandler()); // 路由處理 me.add(new CommonHandler()); // XSS過濾 me.add(new XssHandler("^\\/portal/form/view.*")); }
二、CSRF跨站請求偽造防禦
針對CSRF跨站請求偽造,JFinal-layui主要是對添加、修改的業務表單加入token驗證機制,這樣就可以解決重要業務操作的安全性。我們的攔截是全局驗證攔截,在開發功能過程中就是順手做的事情,簡單高效。
1、利用JFinal的token機制,創建自己的TokenService:
/** * token * @author QinHaiLin * @date 2020-02-14 */ public class TokenService { /** * 創建token * @param c */ public void createToken(Controller c){ TokenManager.createToken(c, Const.DEFAULT_TOKEN_NAME, Const.DEFAULT_SECONDS_OF_TOKEN_TIME_OUT); } /** * 驗證token * @param c */ public boolean validateToken(Controller c){ return TokenManager.validateToken(c, Const.DEFAULT_TOKEN_NAME); } }
2、再創建TokenInterceptor的攔截器進行全局攔截驗證:
/** * token攔截器 * @author QinHaiLin * @date 2020-02-13 */ public class TokenInterceptor implements Interceptor { @Inject TokenService tokenService; @Override public void intercept(Invocation inv) { Controller c=inv.getController(); String methName=inv.getMethod().getName(); //給默認的添加、修改方法添加token if(methName.equals("add")||methName.equals("edit")){ tokenService.createToken(c); } //驗證token if(methName.equals("save")||methName.equals("update")){ boolean b=tokenService.validateToken(c); if(!b){ boolean isAjax="XMLHttpRequest".equalsIgnoreCase(c.getHeader("X-Requested-With")); if(isAjax){ c.renderJson(Ret.fail("msg", "token驗證不通過,請刷新頁面")); }else{ c.setAttr("msg", "token驗證不通過"); c.renderError(403); } return; } //添加修改成功后,返回對的頁面,此處是解決業務驗證不通過的情況,如:添加用戶時,如果存在用戶編號,那麼需要重新填寫,此時就要重新賦值新的token tokenService.createToken(c); } inv.invoke(); } }
3、在MainConfig配置成全局攔截器即可:
/** * 配置全局攔截器 */ @Override public void configInterceptor(Interceptors me) { me.addGlobalActionInterceptor(new SessionInViewInterceptor()); me.addGlobalActionInterceptor(new SessionInterceptor()); me.addGlobalActionInterceptor(new ExceptionInterceptor()); //表單token驗證攔截器 me.addGlobalActionInterceptor(new TokenInterceptor()); me.addGlobalActionInterceptor(new LoggerInterceptor()); }
4、在添加修改的操作表單輸出token:#(token)
三、代碼生成器
為滿足廣大用戶要求,還是決定把代碼生成器集成進來,那麼有了這一神器,就可以把那些繁瑣重複的開發工作交給代碼器了,一鍵多表生成代碼文件,頁面操作簡單,直接生成代碼文件到項目當中,刷新重啟項目即可。
1、代碼生成器操作頁面,選擇需要的表,可多選,點擊選擇按鈕即可:
2、點擊生成代碼,這是預覽代碼,還沒有真正創建代碼文件,點擊下載代碼才是最終在項目中創建:
3、點擊下載代碼,創建文件:
4、刷新項目,就能在預先設置的package裡面創建對應的Java文件了,html目錄也是按照相應規則創建對應的目錄:
java文件: html文件:
5、此時代碼文件已經創建好了,還需要最關鍵的一步,那就是把_MappingKit.java裡面在資料庫表映射關係配置到主配置文件中:
6、最後就是啟動項目,配置菜單許可權即可訪問了。
友情鏈接:
社區交流:JFinal-layui社區
源碼下載:JFinal-layui
[admin
]