yangbq 1 ヶ月 前
コミット
a8d8a2970b

+ 0 - 2
project-admin/src/main/java/com/project/ProjectServletInitializer.java

@@ -1,7 +1,5 @@
 package com.project;
 
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 

+ 1 - 1
project-common/src/main/java/com/project/common/constant/CacheConstants.java

@@ -9,7 +9,7 @@ public class CacheConstants {
     /**
      * 项目名
      */
-    public static final String PROJECT_NAME = "ruoyi-vue-service:";
+    public static final String PROJECT_NAME = "hq-service:";
     /**
      * 登录用户 redis key
      */

+ 1 - 3
project-common/src/main/java/com/project/common/core/redis/MyCache.java

@@ -1,12 +1,10 @@
 package com.project.common.core.redis;
 
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cache.Cache;
 import org.springframework.cache.support.SimpleValueWrapper;
 import org.springframework.stereotype.Component;
 
 import java.util.Collection;
-import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
@@ -14,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
 public class MyCache implements Cache {
 
     // 使用ConcurrentHashMap作为数据的存储
-    private Map<String, Object> storage = new ConcurrentHashMap<>();
+    private ConcurrentHashMap<String, Object> storage = new ConcurrentHashMap<>();
 
     // getName获取cache的名称,存取数据的时候用来区分是针对哪个cache操作
     @Override

+ 9 - 4
project-framework/src/main/java/com/project/framework/config/ResourcesConfig.java

@@ -3,6 +3,7 @@ package com.project.framework.config;
 import com.project.common.config.ProjectConfig;
 import com.project.common.constant.Constants;
 import com.project.framework.interceptor.AuthInterceptor;
+import com.project.framework.interceptor.LargeAuthInterceptor;
 import com.project.framework.interceptor.RepeatSubmitInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
@@ -28,6 +29,9 @@ public class ResourcesConfig implements WebMvcConfigurer {
     @Autowired
     private AuthInterceptor authInterceptor;
 
+    @Autowired
+    private LargeAuthInterceptor largeAuthInterceptor;
+
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
         /** 本地文件上传路径 */
@@ -45,7 +49,8 @@ public class ResourcesConfig implements WebMvcConfigurer {
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         // 重复提交拦截
-        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+        //registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+        registry.addInterceptor(largeAuthInterceptor).addPathPatterns("/large/**");
 
         // api同步接口拦截器
         registry.addInterceptor(authInterceptor).addPathPatterns("/synchronize/**");
@@ -61,11 +66,11 @@ public class ResourcesConfig implements WebMvcConfigurer {
         // 设置访问源地址
         config.addAllowedOriginPattern("*");
         // 设置访问源请求头
-        config.setAllowedHeaders(Arrays.asList("Authorization","X-Access-Token", "Content-Type"));
+        config.addAllowedHeader("*");
         // 设置访问源请求方法
-        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
+        config.addAllowedMethod("*");
         // 有效期 1800秒
-        config.setMaxAge(1800L);
+        config.setMaxAge(3600L);
         // 添加映射路径,拦截一切请求
         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
         source.registerCorsConfiguration("/**", config);

+ 39 - 43
project-framework/src/main/java/com/project/framework/config/SecurityConfig.java

@@ -5,22 +5,18 @@ import com.project.framework.security.filter.JwtAuthenticationTokenFilter;
 import com.project.framework.security.handle.AuthenticationEntryPointImpl;
 import com.project.framework.security.handle.LogoutSuccessHandlerImpl;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.ProviderManager;
 import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
-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.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 import org.springframework.security.web.authentication.logout.LogoutFilter;
 import org.springframework.web.filter.CorsFilter;
@@ -31,7 +27,8 @@ import org.springframework.web.filter.CorsFilter;
  * @author ruoyi
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+@Configuration
+public class SecurityConfig  {
     /**
      * 自定义用户认证逻辑
      */
@@ -75,9 +72,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
      * @throws Exception
      */
     @Bean
-    @Override
     public AuthenticationManager authenticationManagerBean() throws Exception {
-        return super.authenticationManagerBean();
+        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
+        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
+        daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
+        return new ProviderManager(daoAuthenticationProvider);
     }
 
     /**
@@ -95,42 +94,39 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
      * rememberMe          |   允许通过remember-me登录的用户访问
      * authenticated       |   用户登录后可访问
      */
-    @Override
-    protected void configure(HttpSecurity httpSecurity) throws Exception {
-        // 注解标记允许匿名访问的url
-        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
-        permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
-
-        httpSecurity
+    @Bean
+    protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
+        return httpSecurity
                 // CSRF禁用,因为不使用session
-                .csrf().disable()
+                .csrf(csrf -> csrf.disable())
+                // 禁用HTTP响应标头
+                .headers((headersCustomizer) -> {
+                    headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
+                })
                 // 认证失败处理类
-                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
+                .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
                 // 基于token,所以不需要session
-                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
-                // 过滤请求
-                .authorizeRequests()
+                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+                // 注解标记允许匿名访问的url
+                .authorizeHttpRequests((requests) -> {
+                    permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
+
+                    // 对于登录login 注册register 验证码captchaImage 允许匿名访问
+                    requests.antMatchers("/login", "/captchaImage","/synchronize/**","/large/**","/sxgw/**").permitAll()
+                            // 静态资源,可匿名访问
+                            .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
+                            // 除上面外的所有请求全部需要鉴权认证
+                            .anyRequest().authenticated();
+                })
+                // 添加Logout filter
+                .logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
+                // 添加JWT filter
+                .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
+                // 添加CORS filter
+                .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
+                .addFilterBefore(corsFilter, LogoutFilter.class)
+                .build();
 
-                // 授权大屏地址
-                .antMatchers("/synchronize/**").anonymous()
-                //.antMatchers("/xxl-job-admin/**").anonymous()
-                // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage").anonymous()
-                // 静态资源,可匿名访问
-                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
-                //.antMatchers( "/sxgw/**","/sxgw/**/**","/sxgw/**/**/**","/basics/**", "/basics/**/**", "/build/**", "/build/**/**","/employee/**", "/employee/**/**","/health/**", "/health/**/**","/post/**", "/post/**/**","/property/**", "/property/**/**","/smart/**", "/smart/**/**","/video/**", "/video/**/**").permitAll()
-                .antMatchers( "/webjars/**").permitAll()
-                // 除上面外的所有请求全部需要鉴权认证
-                .anyRequest().authenticated()
-                .and()
-                .headers().frameOptions().disable();
-        // 添加Logout filter
-        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
-        // 添加JWT filter
-        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
-        // 添加CORS filter
-        httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
-        httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
     }
 
     /**
@@ -144,8 +140,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
     /**
      * 身份认证接口
      */
-    @Override
+    /*@Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
-    }
+    }*/
 }

+ 0 - 2
project-framework/src/main/java/com/project/framework/interceptor/AuthInterceptor.java

@@ -28,7 +28,6 @@ public class AuthInterceptor implements HandlerInterceptor {
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         // 获取请求头中的token
         String token = request.getHeader(TOKEN_KEY);
-        System.out.println(token);
         // 简单的token验证逻辑
         if (StringUtils.isBlank(token)) {
             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
@@ -38,7 +37,6 @@ public class AuthInterceptor implements HandlerInterceptor {
         }
 
         String encrToken = AESUtil.decrypt(token);
-        System.out.println(encrToken);
         if ( !SECRET_KEY.equals(encrToken)) {
             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
             AjaxResult ajaxResult = AjaxResult.error("token传参异常!");

+ 76 - 0
project-framework/src/main/java/com/project/framework/interceptor/LargeAuthInterceptor.java

@@ -0,0 +1,76 @@
+package com.project.framework.interceptor;
+
+import com.alibaba.fastjson2.JSON;
+import com.project.common.constant.Constants;
+import com.project.common.core.domain.AjaxResult;
+import com.project.common.utils.AESUtil;
+import com.project.common.utils.ServletUtils;
+import com.project.common.utils.StringUtils;
+import com.project.framework.web.service.TokenService;
+import io.jsonwebtoken.Claims;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.annotation.Resource;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Objects;
+
+/**
+ * @Description
+ * @Author bqyang
+ * @Date 2025/3/6 13:59
+ * @Version 1.0
+ */
+@Component
+public class LargeAuthInterceptor implements HandlerInterceptor {
+
+    @Value("${token.header}")
+    private String header;
+    @Resource
+    private TokenService tokenService;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        // 获取请求头中的token
+        String token = getToken(request);
+        // 简单的token验证逻辑
+        if (StringUtils.isBlank(token)) {
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            AjaxResult ajaxResult = AjaxResult.error("token传参异常!");
+            ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
+            return false;
+        }
+
+        Claims claims = tokenService.parseToken(token);
+
+        if (Objects.isNull(claims)) {
+            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+            AjaxResult ajaxResult = AjaxResult.error("token传参异常!");
+            ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
+            return false;
+        }
+        return true;
+    }
+
+    private String getToken(HttpServletRequest request) {
+        String token = request.getHeader(header);
+        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
+            token = token.replace(Constants.TOKEN_PREFIX, "");
+        }
+
+        if (StringUtils.isBlank(token)) {
+            Cookie[] cookies = request.getCookies();
+            if (cookies != null) {
+                for (Cookie cookie : cookies) {
+                    if (header.equals(cookie.getName())) {
+                        return cookie.getValue();
+                    }
+                }
+            }
+        }
+        return token;
+    }
+}

+ 51 - 9
project-framework/src/main/java/com/project/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,6 +1,9 @@
 package com.project.framework.security.filter;
 
+import com.alibaba.fastjson2.JSONObject;
+import com.project.common.constant.Constants;
 import com.project.common.core.domain.model.LoginUser;
+import com.project.common.core.redis.RedisCache;
 import com.project.common.utils.SecurityUtils;
 import com.project.common.utils.StringUtils;
 import com.project.framework.web.service.TokenService;
@@ -8,6 +11,7 @@ import com.project.system.domain.SysOperLog;
 import com.project.system.service.ISysOperLogService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 import org.springframework.stereotype.Component;
@@ -15,11 +19,11 @@ import org.springframework.web.filter.OncePerRequestFilter;
 
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.util.Date;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * token过滤器 验证token有效性
@@ -33,13 +37,18 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
     @Autowired
     private ISysOperLogService sysOperLogService;
 
+    private String header = "SX-Access-Token";
+    @Autowired
+    private RedisCache redisCache;
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
             throws ServletException, IOException {
         LoginUser loginUser = tokenService.getLoginUser(request);
         // TODO 测试用是否携带token
-        //saveOperLog(request, loginUser);
-        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
+        Authentication authentication = SecurityUtils.getAuthentication();
+        saveOperLog(request, loginUser,authentication);
+        if (StringUtils.isNotNull(loginUser)) {
             tokenService.verifyToken(loginUser);
             UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
             authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
@@ -48,20 +57,53 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
         chain.doFilter(request, response);
     }
 
-    private void saveOperLog(HttpServletRequest request, LoginUser loginUser) {
+    private void saveOperLog(HttpServletRequest request, LoginUser loginUser,Authentication authentication) {
         String url = request.getRequestURI();
         SysOperLog operLog = new SysOperLog();
-        String token = request.getHeader("SX-Access-Token");
-        operLog.setTitle("token");
+        String token = getToken(request);
+        if (Objects.isNull(loginUser)) {
+            operLog.setTitle("token 用户为空");
+        } else {
+            operLog.setTitle("token"+ loginUser.getUsername());
+        }
+
         operLog.setBusinessType(0);
         operLog.setOperatorType(1);
-        if (Objects.nonNull(loginUser)){
-            operLog.setOperParam(loginUser.getUsername());
+        if (StringUtils.isNotBlank(token)){
+            operLog.setOperParam(header);
             operLog.setJsonResult(token);
+        } else {
+            Map<String, String> headers = new HashMap<>();
+            Enumeration<String> headerNames = request.getHeaderNames();
+            while (headerNames.hasMoreElements()) {
+                String headerName = headerNames.nextElement();
+                headers.put(headerName, request.getHeader(headerName));
+            }
+            operLog.setJsonResult(JSONObject.toJSONString(headers));
         }
+
         operLog.setStatus(0);
         operLog.setOperUrl(url);
         operLog.setOperTime(new Date());
         sysOperLogService.insertOperlog(operLog);
     }
+
+    private String getToken(HttpServletRequest request) {
+        String token = request.getHeader(header);
+        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
+            token = token.replace(Constants.TOKEN_PREFIX, "");
+        }
+
+        if (StringUtils.isBlank(token)) {
+            Cookie[] cookies = request.getCookies();
+            if (cookies != null) {
+                for (Cookie cookie : cookies) {
+                    if (header.equals(cookie.getName())) {
+                        return cookie.getValue();
+                    }
+                }
+            }
+        }
+        return token;
+    }
 }

+ 22 - 5
project-framework/src/main/java/com/project/framework/web/service/TokenService.java

@@ -19,6 +19,8 @@ import org.springframework.stereotype.Component;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -94,9 +96,15 @@ public class TokenService {
      * @return 令牌
      */
     public String createToken(LoginUser loginUser) {
-        String token = IdUtils.fastUUID();
-        loginUser.setToken(token);
-        setUserAgent(loginUser);
+        String token = "";
+        if (StringUtils.isBlank(loginUser.getToken())){
+            token = IdUtils.fastUUID();
+            loginUser.setToken(token);
+        } else {
+            token = loginUser.getToken();
+        }
+
+        //setUserAgent(loginUser);
         refreshToken(loginUser);
 
         Map<String, Object> claims = new HashMap<>();
@@ -165,8 +173,16 @@ public class TokenService {
      * @return 令牌
      */
     private String createToken(Map<String, Object> claims) {
+        Date now = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(now);
+        calendar.add(Calendar.DAY_OF_MONTH, 7);
+        Date expiryDate = calendar.getTime();
+
         String token = Jwts.builder()
                 .setClaims(claims)
+                .setIssuedAt(now)
+                .setExpiration(expiryDate)
                 .signWith(SignatureAlgorithm.HS512, secret).compact();
         return token;
     }
@@ -177,7 +193,7 @@ public class TokenService {
      * @param token 令牌
      * @return 数据声明
      */
-    private Claims parseToken(String token) {
+    public Claims parseToken(String token) {
         return Jwts.parser()
                 .setSigningKey(secret)
                 .parseClaimsJws(token)
@@ -212,7 +228,7 @@ public class TokenService {
             if (cookies != null) {
                 for (Cookie cookie : cookies) {
                     if (header.equals(cookie.getName())) {
-                        token = cookie.getValue();
+                        return cookie.getValue();
                     }
                 }
             }
@@ -223,4 +239,5 @@ public class TokenService {
     private String getTokenKey(String uuid) {
         return CacheConstants.LOGIN_TOKEN_KEY + uuid;
     }
+
 }

+ 2 - 1
project-zcustom/src/main/java/com/project/zcustom/controller/engineering/PlatProjectCheckController.java

@@ -117,7 +117,8 @@ public class PlatProjectCheckController extends BaseController {
                 return AjaxResult.error("文件上传失败");
             }
 
-            enclosureEmail(multipartFile, entity.getDescription() + "\n" + entity.getNeed());
+            // TODO 发生邮箱待调试
+            //enclosureEmail(multipartFile, entity.getDescription() + "\n" + entity.getNeed());
         }
         return toAjax(largeIssueService.save(entity));
     }

+ 1 - 1
project-zcustom/src/main/java/com/project/zcustom/service/service/employee/impl/PlatEmployeeTypeServiceImpl.java

@@ -285,7 +285,7 @@ public class PlatEmployeeTypeServiceImpl extends ServiceImpl<PlatEmployeeTypeMap
      */
     @Override
     public Map<String, Object> getChartsFlowData(String appOrg) {
-        List<String> nameList = Arrays.asList("内部人员", "借调人员", "外协", "物业","访客");
+        List<String> nameList = Arrays.asList("内部人员", "借调人员", "外协人员", "物业人员","访客");
         // 获取7天前的日期
         List<String> dateList = DateUtils.generateDateList(7);
         List<String> colorList = Arrays.asList("#0084ff", "#ffd296", "#7565ef", "#00ffff","#ffcd3e");