前言
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:
<code>/**
* xss過濾處理
* @author QinHaiLin
* @date 2020-02-13
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper{
\t
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[i] = getBasicHtmlandimage(values[i]);
}
return values;
}
/**
* 重寫並過濾getParameterMap方法
*/
@Override
public Map<string> getParameterMap() {
\t\tMap<string> paraMap = super.getParameterMap();
// 對於paraMap為空的直接return
if (null == paraMap || paraMap.isEmpty()) {
return paraMap;
}
//super.getParameterMap()不允許任何修改,所以只能做深拷貝
Map<string> paraMapCopy = new HashMap<string>();
//實際上putAll只對基本類型深拷貝有效,如果是自定義類型,則要找其他辦法
paraMapCopy.putAll(paraMap);
for (Map.Entry<string> entry : paraMapCopy.entrySet()) {
String[] values = entry.getValue();
if (null == values) {
continue;
}
String[] newValues = new String[values.length];
for (int i = 0; i newValues[i] = getBasicHtmlandimage(values[i]);
}
entry.setValue(newValues);
}
return paraMapCopy;
}
private static String getBasicHtmlandimage(String html) {
\t if (html == null)
\t return null;
\t return Jsoup.clean(html, Whitelist.basicWithImages());
\t}
}
/<string>/<string>/<string>/<string>/<string>/<code>
2、新建XssHandler攔截器:
<code>/**
* xss攔截器
* @author QinHaiLin
*
*/
public class XssHandler extends Handler {
\t// 排除的url,使用的target.startsWith匹配的
private String excludePattern;
/**
* 忽略列表,使用正則排除url
* @param exclude
*/
public XssHandler(String excludePattern) {
this.excludePattern = excludePattern;
}
\t@Override
\tpublic void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
\t\tjava.util.regex.Pattern pattern = Pattern.compile(excludePattern);
\t\t//帶.表示非action請求,忽略(其實不太嚴謹,如果是偽靜態,比如.html會被錯誤地排除);匹配excludePattern的,忽略
if (target.indexOf(".") == -1 && !(!StringUtil.isBlank(excludePattern) && pattern.matcher(target).find() ) ){
request = new XssHttpServletRequestWrapper(request);
}
next.handle(target, request, response, isHandled);
\t}
}
/<code>
3、在MainConfig裡面配置XssHandler攔截器,那麼對XSS的存儲型攻擊就可以進行有效的防禦了。
<code>\t/**
\t * 配置全局處理器
\t */
\t@Override
\tpublic void configHandler(Handlers me) {
\t\t/** 配置druid監控 **/
\t\tme.add(DruidKit.getDruidStatViewHandler());
\t\t// 路由處理
\t\tme.add(new CommonHandler());
\t\t// XSS過濾
\t\tme.add(new XssHandler("^\\\\/portal/form/view.*"));
\t}
/<code>
二、CSRF跨站請求偽造防禦
針對CSRF跨站請求偽造,JFinal-layui主要是對添加、修改的業務表單加入token驗證機制,這樣就可以解決重要業務操作的安全性。我們的攔截是全局驗證攔截,在開發功能過程中就是順手做的事情,簡單高效。
1、利用JFinal的token機制,創建自己的TokenService:
<code>/**
* token
* @author QinHaiLin
* @date 2020-02-14
*/
public class TokenService {
\t/**
\t * 創建token
\t * @param c
\t */
\tpublic void createToken(Controller c){
\t\tTokenManager.createToken(c, Const.DEFAULT_TOKEN_NAME, Const.DEFAULT_SECONDS_OF_TOKEN_TIME_OUT);
\t}
\t
\t/**
\t * 驗證token
\t * @param c
\t */
\tpublic boolean validateToken(Controller c){
\t\treturn TokenManager.validateToken(c, Const.DEFAULT_TOKEN_NAME);
\t}
}
/<code>
2、再創建TokenInterceptor的攔截器進行全局攔截驗證:
<code>/**
* token攔截器
* @author QinHaiLin
* @date 2020-02-13
*/
public class TokenInterceptor implements Interceptor {
\t@Inject
\tTokenService tokenService;
\t
\t@Override
\tpublic void intercept(Invocation inv) {
\t\tController c=inv.getController();
\t\tString methName=inv.getMethod().getName();
\t\t
\t\t//給默認的添加、修改方法添加token
\t\tif(methName.equals("add")||methName.equals("edit")){
\t\t\ttokenService.createToken(c);\t\t
\t\t}
\t\t
\t\t//驗證token
\t\tif(methName.equals("save")||methName.equals("update")){
\t\t\tboolean b=tokenService.validateToken(c);
\t\t\tif(!b){
\t\t\t\tboolean isAjax="XMLHttpRequest".equalsIgnoreCase(c.getHeader("X-Requested-With"));
\t\t\t\tif(isAjax){
\t\t\t\t\tc.renderJson(Ret.fail("msg", "token驗證不通過,請刷新頁面"));
\t\t\t\t}else{
\t\t\t\t\tc.setAttr("msg", "token驗證不通過");
\t\t\t\t\tc.renderError(403);
\t\t\t\t}
\t\t\t\treturn;
\t\t\t}
\t\t\t//添加修改成功後,返回對的頁面,此處是解決業務驗證不通過的情況,如:添加用戶時,如果存在用戶編號,那麼需要重新填寫,此時就要重新賦值新的token
\t\t\ttokenService.createToken(c);
\t\t}
\t\tinv.invoke();
\t}
}
/<code>
3、在MainConfig配置成全局攔截器即可:
<code>/**
\t * 配置全局攔截器
\t */
\t@Override
\tpublic void configInterceptor(Interceptors me) {
\t\tme.addGlobalActionInterceptor(new SessionInViewInterceptor());
\t\tme.addGlobalActionInterceptor(new SessionInterceptor());
\t\tme.addGlobalActionInterceptor(new ExceptionInterceptor());
\t\t//表單token驗證攔截器
\t\tme.addGlobalActionInterceptor(new TokenInterceptor());
\t\tme.addGlobalActionInterceptor(new LoggerInterceptor());
\t}
/<code>
4、在添加修改的操作表單輸出token:#(token)
三、代碼生成器
為滿足廣大用戶要求,還是決定把代碼生成器集成進來,那麼有了這一神器,就可以把那些繁瑣重複的開發工作交給代碼器了,一鍵多表生成代碼文件,頁面操作簡單,直接生成代碼文件到項目當中,刷新重啟項目即可。
1、代碼生成器操作頁面,選擇需要的表,可多選,點擊選擇按鈕即可:
2、點擊生成代碼,這是預覽代碼,還沒有真正創建代碼文件,點擊下載代碼才是最終在項目中創建:
3、點擊下載代碼,創建文件:
4、刷新項目,就能在預先設置的package裡面創建對應的Java文件了,html目錄也是按照相應規則創建對應的目錄:
java文件: html文件:
5、此時代碼文件已經創建好了,還需要最關鍵的一步,那就是把_MappingKit.java裡面在數據庫表映射關係配置到主配置文件中:
6、最後就是啟動項目,配置菜單權限即可訪問了。
閱讀更多 IT實戰聯盟 的文章