Commit 507f55f3c922219a2991e27bb532b4043a084454

Authored by YunaiV
1 parent 593e14f3

1. Xss 的完成

2. 完善 README 文档
README.md
@@ -6,36 +6,45 @@ @@ -6,36 +6,45 @@
6 6
7 * 前端采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)。 7 * 前端采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)。
8 * 后端采用 Spring Boot、MySQL、Redis。 8 * 后端采用 Spring Boot、MySQL、Redis。
9 -* 权限认证使用 Spring Security & JWT,支持多终端认证系统。 9 +* 权限认证使用 Spring Security & Token,支持多终端认证系统。
10 * 支持加载动态权限菜单,多方式轻松权限控制。 10 * 支持加载动态权限菜单,多方式轻松权限控制。
11 * 高效率开发,使用代码生成器可以一键生成前后端代码。 11 * 高效率开发,使用代码生成器可以一键生成前后端代码。
12 12
13 ## 内置功能 13 ## 内置功能
14 14
15 -分成 **业务** 和 **技术** 两类内置功能。  
16 -  
17 -### 业务功能  
18 -  
19 -1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。  
20 -2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。  
21 -3. 岗位管理:配置系统用户所属担任职务。  
22 -4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。  
23 -5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。  
24 -6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。  
25 -7. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。  
26 -8. 登录日志:系统登录日志记录查询包含登录异常。  
27 -9. 在线用户:当前系统中活跃用户状态监控。  
28 -10. 通知公告:系统通知公告信息发布维护。  
29 -  
30 -## 技术功能  
31 -  
32 -1. 配置管理:对系统动态配置常用参数。  
33 -2. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。  
34 -3. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。  
35 -4. 系统接口:根据业务代码自动生成相关的api接口文档。  
36 -5. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。  
37 -6. 在线构建器:拖动表单元素生成相应的HTML代码。  
38 -7. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 15 +分成三种内置功能:
  16 +* 系统功能
  17 +* 基础设施
  18 +* 研发工具
  19 +
  20 +### 系统功能
  21 +
  22 +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置
  23 +1. 在线用户:当前系统中活跃用户状态监控
  24 +1. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分
  25 +1. 菜单管理:配置系统菜单,操作权限,按钮权限标识等
  26 +1. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限
  27 +1. 岗位管理:配置系统用户所属担任职务
  28 +1. 字典管理:对系统中经常使用的一些较为固定的数据进行维护
  29 +1. 通知公告:系统通知公告信息发布维护
  30 +1. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询
  31 +1. 登录日志:系统登录日志记录查询包含登录异常
  32 +
  33 +### 基础设施
  34 +
  35 +1. 配置管理:对系统动态配置常用参数
  36 +1. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志
  37 +1. MySQL 监控:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈
  38 +1. Redis 监控:监控 Redis 数据库的使用情况,使用的 Redis Key 管理
  39 +1. Java 监控:基于 Spring Boot Admin 实现 Java 应用的监控
  40 +1. 链路追踪:基于 SkyWalking 实现性能监控,特别是链路的追踪
  41 +
  42 +### 研发工具
  43 +
  44 +1. 表单构建:拖动表单元素生成相应的 HTML 代码
  45 +1. 代码生成:前后端代码的生成(Java、Vue、SQL),支持 CRUD 下载
  46 +1. 系统接口:基于 Swagger 自动生成相关的 RESTful API 接口文档
  47 +1. 数据库文档:基于 Screw 自动生成数据库文档
39 48
40 ## 在线体验 49 ## 在线体验
41 50
ruoyi-common/src/main/java/com/ruoyi/common/config/FilterConfig.java deleted
1 -package com.ruoyi.framework.config;  
2 -  
3 -import java.util.HashMap;  
4 -import java.util.Map;  
5 -import javax.servlet.DispatcherType;  
6 -  
7 -import org.springframework.beans.factory.annotation.Value;  
8 -import org.springframework.boot.web.servlet.FilterRegistrationBean;  
9 -import org.springframework.context.annotation.Bean;  
10 -import org.springframework.context.annotation.Configuration;  
11 -import com.ruoyi.common.filter.RepeatableFilter;  
12 -import com.ruoyi.common.filter.XssFilter;  
13 -import com.ruoyi.common.utils.StringUtils;  
14 -  
15 -/**  
16 - * Filter配置  
17 - *  
18 - * @author ruoyi  
19 - */  
20 -@Configuration  
21 -public class FilterConfig {  
22 - @Value("${xss.enabled}")  
23 - private String enabled;  
24 -  
25 - @Value("${xss.excludes}")  
26 - private String excludes;  
27 -  
28 - @Value("${xss.urlPatterns}")  
29 - private String urlPatterns;  
30 -  
31 - @SuppressWarnings({"rawtypes", "unchecked"})  
32 - @Bean  
33 - public FilterRegistrationBean xssFilterRegistration() {  
34 - FilterRegistrationBean registration = new FilterRegistrationBean();  
35 - registration.setDispatcherTypes(DispatcherType.REQUEST);  
36 - registration.setFilter(new XssFilter());  
37 - registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));  
38 - registration.setName("xssFilter");  
39 - registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);  
40 - Map<String, String> initParameters = new HashMap<String, String>();  
41 - initParameters.put("excludes", excludes);  
42 - initParameters.put("enabled", enabled);  
43 - registration.setInitParameters(initParameters);  
44 - return registration;  
45 - }  
46 -  
47 -}  
ruoyi-common/src/main/java/com/ruoyi/common/filter/XssFilter.java deleted
1 -package com.ruoyi.common.filter;  
2 -  
3 -import java.io.IOException;  
4 -import java.util.ArrayList;  
5 -import java.util.List;  
6 -import java.util.regex.Matcher;  
7 -import java.util.regex.Pattern;  
8 -import javax.servlet.Filter;  
9 -import javax.servlet.FilterChain;  
10 -import javax.servlet.FilterConfig;  
11 -import javax.servlet.ServletException;  
12 -import javax.servlet.ServletRequest;  
13 -import javax.servlet.ServletResponse;  
14 -import javax.servlet.http.HttpServletRequest;  
15 -import javax.servlet.http.HttpServletResponse;  
16 -import com.ruoyi.common.utils.StringUtils;  
17 -  
18 -/**  
19 - * 防止XSS攻击的过滤器  
20 - *  
21 - * @author ruoyi  
22 - */  
23 -public class XssFilter implements Filter  
24 -{  
25 - /**  
26 - * 排除链接  
27 - */  
28 - public List<String> excludes = new ArrayList<>();  
29 -  
30 - /**  
31 - * xss过滤开关  
32 - */  
33 - public boolean enabled = false;  
34 -  
35 - @Override  
36 - public void init(FilterConfig filterConfig) throws ServletException  
37 - {  
38 - String tempExcludes = filterConfig.getInitParameter("excludes");  
39 - String tempEnabled = filterConfig.getInitParameter("enabled");  
40 - if (StringUtils.isNotEmpty(tempExcludes))  
41 - {  
42 - String[] url = tempExcludes.split(",");  
43 - for (int i = 0; url != null && i < url.length; i++)  
44 - {  
45 - excludes.add(url[i]);  
46 - }  
47 - }  
48 - if (StringUtils.isNotEmpty(tempEnabled))  
49 - {  
50 - enabled = Boolean.valueOf(tempEnabled);  
51 - }  
52 - }  
53 -  
54 - @Override  
55 - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
56 - throws IOException, ServletException  
57 - {  
58 - HttpServletRequest req = (HttpServletRequest) request;  
59 - HttpServletResponse resp = (HttpServletResponse) response;  
60 - if (handleExcludeURL(req, resp))  
61 - {  
62 - chain.doFilter(request, response);  
63 - return;  
64 - }  
65 - XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);  
66 - chain.doFilter(xssRequest, response);  
67 - }  
68 -  
69 - private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)  
70 - {  
71 - if (!enabled)  
72 - {  
73 - return true;  
74 - }  
75 - if (excludes == null || excludes.isEmpty())  
76 - {  
77 - return false;  
78 - }  
79 - String url = request.getServletPath();  
80 - for (String pattern : excludes)  
81 - {  
82 - Pattern p = Pattern.compile("^" + pattern);  
83 - Matcher m = p.matcher(url);  
84 - if (m.find())  
85 - {  
86 - return true;  
87 - }  
88 - }  
89 - return false;  
90 - }  
91 -  
92 - @Override  
93 - public void destroy()  
94 - {  
95 -  
96 - }  
97 -}  
98 \ No newline at end of file 0 \ No newline at end of file
ruoyi-common/src/main/resources/application.yml
@@ -33,12 +33,3 @@ logging: @@ -33,12 +33,3 @@ logging:
33 level: 33 level:
34 com.ruoyi: debug 34 com.ruoyi: debug
35 org.springframework: warn 35 org.springframework: warn
36 -  
37 -# 防止XSS攻击  
38 -xss:  
39 - # 过滤开关  
40 - enabled: true  
41 - # 排除链接(多个用逗号分隔)  
42 - excludes: /system/notice/*  
43 - # 匹配链接  
44 - urlPatterns: /system/*,/monitor/*,/tool/*  
src/main/java/cn/iocoder/dashboard/framework/web/core/filter/XssRequestWrapper.java
1 package cn.iocoder.dashboard.framework.web.core.filter; 1 package cn.iocoder.dashboard.framework.web.core.filter;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.io.IoUtil; 4 import cn.hutool.core.io.IoUtil;
  5 +import cn.hutool.core.util.ArrayUtil;
4 import cn.hutool.core.util.ReflectUtil; 6 import cn.hutool.core.util.ReflectUtil;
5 import cn.hutool.core.util.StrUtil; 7 import cn.hutool.core.util.StrUtil;
6 import cn.hutool.http.HTMLFilter; 8 import cn.hutool.http.HTMLFilter;
@@ -14,6 +16,7 @@ import java.io.BufferedReader; @@ -14,6 +16,7 @@ import java.io.BufferedReader;
14 import java.io.ByteArrayInputStream; 16 import java.io.ByteArrayInputStream;
15 import java.io.IOException; 17 import java.io.IOException;
16 import java.io.InputStreamReader; 18 import java.io.InputStreamReader;
  19 +import java.util.Map;
17 20
18 /** 21 /**
19 * Xss 请求 Wrapper 22 * Xss 请求 Wrapper
@@ -36,7 +39,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper { @@ -36,7 +39,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
36 super(request); 39 super(request);
37 } 40 }
38 41
39 - private static String filterHtml(String content) { 42 + private static String filterXss(String content) {
40 if (StrUtil.isEmpty(content)) { 43 if (StrUtil.isEmpty(content)) {
41 return content; 44 return content;
42 } 45 }
@@ -59,7 +62,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper { @@ -59,7 +62,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
59 62
60 // 读取内容,并过滤 63 // 读取内容,并过滤
61 String content = IoUtil.readUtf8(super.getInputStream()); 64 String content = IoUtil.readUtf8(super.getInputStream());
62 - content = filterHtml(content); 65 + content = filterXss(content);
63 final ByteArrayInputStream newInputStream = new ByteArrayInputStream(content.getBytes()); 66 final ByteArrayInputStream newInputStream = new ByteArrayInputStream(content.getBytes());
64 // 返回 ServletInputStream 67 // 返回 ServletInputStream
65 return new ServletInputStream() { 68 return new ServletInputStream() {
@@ -87,6 +90,47 @@ public class XssRequestWrapper extends HttpServletRequestWrapper { @@ -87,6 +90,47 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
87 90
88 // ========== Param 相关 ========== 91 // ========== Param 相关 ==========
89 92
  93 + @Override
  94 + public String getParameter(String name) {
  95 + String value = super.getParameter(name);
  96 + return filterXss(value);
  97 + }
  98 +
  99 + @Override
  100 + public String[] getParameterValues(String name) {
  101 + String[] values = super.getParameterValues(name);
  102 + if (ArrayUtil.isEmpty(values)) {
  103 + return values;
  104 + }
  105 + // 过滤处理
  106 + for (int i = 0; i < values.length; i++) {
  107 + values[i] = filterXss(values[i]);
  108 + }
  109 + return values;
  110 + }
  111 +
  112 + @Override
  113 + public Map<String, String[]> getParameterMap() {
  114 + Map<String, String[]> valueMap = super.getParameterMap();
  115 + if (CollUtil.isEmpty(valueMap)) {
  116 + return valueMap;
  117 + }
  118 + // 过滤处理
  119 + for (Map.Entry<String, String[]> entry : valueMap.entrySet()) {
  120 + String[] values = entry.getValue();
  121 + for (int i = 0; i < values.length; i++) {
  122 + values[i] = filterXss(values[i]);
  123 + }
  124 + }
  125 + return valueMap;
  126 + }
  127 +
90 // ========== Header 相关 ========== 128 // ========== Header 相关 ==========
91 129
  130 + @Override
  131 + public String getHeader(String name) {
  132 + String value = super.getHeader(name);
  133 + return filterXss(value);
  134 + }
  135 +
92 } 136 }
src/main/resources/application-dev.yaml
@@ -87,6 +87,7 @@ apollo: @@ -87,6 +87,7 @@ apollo:
87 management: 87 management:
88 endpoints: 88 endpoints:
89 web: 89 web:
  90 + base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
90 exposure: 91 exposure:
91 include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 92 include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
92 93
@@ -131,3 +132,8 @@ yudao: @@ -131,3 +132,8 @@ yudao:
131 codegen: 132 codegen:
132 base-package: ${yudao.info.base-package}.modules 133 base-package: ${yudao.info.base-package}.modules
133 db-schemas: ${spring.datasource.name} 134 db-schemas: ${spring.datasource.name}
  135 + xss:
  136 + enable: true
  137 + exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
  138 + - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
  139 + - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
src/main/resources/application-local.yaml
@@ -87,6 +87,7 @@ apollo: @@ -87,6 +87,7 @@ apollo:
87 management: 87 management:
88 endpoints: 88 endpoints:
89 web: 89 web:
  90 + base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
90 exposure: 91 exposure:
91 include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 92 include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
92 93
@@ -131,3 +132,8 @@ yudao: @@ -131,3 +132,8 @@ yudao:
131 codegen: 132 codegen:
132 base-package: ${yudao.info.base-package}.modules 133 base-package: ${yudao.info.base-package}.modules
133 db-schemas: ${spring.datasource.name} 134 db-schemas: ${spring.datasource.name}
  135 + xss:
  136 + enable: true
  137 + exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
  138 + - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
  139 + - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求