From aa5281da83fc6190f9e90de0ce48e3591b52ed4e Mon Sep 17 00:00:00 2001 From: zjf <1799650030@qq.com> Date: Tue, 22 Apr 2025 17:34:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=8C=87=E7=BA=B9=E5=BC=95?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ThirdPartyOAth2Cotroller.java | 43 ++++++- .../utils/DeviceFingerprintUtil.java | 14 +++ .../api/entity/UserTrustedDeviceEntity.java | 95 ++++++++++++++ .../UserTrustedDeviceController.java | 118 ++++++++++++++++++ .../admin/mapper/UserTrustedDeviceMapper.java | 11 ++ .../service/UserTrustedDeviceService.java | 8 ++ .../impl/UserTrustedDeviceServiceImpl.java | 16 +++ .../mapper/UserTrustedDeviceMapper.xml | 19 +++ 8 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/DeviceFingerprintUtil.java create mode 100644 pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/UserTrustedDeviceEntity.java create mode 100644 pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java create mode 100644 pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/UserTrustedDeviceMapper.java create mode 100644 pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java create mode 100644 pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/UserTrustedDeviceServiceImpl.java create mode 100644 pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/UserTrustedDeviceMapper.xml diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java index c6ce8cb0..fca8dc49 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java @@ -17,6 +17,7 @@ import com.bsd.pjcloud.thirdparty.entity.ThirdPartyUserEntity; import com.bsd.pjcloud.thirdparty.service.SmsService; import com.bsd.pjcloud.thirdparty.service.ThirdPartyOAuth2Service; import com.bsd.pjcloud.thirdparty.service.ThirdPartyUserService; +import com.bsd.pjcloud.thirdparty.utils.DeviceFingerprintUtil; import com.bsd.pjcloud.thirdparty.utils.SmsCodeUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -203,20 +204,21 @@ public class ThirdPartyOAth2Cotroller { @Transactional @GlobalTransactional public R shjnsso(@RequestBody @Valid SHJNSSODTO shjnsso) { + //检查设备指纹 ZZDUserDTO zzdUserDTO = thirdPartyOAuth2Service.shjnsso(shjnsso.getAccountId(), shjnsso.getSessionId()); if (null==zzdUserDTO){ throw new RuntimeException(""); } ZZDUserDTO.Ext ext = zzdUserDTO.getExt(); String mobile = zzdUserDTO.getMobile(); - R r; R> userByMobileOrEmployeeCode = remoteUserService.getUserByMobileOrEmployeeCode(null, mobile); List sysUserList = userByMobileOrEmployeeCode.getData(); if(!CollectionUtils.isEmpty(sysUserList)){ //登录成功生成token UserTokenDTO userTokenDTO = new UserTokenDTO(); userTokenDTO.setSysUser(sysUserList.get(0)); - r=remoteTokenService.generateToken(userTokenDTO); + + return remoteTokenService.generateToken(userTokenDTO); }else { //自动注册 // UserDTO userDTO = new UserDTO(); @@ -237,10 +239,25 @@ public class ThirdPartyOAth2Cotroller { // r=remoteTokenService.generateToken(userTokenDTO); return R.failed("系统中没有当前用户信息,请联系管理员进行申请!"); } - return r; + } - + // 在shjnsso方法中添加验证 +// @PostMapping("/shjnsso") +// public R shjnsso(..., HttpServletRequest request) { +// // 设备指纹验证 +// String clientFingerprint = DeviceFingerprintUtil.generate(request); +// String storedFingerprint = redisTemplate.opsForValue().get("device_fp:" + shjnsso.getAccountId()); +// +// if (!clientFingerprint.equals(storedFingerprint)) { +// // 新设备需要短信验证 +// String code = SmsCodeUtil.generateNumberCode(6); +// smsService.sendSms(mobile, "验证码模板ID", Map.of("code", code)); +// return R.failed("new_device").data("needSmsVerify", true); +// } +// +// // 原有逻辑继续执行... +// } @Inner(value = false) @GetMapping("/getAuthToken/{token}") public R info(@PathVariable(name = "token") String token) { @@ -269,14 +286,30 @@ public class ThirdPartyOAth2Cotroller { @Operation(summary = "短信登录认证") @SysLog("短信登录认证") @Inner(value = false) - public R loginSms(@RequestParam String mobilePhone) { + public R loginSms(@RequestParam String mobilePhone,HttpServletRequest httpServletRequest) { Map stringHashMap = new LinkedHashMap<>(); String s = SmsCodeUtil.generateNumberCode(6); stringHashMap.put("code",s); stringHashMap.put("date","5"); + System.out.println(WebUtils.getIP()); + System.out.println(WebUtils.getIP(httpServletRequest)); smsService.sendSms(mobilePhone, "20657",stringHashMap, WebUtils.getIP()); redisTemplate.opsForSet().add("smsCode_"+mobilePhone,s, 5, TimeUnit.MINUTES); + + //记录信任的设备 + // 2. 记录信任设备 +// String deviceFingerprint = DeviceFingerprintUtil.generate(request); +// deviceService.addTrustedDevice( +// dto.getUserId(), +// deviceFingerprint, +// LocalDateTime.now().plusMonths(3) // 信任3个月 +// ); +// +// // 3. 生成令牌 +// User user = userService.getById(dto.getUserId()); +// String token = jwtService.generateToken(user); +// return R.ok().data("token", token); return R.ok(); } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/DeviceFingerprintUtil.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/DeviceFingerprintUtil.java new file mode 100644 index 00000000..cbc193f2 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/utils/DeviceFingerprintUtil.java @@ -0,0 +1,14 @@ +package com.bsd.pjcloud.thirdparty.utils; + +import com.bsd.pjcloud.common.core.util.WebUtils; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.util.DigestUtils; + +public class DeviceFingerprintUtil { + public static String generate(HttpServletRequest request) { + String userAgent = request.getHeader("User-Agent"); + String ip = WebUtils.getIP(request); + String accept = request.getHeader("Accept"); + return DigestUtils.md5DigestAsHex((userAgent + ip + accept).getBytes()); + } +} diff --git a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/UserTrustedDeviceEntity.java b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/UserTrustedDeviceEntity.java new file mode 100644 index 00000000..7e73beeb --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/UserTrustedDeviceEntity.java @@ -0,0 +1,95 @@ +package com.bsd.pjcloud.admin.api.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.time.LocalDateTime; + +/** + * 设备指纹 + * + * @author zjf + * @date 2025-04-22 17:14:57 + */ +@Data +@TableName("user_trusted_device") +@EqualsAndHashCode(callSuper = true) +@Schema(description = "设备指纹") +public class UserTrustedDeviceEntity extends Model { + + + /** + * 主键ID + */ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description="主键ID") + private Long id; + + /** + * 用户id + */ + @Schema(description="用户id") + private Long userId; + + /** + * MD5 + */ + @Schema(description="MD5") + private String deviceFingerprint; + + /** + * 设备名称 + */ + @Schema(description="设备名称") + private String deviceName; + + /** + * 最后一次登录时间 + */ + @Schema(description="最后一次登录时间") + private LocalDateTime lastLoginTime; + + /** + * 过期时间 + */ + @Schema(description="过期时间") + private LocalDateTime expireTime; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description="创建人") + private String createBy; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description="创建时间") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @Schema(description="更新时间") + private String updateBy; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @Schema(description="更新时间") + private LocalDateTime updateTime; + + /** + * 删除标记 + */ + @TableLogic + @TableField(fill = FieldFill.INSERT) + @Schema(description="删除标记") + private String delFlag; +} \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java new file mode 100644 index 00000000..3c2376ac --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java @@ -0,0 +1,118 @@ +package com.bsd.pjcloud.admin.controller; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.log.annotation.SysLog; +import com.bsd.pjcloud.admin.api.entity.UserTrustedDeviceEntity; +import com.bsd.pjcloud.admin.service.UserTrustedDeviceService; +import org.springframework.security.access.prepost.PreAuthorize; +import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.HttpHeaders; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 设备指纹 + * + * @author zjf + * @date 2025-04-22 17:14:57 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/userTrustedDevice" ) +@Tag(description = "userTrustedDevice" , name = "设备指纹管理" ) +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class UserTrustedDeviceController { + + private final UserTrustedDeviceService userTrustedDeviceService; + + /** + * 分页查询 + * @param page 分页对象 + * @param userTrustedDevice 设备指纹 + * @return + */ + @Operation(summary = "分页查询" , description = "分页查询" ) + @GetMapping("/page" ) + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_view')" ) + public R getUserTrustedDevicePage(@ParameterObject Page page, @ParameterObject UserTrustedDeviceEntity userTrustedDevice) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + return R.ok(userTrustedDeviceService.page(page, wrapper)); + } + + + /** + * 通过id查询设备指纹 + * @param id id + * @return R + */ + @Operation(summary = "通过id查询" , description = "通过id查询" ) + @GetMapping("/{id}" ) + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_view')" ) + public R getById(@PathVariable("id" ) Long id) { + return R.ok(userTrustedDeviceService.getById(id)); + } + + /** + * 新增设备指纹 + * @param userTrustedDevice 设备指纹 + * @return R + */ + @Operation(summary = "新增设备指纹" , description = "新增设备指纹" ) + @SysLog("新增设备指纹" ) + @PostMapping + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_add')" ) + public R save(@RequestBody UserTrustedDeviceEntity userTrustedDevice) { + return R.ok(userTrustedDeviceService.save(userTrustedDevice)); + } + + /** + * 修改设备指纹 + * @param userTrustedDevice 设备指纹 + * @return R + */ + @Operation(summary = "修改设备指纹" , description = "修改设备指纹" ) + @SysLog("修改设备指纹" ) + @PutMapping + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_edit')" ) + public R updateById(@RequestBody UserTrustedDeviceEntity userTrustedDevice) { + return R.ok(userTrustedDeviceService.updateById(userTrustedDevice)); + } + + /** + * 通过id删除设备指纹 + * @param ids id列表 + * @return R + */ + @Operation(summary = "通过id删除设备指纹" , description = "通过id删除设备指纹" ) + @SysLog("通过id删除设备指纹" ) + @DeleteMapping + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_del')" ) + public R removeById(@RequestBody Long[] ids) { + return R.ok(userTrustedDeviceService.removeBatchByIds(CollUtil.toList(ids))); + } + + + /** + * 导出excel 表格 + * @param userTrustedDevice 查询条件 + * @param ids 导出指定ID + * @return excel 文件流 + */ + @ResponseExcel + @GetMapping("/export") + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_export')" ) + public List export(UserTrustedDeviceEntity userTrustedDevice,Long[] ids) { + return userTrustedDeviceService.list(Wrappers.lambdaQuery(userTrustedDevice).in(ArrayUtil.isNotEmpty(ids), UserTrustedDeviceEntity::getId, ids)); + } +} \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/UserTrustedDeviceMapper.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/UserTrustedDeviceMapper.java new file mode 100644 index 00000000..53a3319e --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/UserTrustedDeviceMapper.java @@ -0,0 +1,11 @@ +package com.bsd.pjcloud.admin.mapper; + +import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper; +import com.bsd.pjcloud.admin.api.entity.UserTrustedDeviceEntity; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface UserTrustedDeviceMapper extends PjcloudBaseMapper { + + +} \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java new file mode 100644 index 00000000..4f761028 --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java @@ -0,0 +1,8 @@ +package com.bsd.pjcloud.admin.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bsd.pjcloud.admin.api.entity.UserTrustedDeviceEntity; + +public interface UserTrustedDeviceService extends IService { + +} \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/UserTrustedDeviceServiceImpl.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/UserTrustedDeviceServiceImpl.java new file mode 100644 index 00000000..5193e6f9 --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/UserTrustedDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.bsd.pjcloud.admin.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bsd.pjcloud.admin.api.entity.UserTrustedDeviceEntity; +import com.bsd.pjcloud.admin.mapper.UserTrustedDeviceMapper; +import com.bsd.pjcloud.admin.service.UserTrustedDeviceService; +import org.springframework.stereotype.Service; +/** + * 设备指纹 + * + * @author zjf + * @date 2025-04-22 17:14:57 + */ +@Service +public class UserTrustedDeviceServiceImpl extends ServiceImpl implements UserTrustedDeviceService { +} \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/UserTrustedDeviceMapper.xml b/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/UserTrustedDeviceMapper.xml new file mode 100644 index 00000000..06b1459a --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/UserTrustedDeviceMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file