Browse Source

增加xss防护

xusl 1 year ago
parent
commit
6afde116a2
23 changed files with 1294 additions and 45 deletions
  1. 48 0
      backend/src/main/java/com/jiayue/ssi/SsiApplication.java
  2. 8 10
      backend/src/main/java/com/jiayue/ssi/config/WebSecurityConfig.java
  3. 29 2
      backend/src/main/java/com/jiayue/ssi/controller/ForecastPowerShortTermController.java
  4. 29 2
      backend/src/main/java/com/jiayue/ssi/controller/IpBlacklistController.java
  5. 29 2
      backend/src/main/java/com/jiayue/ssi/controller/NwpController.java
  6. 29 2
      backend/src/main/java/com/jiayue/ssi/controller/SysApproveController.java
  7. 29 2
      backend/src/main/java/com/jiayue/ssi/controller/SysLogininforController.java
  8. 28 2
      backend/src/main/java/com/jiayue/ssi/controller/SysOperlogController.java
  9. 28 2
      backend/src/main/java/com/jiayue/ssi/controller/SysParameterController.java
  10. 28 2
      backend/src/main/java/com/jiayue/ssi/controller/SysRoleController.java
  11. 29 2
      backend/src/main/java/com/jiayue/ssi/controller/SysUserController.java
  12. 40 0
      backend/src/main/java/com/jiayue/ssi/filter/XssEscapeFilter.java
  13. 99 0
      backend/src/main/java/com/jiayue/ssi/filter/XssKeywordsFilter.java
  14. 134 0
      backend/src/main/java/com/jiayue/ssi/servlet/XssEscapeHttpServletRequestWrapper.java
  15. 656 0
      backend/src/main/java/com/jiayue/ssi/servlet/XssKeywordsHttpServletRequestWrapper.java
  16. 10 0
      backend/src/main/java/com/jiayue/ssi/util/SecurityValidate.java
  17. 9 3
      backend/src/main/resources/application.yml
  18. 2 1
      backend/src/test/java/com/jiayue/ssi/JasyptStringEncryptorDemo.java
  19. 18 1
      ui/src/App.vue
  20. 1 1
      ui/src/permission.js
  21. 1 1
      ui/src/utils/auth.js
  22. 5 5
      ui/src/utils/request.js
  23. 5 5
      ui/src/views/sysManager/roleManager/index.vue

+ 48 - 0
backend/src/main/java/com/jiayue/ssi/SsiApplication.java

@@ -1,9 +1,17 @@
 package com.jiayue.ssi;
 
 import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
+import org.apache.tomcat.util.descriptor.web.SecurityCollection;
+import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
 
 /**
  * TODO
@@ -19,4 +27,44 @@ public class SsiApplication {
         SpringApplication.run(SsiApplication.class, args);
     }
 
+//    @Bean
+//    public ConfigurableServletWebServerFactory webServerFactory() {
+//        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
+//        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
+//            @Override
+//            public void customize(Connector connector) {
+//                connector.setProperty("relaxedQueryChars", "|{}[]");//允许的特殊字符
+//            }
+//        });
+//        return factory;
+//    }
+
+//    @Bean
+//    public TomcatServletWebServerFactory servletContainer() {
+//        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
+//            @Override
+//            protected void postProcessContext(Context context) {
+//                SecurityConstraint constraint = new SecurityConstraint();
+//                constraint.setUserConstraint("CONFIDENTIAL");
+//                SecurityCollection collection = new SecurityCollection();
+//                collection.addPattern("/*");
+//                constraint.addCollection(collection);
+//                context.addConstraint(constraint);
+//            }
+//        };
+//        tomcat.addAdditionalTomcatConnectors(httpConnector());
+//        return tomcat;
+//    }
+//
+//    @Bean
+//    public Connector httpConnector() {
+//        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
+//        connector.setScheme("http");
+//        //Connector监听的http的端口号
+//        connector.setPort(8887);
+//        connector.setSecure(false);
+//        //监听到http的端口号后转向到的https的端口号
+//        connector.setRedirectPort(8888);
+//        return connector;
+//    }
 }

+ 8 - 10
backend/src/main/java/com/jiayue/ssi/config/WebSecurityConfig.java

@@ -4,15 +4,10 @@ import com.jiayue.ssi.filter.*;
 import com.jiayue.ssi.handler.*;
 import com.jiayue.ssi.service.impl.UserServiceImpl;
 import com.jiayue.ssi.util.JwtTokenUtil;
-import org.apache.catalina.connector.Connector;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
-import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
-import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpMethod;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.builders.WebSecurity;
@@ -21,11 +16,9 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 import org.springframework.security.web.authentication.logout.LogoutFilter;
 import org.springframework.security.web.firewall.DefaultHttpFirewall;
 import org.springframework.security.web.firewall.HttpFirewall;
-import org.springframework.web.filter.CorsFilter;
 
 
 /**
@@ -51,6 +44,12 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     CustomLogoutSuccessHandler customLogoutSuccessHandler;
     @Autowired
     JwtTokenUtil jwtTokenUtil;
+    @Autowired
+    XssEscapeFilter xssEscapeFilter;
+    @Autowired
+    XssKeywordsFilter xssKeywordsFilter;
+    @Autowired
+    InterfaceLimitFilter interfaceLimitFilter;
 
     @Bean
     public MyAuthenticationProvider eacpsAuthenticationProvider(){
@@ -74,12 +73,11 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 //        auth.userDetailsService(userServiceImpl);
 //    }
 
-    @Autowired
-    InterfaceLimitFilter interfaceLimitFilter;
-
     @Override
     protected void configure(HttpSecurity httpSecurity) throws Exception {
         httpSecurity.addFilterBefore(interfaceLimitFilter, LogoutFilter.class);
+        httpSecurity.addFilterBefore(xssKeywordsFilter, LogoutFilter.class);
+        httpSecurity.addFilterBefore(xssEscapeFilter, LogoutFilter.class);
         httpSecurity.addFilterBefore(new VerifySmFilter(), LogoutFilter.class);
         httpSecurity.addFilterBefore(new VerifyCodeFilter(), LogoutFilter.class);
         httpSecurity.addFilterBefore(new MailCodeFilter(), LogoutFilter.class);

+ 29 - 2
backend/src/main/java/com/jiayue/ssi/controller/ForecastPowerShortTermController.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.controller;
 
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.constant.CustomException;
@@ -33,8 +34,34 @@ public class ForecastPowerShortTermController {
      * @return 用户信息
      */
     @GetMapping(value = "/getAll")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String startTime, String endTime) throws CustomException {
+    public ResponseVO getAll(String currentPage, String pageSize, String startTime, String endTime) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
+
             QueryWrapper<ForecastPowerShortTerm> wrapper = new QueryWrapper<>();
             if (StringUtils.isNotEmpty(startTime)) {
                 wrapper.ge("forecast_time", startTime);
@@ -43,7 +70,7 @@ public class ForecastPowerShortTermController {
                 wrapper.le("forecast_time", endTime);
             }
             wrapper.orderByAsc("forecast_time");
-            Page<ForecastPowerShortTerm> result = forecastPowerShortTermService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<ForecastPowerShortTerm> result = forecastPowerShortTermService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取短期列表异常", e);

+ 29 - 2
backend/src/main/java/com/jiayue/ssi/controller/IpBlacklistController.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.controller;
 
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.annotation.OperateLog;
@@ -38,8 +39,34 @@ public class IpBlacklistController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('system:ipblacklist:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String ip) throws CustomException {
+    public ResponseVO getAll(String currentPage, String pageSize, String ip) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
+
             QueryWrapper<SysBlacklist> wrapper = new QueryWrapper<>();
             if (StringUtils.isNotEmpty(ip)) {
                 if (!IPUtils.isIP(ip)) {
@@ -47,7 +74,7 @@ public class IpBlacklistController {
                 }
                 wrapper.eq("ip", ip);
             }
-            Page<SysBlacklist> result = sysBlacklistService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysBlacklist> result = sysBlacklistService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取ip列表异常", e);

+ 29 - 2
backend/src/main/java/com/jiayue/ssi/controller/NwpController.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.controller;
 
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.constant.CustomException;
@@ -37,8 +38,34 @@ public class NwpController {
      * @return 用户信息
      */
     @GetMapping(value = "/getAll")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String startTime, String endTime) throws CustomException {
+    public ResponseVO getAll(String currentPage, String pageSize, String startTime, String endTime) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
+
             QueryWrapper<Nwp> wrapper = new QueryWrapper<>();
             if (StringUtils.isNotEmpty(startTime)) {
                 wrapper.ge("pre_time", startTime);
@@ -47,7 +74,7 @@ public class NwpController {
                 wrapper.le("pre_time", endTime);
             }
             wrapper.orderByAsc("pre_time");
-            Page<Nwp> result = nwpService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<Nwp> result = nwpService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取NWP列表异常", e);

+ 29 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysApproveController.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.controller;
 
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -44,8 +45,34 @@ public class SysApproveController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('approveManager:approve:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String approveStatus, String approveResult) throws CustomException {
+    public ResponseVO getAll(String currentPage, String pageSize, String approveStatus, String approveResult) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
+
             QueryWrapper<SysApprove> wrapper = new QueryWrapper<>();
             if (StringUtils.isNotEmpty(approveStatus)) {
                 wrapper.eq("approve_status", approveStatus);
@@ -53,7 +80,7 @@ public class SysApproveController {
             if (StringUtils.isNotEmpty(approveResult)) {
                 wrapper.eq("approve_result", approveResult);
             }
-            Page<SysApprove> result = sysApproveService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysApprove> result = sysApproveService.page(new Page<>(cp, ps), wrapper);
             List<SysApprove> records = result.getRecords();
             //遍历对象数组的方法
             records.forEach(

+ 29 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysLogininforController.java

@@ -1,6 +1,7 @@
 package com.jiayue.ssi.controller;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.annotation.OperateLog;
@@ -39,9 +40,35 @@ public class SysLogininforController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('auditManager:logininfor:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String ipaddr, String userName,
+    public ResponseVO getAll(String currentPage, String pageSize, String ipaddr, String userName,
                              String status, String startLoginTime, String endLoginTime, String sortOrder) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
+
             if (StringUtils.isNotEmpty(ipaddr)) {
                 if (ipaddr.length() > 128) {
                     return ResponseVO.fail("登录地址长度不能超过128个字符!");
@@ -85,7 +112,7 @@ public class SysLogininforController {
                 }
             }
 
-            Page<SysLogininfor> result = sysLogininforService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysLogininfor> result = sysLogininforService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取登录日志列表异常", e);

+ 28 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysOperlogController.java

@@ -1,6 +1,7 @@
 package com.jiayue.ssi.controller;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.annotation.OperateLog;
@@ -75,9 +76,34 @@ public class SysOperlogController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('auditManager:operlog:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String title, String operName, String auditType,
+    public ResponseVO getAll(String currentPage, String pageSize, String title, String operName, String auditType,
                              String businessType, String status, String startOperTime, String endOperTime, String sortOrder) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
             if (StringUtils.isNotEmpty(title)) {
                 if (title.length() > 50) {
                     return ResponseVO.fail("系统模块长度不能超过50个字符!");
@@ -133,7 +159,7 @@ public class SysOperlogController {
                 wrapper.eq("audit_type", "1");
             }
 
-            Page<SysOperLog> result = sysOperLogService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysOperLog> result = sysOperLogService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取操作日志列表异常", e);

+ 28 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysParameterController.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.controller;
 
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.annotation.InterfaceLimit;
@@ -162,8 +163,33 @@ public class SysParameterController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('system:config:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String keywords) throws CustomException {
+    public ResponseVO getAll(String currentPage, String pageSize, String keywords) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
             if (StringUtils.isNotEmpty(keywords)) {
                 if (keywords.length() > 200) {
                     return ResponseVO.fail("参数描述长度不能超过200个字符!");
@@ -173,7 +199,7 @@ public class SysParameterController {
             if (StringUtils.isNotEmpty(keywords)) {
                 wrapper.like("sys_describe", keywords);
             }
-            Page<SysParameter> result = sysParameterService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysParameter> result = sysParameterService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取参数异常", e);

+ 28 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysRoleController.java

@@ -1,6 +1,7 @@
 package com.jiayue.ssi.controller;
 
 import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.NumberUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jiayue.ssi.annotation.InterfaceLimit;
@@ -47,8 +48,33 @@ public class SysRoleController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('system:role:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String roleName, String status, String roleKey) throws CustomException {
+    public ResponseVO getAll(String currentPage, String pageSize, String roleName, String status, String roleKey) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
             if (StringUtils.isNotEmpty(roleName)) {
                 if (roleName.length() > 15) {
                     return ResponseVO.fail("角色名称不能超过15个字符!");
@@ -70,7 +96,7 @@ public class SysRoleController {
                 wrapper.like("role_key", roleKey);
             }
             wrapper.orderByAsc("role_sort");
-            Page<SysRole> result = roleService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysRole> result = roleService.page(new Page<>(cp, ps), wrapper);
             return ResponseVO.success(result);
         } catch (Exception e) {
             throw new CustomException("获取角色列表异常", e);

+ 29 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysUserController.java

@@ -1,6 +1,7 @@
 package com.jiayue.ssi.controller;
 
 import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.crypto.SmUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -63,9 +64,35 @@ public class SysUserController {
      */
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('system:user:list')")
-    public ResponseVO getAll(Integer currentPage, Integer pageSize, String username, String phonenumber,
+    public ResponseVO getAll(String currentPage, String pageSize, String username, String phonenumber,
                              String status) throws CustomException {
         try {
+            Integer cp;
+            if (StringUtils.isNotEmpty(currentPage)) {
+                if (NumberUtil.isInteger(currentPage)){
+                    cp = Integer.parseInt(currentPage);
+                }
+                else{
+                    return ResponseVO.fail("currentPage不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("currentPage不能是空!");
+            }
+
+            Integer ps;
+            if (StringUtils.isNotEmpty(pageSize)) {
+                if (NumberUtil.isInteger(pageSize)){
+                    ps = Integer.parseInt(pageSize);
+                }
+                else{
+                    return ResponseVO.fail("pageSize不是整数!");
+                }
+            }
+            else{
+                return ResponseVO.fail("pageSize不能是空!");
+            }
+
             if (StringUtils.isNotEmpty(username)) {
                 if (username.length() > 20) {
                     return ResponseVO.fail("用户账号长度不能超过20个字符!");
@@ -93,7 +120,7 @@ public class SysUserController {
                 wrapper.eq("usertype", "1");
             }
 
-            Page<SysUser> result = sysUserService.page(new Page<>(currentPage, pageSize), wrapper);
+            Page<SysUser> result = sysUserService.page(new Page<>(cp, ps), wrapper);
             List<SysUser> records = result.getRecords();
             //遍历对象数组的方法
             records.forEach(

+ 40 - 0
backend/src/main/java/com/jiayue/ssi/filter/XssEscapeFilter.java

@@ -0,0 +1,40 @@
+package com.jiayue.ssi.filter;
+/**
+ * @author xsl
+ * @since 2023/05/17
+ */
+
+import com.jiayue.ssi.servlet.XssEscapeHttpServletRequestWrapper;
+import com.jiayue.ssi.util.IPUtils;
+import com.jiayue.ssi.util.ResponseInfo;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+//拦截请求
+@RequiredArgsConstructor
+@Order(3)
+@Slf4j
+@Component
+public class XssEscapeFilter extends OncePerRequestFilter {
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
+        try {
+            //先进行转义在把请求返回
+            XssEscapeHttpServletRequestWrapper wrapper = new XssEscapeHttpServletRequestWrapper(request);
+            filterChain.doFilter(wrapper, response);
+        } catch (Exception e) {
+            log.error(IPUtils.getIpAddr(request) + "访问系统失败", e);
+            ResponseInfo.doResponse(response, "访问失败,联系管理员!", 401);
+            return;
+        }
+    }
+}
+

+ 99 - 0
backend/src/main/java/com/jiayue/ssi/filter/XssKeywordsFilter.java

@@ -0,0 +1,99 @@
+package com.jiayue.ssi.filter;
+
+
+import com.jiayue.ssi.servlet.XssKeywordsHttpServletRequestWrapper;
+import com.jiayue.ssi.util.ResponseInfo;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+/**
+ * xss和sql过滤器
+ *
+ * @author xsl
+ * @since 2023/05/16
+ */
+@RequiredArgsConstructor
+@Order(2)
+@Slf4j
+@Component
+public class XssKeywordsFilter extends OncePerRequestFilter {
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
+        try {
+            //跨域设置
+//        if(servletResponse instanceof HttpServletResponse){
+//            HttpServletResponse httpServletResponse=(HttpServletResponse)servletResponse;
+//            //通过在响应 header 中设置 ‘*’ 来允许来自所有域的跨域请求访问。
+//            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
+//            //通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie
+//            //设置了Allow-Credentials,Allow-Origin就不能为*,需要指明具体的url域
+//            //httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
+//            //请求方式
+//            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
+//            //(预检请求)的返回结果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 可以被缓存多久
+//            httpServletResponse.setHeader("Access-Control-Max-Age", "86400");
+//            //首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段
+//            httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
+//        }
+
+            XssKeywordsHttpServletRequestWrapper xssRequest = new XssKeywordsHttpServletRequestWrapper(request);
+//            String method = request.getMethod();
+//
+//            String param = "";
+
+//            if ("POST".equalsIgnoreCase(method)) {
+//                param = this.getBodyString(xssRequest.getReader());
+//                if (StringUtils.isNotBlank(param)) {
+//                    if (xssRequest.checkXSSAndSql(param)) {
+//                        ResponseInfo.doResponse(response, "您所访问的页面请求中有违反安全规则元素存在,拒绝访问!", 410);
+//                        return;
+//                    }
+//                }
+//            }
+
+            if (xssRequest.checkParameter()) {
+                ResponseInfo.doResponse(response, "您所访问的页面请求中有违反安全规则元素存在,拒绝访问!", 410);
+                return;
+            }
+
+            filterChain.doFilter(xssRequest, response);
+        } catch (Exception e) {
+//            log.error(IPUtils.getIpAddr(request) + "访问系统失败", e);
+            ResponseInfo.doResponse(response, "访问失败,联系管理员!", 401);
+            return;
+        }
+
+    }
+
+
+    // 获取request请求body中参数
+    public String getBodyString(BufferedReader br) {
+        String inputLine;
+        String str = "";
+        try {
+            while ((inputLine = br.readLine()) != null) {
+                str += inputLine;
+            }
+            br.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return str;
+
+    }
+
+
+    @Override
+    public void destroy() {
+
+    }
+}

+ 134 - 0
backend/src/main/java/com/jiayue/ssi/servlet/XssEscapeHttpServletRequestWrapper.java

@@ -0,0 +1,134 @@
+package com.jiayue.ssi.servlet;
+/**
+*
+*
+* @author xsl
+* @since 2023/05/17
+*/
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HtmlUtil;
+import cn.hutool.json.JSONUtil;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.LinkedHashMap;
+import java.util.Map;
+//思路是使用 HttpServletRequestWrapper 实现后端
+public class XssEscapeHttpServletRequestWrapper extends HttpServletRequestWrapper {
+    public XssEscapeHttpServletRequestWrapper(HttpServletRequest request) {
+        super(request);
+    }
+    //提取请求参数
+    @Override
+    public String getParameter(String name) {
+        String value= super.getParameter(name);
+        if(!StrUtil.hasEmpty(value)){
+            value=HtmlUtil.filter(value);
+        }
+        return value;
+    }
+
+    @Override
+    public String[] getParameterValues(String name) {
+        String[] values= super.getParameterValues(name);
+        if(values!=null){
+            for (int i=0;i<values.length;i++){
+                String value=values[i];
+                if(!StrUtil.hasEmpty(value)){
+                    value=HtmlUtil.filter(value);
+                }
+                values[i]=value;
+            }
+        }
+        return values;
+    }
+
+    //转义数据
+    @Override
+    public Map<String, String[]> getParameterMap() {
+        Map<String, String[]> parameters = super.getParameterMap();
+        LinkedHashMap<String, String[]> map=new LinkedHashMap();
+        if(parameters!=null){
+            for (String key:parameters.keySet()){
+                String[] values=parameters.get(key);
+                for (int i = 0; i < values.length; i++) {
+                    String value = values[i];
+                    if (!StrUtil.hasEmpty(value)) {
+                        //导入Hutool的依赖,进行html转义
+                        value = HtmlUtil.filter(value);
+                    }
+                    values[i] = value;
+                }
+                map.put(key,values);
+            }
+        }
+        return map;
+    }
+
+    @Override
+    public String getHeader(String name) {
+        String value= super.getHeader(name);
+        if (!StrUtil.hasEmpty(value)) {
+            value = HtmlUtil.filter(value);
+        }
+        return value;
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        InputStream in= super.getInputStream();
+        //指定字符集编码
+        InputStreamReader reader=new InputStreamReader(in, Charset.forName("UTF-8"));
+        BufferedReader buffer=new BufferedReader(reader);
+        StringBuffer body=new StringBuffer();
+        String line=buffer.readLine();
+        while(line!=null){
+            body.append(line);
+            line=buffer.readLine();
+        }
+        buffer.close();
+        reader.close();
+        in.close();
+        Map<String,Object> map=JSONUtil.parseObj(body.toString());
+        Map<String,Object> result=new LinkedHashMap<>();
+        for(String key:map.keySet()){
+            Object val=map.get(key);
+            if(val instanceof String){
+                if(!StrUtil.hasEmpty(val.toString())){
+                    result.put(key,HtmlUtil.filter(val.toString()));
+                }
+            }
+            else {
+                result.put(key,val);
+            }
+        }
+        String json=JSONUtil.toJsonStr(result);
+        ByteArrayInputStream bain=new ByteArrayInputStream(json.getBytes());
+        //匿名类实现IO流
+        return new ServletInputStream() {
+            @Override
+            public int read() throws IOException {
+                return bain.read();
+            }
+
+            @Override
+            public boolean isFinished() {
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener) {
+
+            }
+        };
+    }
+}

+ 656 - 0
backend/src/main/java/com/jiayue/ssi/servlet/XssKeywordsHttpServletRequestWrapper.java

@@ -0,0 +1,656 @@
+package com.jiayue.ssi.servlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StreamUtils;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * @author code
+ * @version 1.0
+ * @Date 2023/2/7 10:38
+ * @Description ${DESCRIPTION}
+ */
+public class XssKeywordsHttpServletRequestWrapper extends HttpServletRequestWrapper {
+
+    private final Logger logger = LoggerFactory.getLogger(XssKeywordsHttpServletRequestWrapper.class);
+
+    private String key = "and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+";
+    private Set<String> notAllowedKeyWords = new HashSet<String>(0);
+
+    HttpServletRequest orgRequest = null;
+    private Map<String, String[]> parameterMap;
+    private final byte[] body; //用于保存读取body中数据
+
+    public XssKeywordsHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
+        super(request);
+        orgRequest = request;
+        parameterMap = request.getParameterMap();
+        body = StreamUtils.copyToByteArray(request.getInputStream());
+
+        String keyStr[] = key.split("\\|");
+        for (String str : keyStr) {
+            notAllowedKeyWords.add(str);
+        }
+
+    }
+
+    // 重写几个HttpServletRequestWrapper中的方法
+    /**
+     * 获取所有参数名
+     *
+     * @return 返回所有参数名
+     */
+    @Override
+    public Enumeration<String> getParameterNames() {
+        Vector<String> vector = new Vector<String>(parameterMap.keySet());
+        return vector.elements();
+    }
+
+    /**
+     * 覆盖getParameter方法,将参数名和参数值都做xss &amp; sql过滤。<br>
+     * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br>
+     * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
+     */
+    @Override
+    public String getParameter(String name) {
+        String[] results = parameterMap.get(name);
+        if (results == null || results.length == 0) {
+            return null;
+        }else {
+            String value = results[0];
+            if (value != null) {
+                value = xssEncode(value);
+            }
+            return value;
+        }
+    }
+
+    @Override
+    public Map<String, String[]> getParameterMap() {
+        Map<String,String[]> values = super.getParameterMap();
+        if(null == values){
+            return null;
+        }
+        Map<String,String[]> result = new HashMap<>();
+        for (String key : values.keySet()) {
+            String encodedKey = xssEncode(key);
+            int count = values.get(key).length;
+            String[] encodedValues = new String[count];
+            for(int i = 0;i < count;i++){
+                encodedValues[i] = xssEncode(values.get(key)[i]);
+            }
+            result.put(encodedKey,encodedValues);
+        }
+        return result;
+    }
+
+    /**
+     * 获取指定参数名的所有值的数组,如:checkbox的所有数据 接收数组变量 ,如checkobx类型
+     */
+    @Override
+    public String[] getParameterValues(String name) {
+        String[] results = parameterMap.get(name);
+        if (results == null || results.length == 0) {
+            return null;
+        }else {
+            int length = results.length;
+            for (int i = 0; i < length; i++) {
+                results[i] = xssEncode(results[i]);
+            }
+            return results;
+        }
+    }
+
+    /**
+     * 覆盖getHeader方法,将参数名和参数值都做xss &amp; sql过滤。<br>
+     * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br>
+     * getHeaderNames 也可能需要覆盖
+     */
+    @Override
+    public String getHeader(String name) {
+
+        String value = super.getHeader(xssEncode(name));
+        if (value != null) {
+            value = xssEncode(value);
+        }
+        return value;
+    }
+
+    /**
+     * 将容易引起xss &amp; sql漏洞的半角字符直接替换成全角字符
+     *
+     * @param s
+     * @return
+     */
+    private String xssEncode(String s) {
+        if (s == null || s.isEmpty()) {
+            return s;
+        } else {
+            s = stripXSSAndSql(s);
+        }
+        StringBuilder sb = new StringBuilder(s.length() + 16);
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '>':
+                    sb.append(">");// 转义大于号
+                    break;
+                case '<':
+                    sb.append("<");// 转义小于号
+                    break;
+                case '\'':
+                    sb.append("'");// 转义单引号
+                    break;
+                case '\"':
+                    sb.append(""");// 转义双引号
+                    break;
+                case '&':
+                    sb.append("&");// 转义&
+                    break;
+                case '#':
+                    sb.append("#");// 转义#
+                    break;
+                default:
+                    sb.append(c);
+                    break;
+            }
+        }
+
+
+        return sb.toString();
+    }
+
+    /**
+     * 获取最原始的request
+     *
+     * @return
+     */
+    public HttpServletRequest getOrgRequest() {
+        return orgRequest;
+    }
+
+    /**
+     * 获取最原始的request的静态方法
+     *
+     * @return
+     */
+    @SuppressWarnings("unused")
+    public HttpServletRequest getOrgRequest(HttpServletRequest req) {
+        if (req instanceof XssKeywordsHttpServletRequestWrapper) {
+            return ((XssKeywordsHttpServletRequestWrapper) req).getOrgRequest();
+        }
+
+        return req;
+    }
+
+    /**
+     *
+     * 防止xss跨脚本攻击(替换,根据实际情况调整)
+     */
+
+    public String stripXSSAndSql(String value) {
+        if (value != null) {
+            // NOTE: It's highly recommended to use the ESAPI library and
+            // uncomment the following line to
+            // avoid encoded attacks.
+            // value = ESAPI.encoder().canonicalize(value);
+            // Avoid null characters
+            /** value = value.replaceAll("", ""); ***/
+            // Avoid anything between script tags
+            Pattern scriptPattern = Pattern.compile(
+                    "&lt;[\r\n| | ]*script[\r\n| | ]*&gt;(.*?)<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Avoid anything in a
+            // src="http://www.yihaomen.com/article/java/..." type of
+            // e-xpression
+            scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Remove any lonesome  tag
+            scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Remove any lonesome <script ...> tag
+            scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Avoid eval(...) expressions
+            scriptPattern = Pattern.compile("eval\\((.*?)\\)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Avoid e-xpression(...) expressions
+            scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Avoid javascript:... expressions
+            scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Avoid vbscript:... expressions
+            scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
+            value = scriptPattern.matcher(value).replaceAll("");
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onload(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+
+            scriptPattern = Pattern.compile("onerror(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+
+            scriptPattern = Pattern.compile("onmouse(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+
+            scriptPattern = Pattern.compile("scr*ipt(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+
+            scriptPattern = Pattern.compile("%3b(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            value = scriptPattern.matcher(value).replaceAll("");
+        }
+        return value;
+    }
+
+    public boolean checkXSSAndSql(String value) {
+        boolean flag = false;
+        if (value != null) {
+            Pattern scriptPattern = Pattern.compile(
+                    "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile(
+                    "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("scr*ipt(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("eval\\((.*?)\\)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            // Avoid e-xpression(...) expressions
+            scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            // Avoid javascript:... expressions
+            scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            // Avoid vbscript:... expressions
+            scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onload(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onerror(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onmouse(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<(.*?)img(.*?)src=(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("</STYLE>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("</scr(.*?)ipt>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("alert(.*?);|console(.*?);|confirm(.*?);|prompt(.*?);",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            flag = checkSqlKeyWords(value);
+        }
+        return flag;
+    }
+
+    public boolean checkSqlKeyWords(String value){
+        String paramValue = value;
+        for (String keyword : notAllowedKeyWords) {
+            if (paramValue.length() > keyword.length() + 4
+                    && (paramValue.contains(" "+keyword)||paramValue.contains(keyword+" ")||paramValue.contains(" "+keyword+" "))) {
+
+                logger.error(this.getRequestURI()+ "参数中包含不允许sql的关键词(" + keyword
+                        + ")");
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public final boolean checkParameter() {
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        Map<String, String[]> submitParams = new HashMap(parameterMap);
+
+        Set<String> submitNames = submitParams.keySet();
+        for (String submitName : submitNames) {
+            Object submitValues = submitParams.get(submitName);
+            if ((submitValues instanceof String)) {
+                if (checkXSSAndSql((String) submitValues)) {
+                    return true;
+                }
+            } else if ((submitValues instanceof String[])) {
+                for (String submitValue : (String[])submitValues){
+                    if (checkXSSAndSql(submitValue)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream() {
+
+            @Override
+            public int read() throws IOException {
+                return bais.read();
+            }
+
+            @Override
+            public boolean isFinished() {
+                // TODO Auto-generated method stub
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                // TODO Auto-generated method stub
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener arg0) {
+                // TODO Auto-generated method stub
+
+            }
+        };
+    }
+
+    public static boolean testxss(String value) {
+        boolean flag = false;
+        if (value != null) {
+            Pattern scriptPattern = Pattern.compile(
+                    "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile(
+                    "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("scr*ipt(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("eval\\((.*?)\\)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            // Avoid e-xpression(...) expressions
+            scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            // Avoid javascript:... expressions
+            scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            // Avoid vbscript:... expressions
+            scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onload(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onerror(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            // Avoid οnlοad= expressions
+            scriptPattern = Pattern.compile("onmouse(.*?)=",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("<(.*?)img(.*?)src=(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("</STYLE>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+            scriptPattern = Pattern.compile("</scr(.*?)ipt>", Pattern.CASE_INSENSITIVE);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+
+            scriptPattern = Pattern.compile("%3b(.*?)",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+            flag = scriptPattern.matcher(value).find();
+            if (flag) {
+                return flag;
+            }
+        }
+        return flag;
+    }
+
+    public static void main(String[] args) throws Exception{
+        String str = "console.log(299792458)%3b";
+        if (str.indexOf("%3b")>0){
+            System.out.println("====");
+
+        }
+        System.out.println(XssKeywordsHttpServletRequestWrapper.testxss(str));
+    }
+}
+

+ 10 - 0
backend/src/main/java/com/jiayue/ssi/util/SecurityValidate.java

@@ -0,0 +1,10 @@
+package com.jiayue.ssi.util;
+/**
+* sql注入,路径操作,http响应拦截,日志伪造验证类
+*
+* @author xsl
+* @since 2023/05/12
+*/
+public class SecurityValidate {
+
+}

+ 9 - 3
backend/src/main/resources/application.yml

@@ -4,8 +4,12 @@ server:
     key-store: classpath:9564748_api.jiayuepowertech.com.pfx
     key-store-type: PKCS12
     key-store-password: ENC(6daOBtvpihAkIU2Kh8iRK3KqYgI4E0/s)
-#  tomcat:
-#    max-connections: 1000
+    enabled-protocols: "TLSv1.2"
+    ciphers: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA"
+  tomcat:
+    max-connections: 50
+    max-threads: 30
+    accept-count: 5
 
 logging:
   config: classpath:logback-ssi.xml
@@ -16,9 +20,11 @@ spring:
     name: ssq-mybatis-plus
   #配置数据库
   datasource:
+    druid:
+      stat-view-servlet.enabled: false
     driver-class-name: com.mysql.cj.jdbc.Driver
     type: com.alibaba.druid.pool.DruidDataSource
-    url: ENC(QXx1EZuk8U3oLrOT3z852/12vlm8mMS9T3KJFM1kp2X/mAk1aqT+IbxsYjWB2zKQmdlEL5/gYdsKnl8vKwIuEd/jBMuY+Iy2hd7YE3ugmvDiW+NCYqy3Q5X+fq6pP7xkGsHW4mS9KQ1E6YwANjofjujAtL6xOQeaxDl7HA1oS+vaUkWvftdkZEnHPOJJAaPonfMq+2u9HzB+jNVUBYclmo2ztStt24nV9slX46jn5xJ1EAiC5WfUnJ8kEfQenuzY)
+    url: ENC(ZgtAyohxxJKcsLx2JdcHWZtKlrdbU1idypY/AclaZS4G99NhJZoa64l+I4lMfVnoDurg1g3Vs2Rs/PIJMe/CoBA+94sBgRXoWxPn/jo0hD59QXXrJmXbzI/oRuITNKpXBUR1nVTDLTRBNxfArynX40UPVrAlefi5ckgWHQkUh1qFp5l+QRUV05BCMaRoCBPTxg+pDXgh2AWkCZU+k0kcmkG8zty1AMSnRl8xom6YbHk9ryejmByW7g==)
     username: ENC(UN5TVXHQJt2DbXQiX/GRsw==)
     password: ENC(r9wV3VlMJEcxqJ6hYeG7BLRdUMXsPQHQ)
 

+ 2 - 1
backend/src/test/java/com/jiayue/ssi/JasyptStringEncryptorDemo.java

@@ -17,7 +17,8 @@ public class JasyptStringEncryptorDemo {
         System.out.println("keyStorePassword===>"+keyStorePassword);
         // mysql:url
         System.out.println("==========mysql配置==========");
-        String mysqlURL = textEncryptor.encrypt("jdbc:mysql://192.168.1.205:3306/ssi?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai");
+        String mysqlURL = textEncryptor.encrypt("jdbc:mysql://localhost:3307/ssi?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai");
+//        String mysqlURL = textEncryptor.encrypt("jdbc:mysql://192.168.1.208:3308/ssi?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai&useSSL=true&verifyServerCertificate=true&requireSSL=true&clientCertificateKeyStoreUrl=classpath:mysql_ssl/mysql-keystore&clientCertificateKeyStorePassword=jieyue6677*&trustCertificateKeyStoreUrl=classpath:mysql_ssl/mysql-truststore&trustCertificateKeyStorePassword=jieyue6677*");
         System.out.println("mysqlURL===>"+mysqlURL);
         String mysqlUserName = textEncryptor.encrypt("root");
         System.out.println("mysqlUserName===>"+mysqlUserName);

+ 18 - 1
ui/src/App.vue

@@ -2,10 +2,27 @@
   <div id="app">
     <router-view />
   </div>
+
 </template>
 
 <script>
 export default {
-  name: 'App'
+  name: 'App',
+  mounted(){
+    // 禁用鼠标右键
+    document.getElementById("app").oncontextmenu = function (e){
+      return false;
+    };
+    // this.$nextTick(()=>{
+    //   document.onkeydown = function (e){
+    //     if (e && e.keyCode === 123){
+    //       e.returnValue = false;
+    //       return false;
+    //     }
+    //
+    //   }
+    //
+    // })
+  }
 }
 </script>

+ 1 - 1
ui/src/permission.js

@@ -16,7 +16,7 @@ router.beforeEach(async (to, from, next) => {
   NProgress.start()
   // set page title
   document.title = getPageTitle(to.meta.title)
-  if (sessionStorage.getItem('token')) {
+  if (sessionStorage.getItem('jy')) {
     if (to.path === '/login') {
       // if is logged in, redirect to the home page
       next({ path: '/dashboard' })

+ 1 - 1
ui/src/utils/auth.js

@@ -13,7 +13,7 @@ export function setToken(token) {
 }
 
 export function removeToken() {
-  sessionStorage.removeItem('token')
+  sessionStorage.removeItem('jy')
   sessionStorage.removeItem('active')
   store.dispatch('tagsView/delAllCachedViews')
   store.dispatch('tagsView/delAllVisitedViews')

+ 5 - 5
ui/src/utils/request.js

@@ -55,11 +55,11 @@ service.interceptors.request.use(
       }
     }
 
-    if (sessionStorage.getItem("token")!=="undefined" && sessionStorage.getItem("token")!==undefined && sessionStorage.getItem("token")!=null) { // 判断是否存在token,如果存在的话,则每个http header都加上token
-      let tokenStr = sessionStorage.getItem("token")
+    if (sessionStorage.getItem("jy")!=="undefined" && sessionStorage.getItem("jy")!==undefined && sessionStorage.getItem("jy")!=null) { // 判断是否存在token,如果存在的话,则每个http header都加上token
+      let tokenStr = sessionStorage.getItem("jy")
 
       config.headers['Authorization'] = tokenStr.split("&")[0]
-      config.headers['TokenSign'] = tokenStr.split("&")[1]
+      config.headers['JySign'] = tokenStr.split("&")[1]
       // console.log('Authorization='+tokenStr)
       // console.log('TokenSign='+config.headers['TokenSign'])
     }
@@ -181,7 +181,7 @@ service.interceptors.response.use(
               // 替换token
               let tokenStr = doEncrypt(res.data)
               let sign = doSign(res.data)
-              sessionStorage.setItem('token', tokenStr+'&'+sign)
+              sessionStorage.setItem('jy', tokenStr+'&'+sign)
               // Vue.prototype.$axios(error.response.config)
               // 重新请求接口 前过期的接口
               error.config.headers.Authorization = res.data;
@@ -205,7 +205,7 @@ service.interceptors.response.use(
             // 正在刷新token ,把后来的接口缓冲起来
             return new Promise((resolve) => {
               requests.push(() => {
-                error.config.headers.Authorization = sessionStorage.getItem('token');
+                error.config.headers.Authorization = sessionStorage.getItem('jy');
                 resolve(Vue.prototype.$axios.request(error.config));
               });
             })

+ 5 - 5
ui/src/views/sysManager/roleManager/index.vue

@@ -541,8 +541,8 @@ export default {
         return
       }
 
-      if (_selectData.roleKey == 'system' || _selectData.roleKey == 'audit') {
-        this.edit = true;
+      if (_selectData.roleKey == 'xtgly' || _selectData.roleKey == 'sjgly') {
+        this.edit=true;
       }
 
       const roleId = _selectData.roleId
@@ -583,12 +583,12 @@ export default {
     submitForm: debounce(function () {
       this.$refs["form"].validate(valid => {
         if (valid) {
-          if (this.form.roleKey.trim() == 'system' || this.form.roleKey.trim() == 'audit') {
+          if (this.form.roleKey.trim() == 'xtgly' || this.form.roleKey.trim() == 'sjgly') {
             if (this.form.builtIn != '0') {
               // 不是内置用户则拦截
               this.$message({
                 type: 'warning',
-                message: '字符标识不能是system或audit!'
+                message: '字符标识不能是xtgly或sjgly!'
               });
               return
             }
@@ -655,7 +655,7 @@ export default {
         return
       }
 
-      if (_selectData.roleKey == 'system' || _selectData.roleKey == 'audit') {
+      if (_selectData.roleKey == 'xtgly' || _selectData.roleKey == 'sjgly') {
         this.$message({
           type: 'warning',
           message: '内置角色不能删除!'