权限控制

This commit is contained in:
2025-06-25 09:06:22 +08:00
parent 74cdfaf882
commit c45800f6d5
11 changed files with 174 additions and 38 deletions

View File

@@ -11,6 +11,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
@@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("accept")
@RestController
@RequiredArgsConstructor
@Slf4j
public class EventGateController extends BaseController {
private final WebSocketServer webSocketServer;
@@ -31,13 +33,13 @@ public class EventGateController extends BaseController {
@GetMapping("/eventMsg")
@ApiOperation("接收远程推送的暂态事件")
@ApiImplicitParam(name = "eventMsg", value = "暂态事件json字符", required = true)
public HttpResult<JSONObject> eventMsg(@RequestParam("msg") String msg) {
public HttpResult<Object> eventMsg(@RequestParam("msg") String msg) {
String methodDescribe = getMethodDescribe("eventMsg");
System.out.println(msg);
log.info("接收到暂降事件:{}",msg);
JSONObject jsonObject = new JSONObject(msg);
webSocketServer.sendMessageToUser("bbb",jsonObject.toString());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, jsonObject, methodDescribe);
webSocketServer.sendMessageToAll(jsonObject.toString());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}

View File

@@ -81,6 +81,17 @@ public class LargeScreenCountController extends BaseController {
@OperateInfo
@PostMapping("/noDealEventList")
@ApiOperation("暂降事件列表")
@ApiImplicitParam(name = "largeScreenCountParam", value = "查询参数", required = true)
public HttpResult<List<EventDetailVO>> noDealEventList(@RequestBody LargeScreenCountParam largeScreenCountParam) {
String methodDescribe = getMethodDescribe("noDealEventList");
List<EventDetailVO> result = largeScreenCountService.eventList(largeScreenCountParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}

View File

@@ -1,5 +1,8 @@
package com.njcn.gather.event.transientes.filter;
import cn.hutool.json.JSONObject;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.gather.event.transientes.utils.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
@@ -33,21 +36,22 @@ public class JwtRequestFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
System.out.println("请求路径"+request.getRequestURI());
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
try {
username = jwtUtil.extractUsername(jwt);
} catch (ExpiredJwtException e) {
e.printStackTrace();
sendErrorResponse(response,CommonResponseEnum.TOKEN_EXPIRE_JWT);
return;
} catch (Exception e) {
// 可以在这里处理令牌过期的情况
log.info("JWT Token 校验异常,可能过期了");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Token expired");
return; // 终止请求处理
e.printStackTrace();
sendErrorResponse(response,CommonResponseEnum.PARSE_TOKEN_ERROR);
return;
}
}
@@ -58,11 +62,21 @@ public class JwtRequestFilter extends OncePerRequestFilter {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
private void sendErrorResponse(HttpServletResponse response, CommonResponseEnum error) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json;charset=UTF-8");
HttpResult<String> httpResult = new HttpResult<>();
httpResult.setCode(error.getCode());
httpResult.setMessage(error.getMessage());
response.getWriter().write(new JSONObject(httpResult, false).toString());
}
}

View File

@@ -0,0 +1,13 @@
package com.njcn.gather.event.transientes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.gather.event.transientes.pojo.po.PqsUserSet;
/**
* @Author: cdf
* @CreateTime: 2025-06-24
* @Description:
*/
public interface PqsUserSetMapper extends BaseMapper<PqsUserSet> {
}

View File

@@ -19,4 +19,7 @@ public class LargeScreenCountParam {
@ApiModelProperty(name="eventtype",value="类型0 暂降事件 1远程通知")
private Integer eventtype;
@ApiModelProperty(name="eventDeep",value="0.普通事件 1.严重事件 null.全部事件")
private Integer eventDeep;
}

View File

@@ -0,0 +1,49 @@
package com.njcn.gather.event.transientes.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* @Author: cdf
* @CreateTime: 2025-06-24
* @Description:
*/
@Data
@TableName("PQSADMIN_BJ.PQS_USERSET")
public class PqsUserSet implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户设置索引
*/
@TableId("USERSET_INDEX")
private String usersetIndex;
/**
* 用户索引
*/
@TableField("USER_INDEX")
private String userIndex;
/**
* 是否通知(0-否,1-是)
*/
@TableField("ISNOTICE")
private Integer isNotice;
/**
* 角色组索引
*/
@TableField("ROLEGP_INDEX")
private String roleGpIndex;
/**
* 部门索引
*/
@TableField("DEPTS_INDEX")
private String deptsIndex;
}

View File

@@ -1,7 +1,14 @@
package com.njcn.gather.event.transientes.security;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.PubUtils;
import com.njcn.gather.event.transientes.utils.JwtUtil;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.HttpResultUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
@@ -13,7 +20,8 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AuthController {
@Slf4j
public class AuthController extends BaseController {
@Autowired
private AuthenticationManager authenticationManager;
@@ -25,18 +33,21 @@ public class AuthController {
private JwtUtil jwtUtil;
@PostMapping("/cn_authenticate")
public String createAuthenticationToken(@RequestBody AuthRequest authRequest) throws Exception {
@ApiOperation("登录认证")
public HttpResult<String> createAuthenticationToken(@RequestBody AuthRequest authRequest) {
String methodDescribe = getMethodDescribe("createAuthenticationToken");
log.info("Authentication request - username: {}, password: {}",authRequest.getUsername(),authRequest.getPassword());
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
);
} catch (BadCredentialsException e) {
e.printStackTrace();
throw new BusinessException("Incorrect username or password");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
}
final UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
final String jwt = jwtUtil.generateToken(userDetails);
return jwt;
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, jwt, methodDescribe);
}
}

View File

@@ -34,7 +34,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/cn_authenticate").permitAll() // 允许访问认证接口
.antMatchers("/cn_authenticate","/ws/**").permitAll() // 允许访问认证接口
.anyRequest().authenticated()
.and()
.sessionManagement()

View File

@@ -23,4 +23,8 @@ public interface LargeScreenCountService {
List<EventTrendVO> eventTrend(LargeScreenCountParam largeScreenCountParam);
List<EventDetailVO> eventList(LargeScreenCountParam largeScreenCountParam);
List<EventDetailVO> noDealEventList(LargeScreenCountParam largeScreenCountParam);
}

View File

@@ -3,6 +3,7 @@ package com.njcn.gather.event.transientes.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.event.transientes.pojo.param.LargeScreenCountParam;
import com.njcn.gather.event.devcie.pojo.po.PqDevice;
@@ -24,10 +25,7 @@ import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -186,5 +184,19 @@ public class LargeScreenCountServiceImpl implements LargeScreenCountService {
return null;
}
@Override
public List<EventDetailVO> noDealEventList(LargeScreenCountParam largeScreenCountParam) {
if(Objects.isNull(largeScreenCountParam.getEventDeep())){
}
/* eventdetails = pqsEventdetailService.lambdaQuery()
.between(PqsEventdetail::getTimeid, startTime, endTime)
.in(PqsEventdetail::getLineid,deptslineIds)
.eq(PqsEventdetail::getLookFlag,largeScreenCountParam.getEventtype()).list();*/
return null;
}
}

View File

@@ -1,6 +1,5 @@
package com.njcn.gather.event.transientes.websocket;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -30,12 +29,15 @@ import java.util.concurrent.TimeUnit;
public class WebSocketServer {
private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
private final ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1);
private static final ConcurrentHashMap<String, Long> lastHeartbeatTime = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, ScheduledExecutorService> heartbeatExecutors = new ConcurrentHashMap<>();
private static final long HEARTBEAT_TIMEOUT = 60; // 60秒超时
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
if (StrUtil.isNotBlank(userId)) {
sessions.put(userId, session);
lastHeartbeatTime.put(userId, System.currentTimeMillis());
sendMessage(session, "连接成功");
System.out.println("用户 " + userId + " 已连接");
@@ -52,9 +54,10 @@ public class WebSocketServer {
@OnMessage
public void onMessage(String message, Session session, @PathParam("userId") String userId) {
if ("ping".equalsIgnoreCase(message)) {
// 处理心跳请求
sendMessage(session, "pong");
if ("alive".equalsIgnoreCase(message)) {
// 更新最后心跳时间
lastHeartbeatTime.put(userId, System.currentTimeMillis());
sendMessage(session, "over");
} else {
// 处理业务消息
System.out.println("收到用户 " + userId + " 的消息: " + message);
@@ -64,7 +67,13 @@ public class WebSocketServer {
@OnClose
public void onClose(Session session, CloseReason closeReason, @PathParam("userId") String userId) {
// 移除用户并取消心跳检测
sessions.remove(userId);
lastHeartbeatTime.remove(userId);
ScheduledExecutorService executor = heartbeatExecutors.remove(userId);
if (executor != null) {
executor.shutdownNow();
}
System.out.println("用户 " + userId + " 已断开连接,状态码: " + closeReason.getReasonPhrase());
}
@@ -87,12 +96,14 @@ public class WebSocketServer {
System.out.println("发送消息给用户 " + userId + " 失败: " + e.getMessage());
}
} else {
System.out.println("用户 " + userId + " 不在线或会话已关闭");
System.out.println("webSocket用户 " + userId + " 不在线或会话已关闭");
}
}
public void sendMessageToAll(String message) {
sessions.forEach((userId, session) -> {
System.out.println("给用户推送消息"+userId);
if (session.isOpen()) {
try {
session.getBasicRemote().sendText(message);
@@ -112,19 +123,25 @@ public class WebSocketServer {
}
private void startHeartbeat(Session session, String userId) {
heartbeatExecutor.scheduleAtFixedRate(() -> {
if (session.isOpen()) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
heartbeatExecutors.put(userId, executor);
// 定期检查心跳
executor.scheduleAtFixedRate(() -> {
long lastTime = lastHeartbeatTime.getOrDefault(userId, 0L);
long currentTime = System.currentTimeMillis();
// 如果超过30秒没有收到心跳
if (currentTime - lastTime > HEARTBEAT_TIMEOUT * 1000) {
try {
session.getBasicRemote().sendText("ping");
System.out.println("用户 " + userId + " 心跳超时,关闭连接");
session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "心跳超时"));
} catch (IOException e) {
System.out.println("发送心跳给用户 " + userId + " 失败: " + e.getMessage());
try {
session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "心跳失败"));
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("关闭用户 " + userId + " 连接时出错: " + e.getMessage());
}
executor.shutdown();
heartbeatExecutors.remove(userId);
}
}, 10, 10, TimeUnit.SECONDS); // 每10秒发送一次心跳
}, 0, 5, TimeUnit.SECONDS); // 每5秒检查一次
}
}