1. Xss 的完成
2. 完善 README 文档
This commit is contained in:
parent
593e14f3a9
commit
507f55f3c9
51
README.md
51
README.md
@ -6,36 +6,45 @@
|
||||
|
||||
* 前端采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)。
|
||||
* 后端采用 Spring Boot、MySQL、Redis。
|
||||
* 权限认证使用 Spring Security & JWT,支持多终端认证系统。
|
||||
* 权限认证使用 Spring Security & Token,支持多终端认证系统。
|
||||
* 支持加载动态权限菜单,多方式轻松权限控制。
|
||||
* 高效率开发,使用代码生成器可以一键生成前后端代码。
|
||||
|
||||
## 内置功能
|
||||
|
||||
分成 **业务** 和 **技术** 两类内置功能。
|
||||
分成三种内置功能:
|
||||
* 系统功能
|
||||
* 基础设施
|
||||
* 研发工具
|
||||
|
||||
### 业务功能
|
||||
### 系统功能
|
||||
|
||||
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
|
||||
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
|
||||
3. 岗位管理:配置系统用户所属担任职务。
|
||||
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
|
||||
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
|
||||
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
|
||||
7. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
|
||||
8. 登录日志:系统登录日志记录查询包含登录异常。
|
||||
9. 在线用户:当前系统中活跃用户状态监控。
|
||||
10. 通知公告:系统通知公告信息发布维护。
|
||||
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置
|
||||
1. 在线用户:当前系统中活跃用户状态监控
|
||||
1. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分
|
||||
1. 菜单管理:配置系统菜单,操作权限,按钮权限标识等
|
||||
1. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限
|
||||
1. 岗位管理:配置系统用户所属担任职务
|
||||
1. 字典管理:对系统中经常使用的一些较为固定的数据进行维护
|
||||
1. 通知公告:系统通知公告信息发布维护
|
||||
1. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询
|
||||
1. 登录日志:系统登录日志记录查询包含登录异常
|
||||
|
||||
## 技术功能
|
||||
### 基础设施
|
||||
|
||||
1. 配置管理:对系统动态配置常用参数。
|
||||
2. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
|
||||
3. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
|
||||
4. 系统接口:根据业务代码自动生成相关的api接口文档。
|
||||
5. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
||||
6. 在线构建器:拖动表单元素生成相应的HTML代码。
|
||||
7. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
||||
1. 配置管理:对系统动态配置常用参数
|
||||
1. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志
|
||||
1. MySQL 监控:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈
|
||||
1. Redis 监控:监控 Redis 数据库的使用情况,使用的 Redis Key 管理
|
||||
1. Java 监控:基于 Spring Boot Admin 实现 Java 应用的监控
|
||||
1. 链路追踪:基于 SkyWalking 实现性能监控,特别是链路的追踪
|
||||
|
||||
### 研发工具
|
||||
|
||||
1. 表单构建:拖动表单元素生成相应的 HTML 代码
|
||||
1. 代码生成:前后端代码的生成(Java、Vue、SQL),支持 CRUD 下载
|
||||
1. 系统接口:基于 Swagger 自动生成相关的 RESTful API 接口文档
|
||||
1. 数据库文档:基于 Screw 自动生成数据库文档
|
||||
|
||||
## 在线体验
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.ruoyi.common.filter.RepeatableFilter;
|
||||
import com.ruoyi.common.filter.XssFilter;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Filter配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
@Value("${xss.enabled}")
|
||||
private String enabled;
|
||||
|
||||
@Value("${xss.excludes}")
|
||||
private String excludes;
|
||||
|
||||
@Value("${xss.urlPatterns}")
|
||||
private String urlPatterns;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Bean
|
||||
public FilterRegistrationBean xssFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
registration.setFilter(new XssFilter());
|
||||
registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
|
||||
registration.setName("xssFilter");
|
||||
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
|
||||
Map<String, String> initParameters = new HashMap<String, String>();
|
||||
initParameters.put("excludes", excludes);
|
||||
initParameters.put("enabled", enabled);
|
||||
registration.setInitParameters(initParameters);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 防止XSS攻击的过滤器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* 排除链接
|
||||
*/
|
||||
public List<String> excludes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* xss过滤开关
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
String tempExcludes = filterConfig.getInitParameter("excludes");
|
||||
String tempEnabled = filterConfig.getInitParameter("enabled");
|
||||
if (StringUtils.isNotEmpty(tempExcludes))
|
||||
{
|
||||
String[] url = tempExcludes.split(",");
|
||||
for (int i = 0; url != null && i < url.length; i++)
|
||||
{
|
||||
excludes.add(url[i]);
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(tempEnabled))
|
||||
{
|
||||
enabled = Boolean.valueOf(tempEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
if (handleExcludeURL(req, resp))
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (excludes == null || excludes.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String url = request.getServletPath();
|
||||
for (String pattern : excludes)
|
||||
{
|
||||
Pattern p = Pattern.compile("^" + pattern);
|
||||
Matcher m = p.matcher(url);
|
||||
if (m.find())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -33,12 +33,3 @@ logging:
|
||||
level:
|
||||
com.ruoyi: debug
|
||||
org.springframework: warn
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice/*
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
|
@ -1,6 +1,8 @@
|
||||
package cn.iocoder.dashboard.framework.web.core.filter;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HTMLFilter;
|
||||
@ -14,6 +16,7 @@ import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Xss 请求 Wrapper
|
||||
@ -36,7 +39,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
||||
super(request);
|
||||
}
|
||||
|
||||
private static String filterHtml(String content) {
|
||||
private static String filterXss(String content) {
|
||||
if (StrUtil.isEmpty(content)) {
|
||||
return content;
|
||||
}
|
||||
@ -59,7 +62,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
// 读取内容,并过滤
|
||||
String content = IoUtil.readUtf8(super.getInputStream());
|
||||
content = filterHtml(content);
|
||||
content = filterXss(content);
|
||||
final ByteArrayInputStream newInputStream = new ByteArrayInputStream(content.getBytes());
|
||||
// 返回 ServletInputStream
|
||||
return new ServletInputStream() {
|
||||
@ -87,6 +90,47 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
// ========== Param 相关 ==========
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String value = super.getParameter(name);
|
||||
return filterXss(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] values = super.getParameterValues(name);
|
||||
if (ArrayUtil.isEmpty(values)) {
|
||||
return values;
|
||||
}
|
||||
// 过滤处理
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = filterXss(values[i]);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
Map<String, String[]> valueMap = super.getParameterMap();
|
||||
if (CollUtil.isEmpty(valueMap)) {
|
||||
return valueMap;
|
||||
}
|
||||
// 过滤处理
|
||||
for (Map.Entry<String, String[]> entry : valueMap.entrySet()) {
|
||||
String[] values = entry.getValue();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = filterXss(values[i]);
|
||||
}
|
||||
}
|
||||
return valueMap;
|
||||
}
|
||||
|
||||
// ========== Header 相关 ==========
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
String value = super.getHeader(name);
|
||||
return filterXss(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ apollo:
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||
exposure:
|
||||
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||
|
||||
@ -131,3 +132,8 @@ yudao:
|
||||
codegen:
|
||||
base-package: ${yudao.info.base-package}.modules
|
||||
db-schemas: ${spring.datasource.name}
|
||||
xss:
|
||||
enable: true
|
||||
exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
|
||||
- ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
|
||||
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
|
||||
|
@ -87,6 +87,7 @@ apollo:
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||
exposure:
|
||||
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||
|
||||
@ -131,3 +132,8 @@ yudao:
|
||||
codegen:
|
||||
base-package: ${yudao.info.base-package}.modules
|
||||
db-schemas: ${spring.datasource.name}
|
||||
xss:
|
||||
enable: true
|
||||
exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
|
||||
- ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
|
||||
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
|
||||
|
Loading…
Reference in New Issue
Block a user