Browse Source

change:
1. 添加自动刷新登陆状态功能
fix:
1. 修复修改用户密码接口
2. userHeader获取显示状态

kindring 2 years ago
parent
commit
a9342a0697

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java

@@ -34,7 +34,7 @@ public class    AnonymousAuthenticationEntryPoint implements AuthenticationEntry
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("code", ErrorCode.ERROR401.getCode());
         jsonObject.put("msg", ErrorCode.ERROR401.getMsg());
-//        logger.info("未登陆用户");
+        logger.info("未登陆用户");
         String logUri = "api/user/login";
         if (request.getRequestURI().contains(logUri)){
             jsonObject.put("msg", e.getMessage());

+ 9 - 0
src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java

@@ -1,6 +1,7 @@
 package com.genersoft.iot.vmp.conf.security;
 
 import com.genersoft.iot.vmp.conf.security.dto.JwtUser;
+import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -31,6 +32,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
             chain.doFilter(request, response);
             return;
         }
+//        logger.info("[用户token] " + requestURI);
         String jwt = request.getHeader(JwtUtils.getHeader());
         // 这里如果没有jwt,继续往后走,因为后面还有鉴权管理器等去判断是否拥有身份凭证,所以是可以放行的
         // 没有jwt相当于匿名访问,若有一些接口是需要权限的,则不能访问这些接口
@@ -44,6 +46,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
 
         JwtUser jwtUser = JwtUtils.verifyToken(jwt);
         String username = jwtUser.getUserName();
+        String password = jwtUser.getPassword();
         // TODO 处理各个状态
         switch (jwtUser.getStatus()){
             case EXPIRED:
@@ -59,8 +62,14 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
             case EXPIRING_SOON:
                 // 即将过期
 //                return;
+                logger.info("[用户token] 即将过期,刷新过期时间");
+                String newJwt = JwtUtils.createToken(username, password);
+                response.setHeader(JwtUtils.getHeader(), newJwt);
+                request.setAttribute(JwtUtils.getHeader(), newJwt);
             default:
         }
+        // 延长token有效期
+
 
 //        String password = SecurityUtils.encryptPassword(jwtUser.getPassword());
 //        user.setPassword(password);

+ 31 - 0
src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java

@@ -135,4 +135,35 @@ public class JwtUtils {
             return jwtUser;
         }
     }
+
+    public static JwtUser refreshToken(String token,int minutes){
+        // 刷新token有效期
+        JwtUser jwtUser = new JwtUser();
+        try{
+            JwtConsumer consumer = new JwtConsumerBuilder()
+                    .setRequireExpirationTime()
+                    .setMaxFutureValidityInMinutes(5256000)
+                    .setAllowedClockSkewInSeconds(30)
+                    .setRequireSubject()
+                    //.setExpectedIssuer("")
+                    .setExpectedAudience(AUDIENCE)
+                    .setVerificationKey(new RsaJsonWebKey(JsonUtil.parseJson(publicKeyStr)).getPublicKey())
+                    .build();
+
+            JwtClaims claims = consumer.processToClaims(token);
+            NumericDate expirationTime = claims.getExpirationTime();
+            // 刷新token有效期,添加2分钟
+            expirationTime.addSeconds(minutes * 60);
+            claims.setExpirationTime(expirationTime);
+            claims.setIssuedAtToNow();
+            String username = (String) claims.getClaimValue("username");
+            String password = (String) claims.getClaimValue("password");
+            jwtUser.setUserName(username);
+            jwtUser.setPassword(password);
+            jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
+        }catch (Exception e){
+            logger.error("[Token刷新失败]: {}", e.getMessage());
+        }
+        return jwtUser;
+    }
 }

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java

@@ -87,6 +87,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
             matchers.add("/swagger-resources/**");
             matchers.add("/v3/api-docs/**");
             matchers.add("/aiLib/aialarm");
+            matchers.add("/ai/unread");
             matchers.add("/js/**");
             matchers.addAll(userSetting.getInterfaceAuthenticationExcludes());
             // 可以直接访问的静态数据
@@ -113,6 +114,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
+        logger.info("interfaceAuthentication: " + userSetting.isInterfaceAuthentication());
         http.headers().contentTypeOptions().disable()
 //                .and().cors().configurationSource(configurationSource())
                 .and().cors()

+ 4 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java

@@ -57,8 +57,10 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
     public void handForDevice(RequestEvent evt, Device device, Element element) {
         if (device == null) {
             // 未注册的设备不做处理
+            logger.warn("[{}]未注册设备,不做处理", evt.getRequest().getRequestURI().toString());
             return;
         }
+        // 收到设备心跳包
         SIPRequest request = (SIPRequest) evt.getRequest();
         // 回复200 OK
         try {
@@ -91,9 +93,11 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
                 deviceService.online(device);
             }
         }
+        // fixme dynamicTask 出现任务丢失的情况
         // 刷新过期任务
         String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
         // 如果三次心跳失败,则设置设备离线
+        // 修改定时任务
         dynamicTask.startDelay(registerExpireTaskKey, ()-> deviceService.offline(device.getDeviceId(), "三次心跳失败"), device.getKeepaliveIntervalTime()*1000*3);
 
     }

+ 1 - 0
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java

@@ -25,6 +25,7 @@ public class UserServiceImpl implements IUserService {
 
     @Override
     public boolean changePassword(int id, String password) {
+
         User user = userMapper.selectById(id);
         user.setPassword(password);
         return userMapper.update(user) > 0;

+ 14 - 6
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java

@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.security.JwtUtils;
 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
+import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.KeepaliveNotifyMessageHandler;
 import com.genersoft.iot.vmp.service.IRoleService;
 import com.genersoft.iot.vmp.service.IUserService;
 import com.genersoft.iot.vmp.storager.dao.dto.Role;
@@ -15,6 +16,8 @@ import com.github.pagehelper.PageInfo;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.util.DigestUtils;
@@ -31,7 +34,7 @@ import java.util.List;
 @RestController
 @RequestMapping("/api/user")
 public class UserController {
-
+    private Logger logger = LoggerFactory.getLogger(UserController.class);
     @Autowired
     private AuthenticationManager authenticationManager;
 
@@ -52,6 +55,7 @@ public class UserController {
         LoginUser user;
         try {
             user = SecurityUtils.login(username, password, authenticationManager);
+            logger.info("[用户管理] - [登录] - [{} - {} -{}] - 登录成功", user.getId(), user.getUsername(), user.getRole().getId());
         } catch (AuthenticationException e) {
             throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
         }
@@ -72,20 +76,24 @@ public class UserController {
     @Parameter(name = "oldpassword", description = "旧密码(已md5加密的密码)", required = true)
     @Parameter(name = "password", description = "新密码(未md5加密的密码)", required = true)
     public void changePassword(@RequestParam String oldPassword, @RequestParam String password){
+        logger.info("[用户管理] 修改密码");
         // 获取当前登录用户id
-        LoginUser userInfo = SecurityUtils.getUserInfo();
-        if (userInfo== null) {
+        LoginUser loginUser = SecurityUtils.getUserInfo();
+        if (loginUser== null) {
             throw new ControllerException(ErrorCode.ERROR100);
         }
-        String username = userInfo.getUsername();
+        String username = loginUser.getUsername();
+        String passwordMd5 = loginUser.getPassword();
+        logger.info("[用户管理] ");
         LoginUser user = null;
         try {
             user = SecurityUtils.login(username, oldPassword, authenticationManager);
             if (user == null) {
                 throw new ControllerException(ErrorCode.ERROR100);
             }
-            int userId = SecurityUtils.getUserId();
-            boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes()));
+//            int userId = SecurityUtils.getUserId();
+            logger.info("[用户管理] 修改密码,用户id:" + user.getId() + ",用户名:" + username);
+            boolean result = userService.changePassword(user.getId(), DigestUtils.md5DigestAsHex(password.getBytes()));
             if (!result) {
                 throw new ControllerException(ErrorCode.ERROR100);
             }

+ 0 - 1
web_src/src/components/dialog/changePassword.vue

@@ -105,7 +105,6 @@ export default {
           });
           this.showDialog = false;
           setTimeout(()=>{
-            // 删除cookie,回到登录页面
             userService.clearUserInfo();
             this.$router.push('/login');
             this.sseSource.close();

+ 13 - 2
web_src/src/components/layoutCom/user_header.vue

@@ -10,13 +10,24 @@
 </template>
 
 <script>
+import userService from "@/components/service/UserService";
+
 export default {
   name: "user_header",
   data(){
     return {
       activeIndex: this.$route.path,
-      editUser: this.$cookies.get("session").roleId==1,
-
+      editUser: false,
+    }
+  },
+  beforeMount() {
+    this.initHeader();
+  },
+  methods: {
+    initHeader(){
+      this.activeIndex = this.$route.path;
+      let user = userService.getUser();
+      this.editUser = user.roleId===1;
     }
   }
 }

+ 1 - 0
web_src/src/main.js

@@ -54,6 +54,7 @@ _axios.interceptors.response.use((response) => {
   // 对响应数据做点什么
   let token = response.headers["access-token"];
   if (token) {
+    console.log("更新token");
     userService.setToken(token)
   }
   return response;