feat(license): 添加应用信息接口并增强验证逻辑
- 在 SecurityConfig 中为 /api/license/app-info 接口添加无需认证访问权限 - 优化 GlobalExceptionHandler 中的参数验证错误信息显示,提供详细的字段错误信息 - 移除 RegisterRequest 和 VerifyRequest 中的注解验证,改用代码手动验证 - 为 register 接口添加 deviceId 非空检查 - 为 verify 接口添加 deviceId 和 token 非空检查 - 移除 RegisterRequest 中对 deviceId 的 @NotBlank 注解验证 - 移除 VerifyRequest 中对 deviceId 和 token 的 @NotBlank 注解验证
这个提交包含在:
父节点
b7c2f0144f
当前提交
8e131906d8
@ -36,7 +36,7 @@ public class SecurityConfig {
|
|||||||
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||||
.requestMatchers("/api/license/register", "/api/license/verify").permitAll()
|
.requestMatchers("/api/license/register", "/api/license/verify", "/api/license/app-info").permitAll()
|
||||||
.requestMatchers("/api/license/internal/**", "/actuator/health", "/actuator/info").permitAll()
|
.requestMatchers("/api/license/internal/**", "/actuator/health", "/actuator/info").permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
)
|
)
|
||||||
|
|||||||
@ -17,6 +17,10 @@ public class GlobalExceptionHandler {
|
|||||||
|
|
||||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
public ResponseEntity<ApiResponse<Void>> handleValidationException(MethodArgumentNotValidException e) {
|
public ResponseEntity<ApiResponse<Void>> handleValidationException(MethodArgumentNotValidException e) {
|
||||||
return ResponseEntity.badRequest().body(ApiResponse.badRequest("Invalid request"));
|
String detail = e.getBindingResult().getFieldErrors().stream()
|
||||||
|
.map(f -> f.getField() + ": " + f.getDefaultMessage())
|
||||||
|
.reduce((a, b) -> a + "; " + b)
|
||||||
|
.orElse("Invalid request");
|
||||||
|
return ResponseEntity.badRequest().body(ApiResponse.badRequest(detail));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,8 +9,6 @@ import com.xuqm.common.security.LicenseFileCrypto;
|
|||||||
import com.xuqm.license.entity.AppLicenseEntity;
|
import com.xuqm.license.entity.AppLicenseEntity;
|
||||||
import com.xuqm.license.service.AppLicenseService;
|
import com.xuqm.license.service.AppLicenseService;
|
||||||
import com.xuqm.license.service.DeviceService;
|
import com.xuqm.license.service.DeviceService;
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -30,7 +28,10 @@ public class LicensePublicController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public ResponseEntity<ApiResponse<Map<String, Object>>> register(@Valid @RequestBody RegisterRequest req) {
|
public ResponseEntity<ApiResponse<Map<String, Object>>> register(@RequestBody RegisterRequest req) {
|
||||||
|
if (req.deviceId() == null || req.deviceId().isBlank()) {
|
||||||
|
throw new BusinessException(400, "deviceId 不能为空");
|
||||||
|
}
|
||||||
String resolvedAppKey = resolveAppKey(req.appKey(), req.licenseFile());
|
String resolvedAppKey = resolveAppKey(req.appKey(), req.licenseFile());
|
||||||
DeviceService.RegisterResult result = deviceService.register(
|
DeviceService.RegisterResult result = deviceService.register(
|
||||||
resolvedAppKey,
|
resolvedAppKey,
|
||||||
@ -50,7 +51,13 @@ public class LicensePublicController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/verify")
|
@PostMapping("/verify")
|
||||||
public ResponseEntity<ApiResponse<Map<String, Object>>> verify(@Valid @RequestBody VerifyRequest req) {
|
public ResponseEntity<ApiResponse<Map<String, Object>>> verify(@RequestBody VerifyRequest req) {
|
||||||
|
if (req.deviceId() == null || req.deviceId().isBlank()) {
|
||||||
|
throw new BusinessException(400, "deviceId 不能为空");
|
||||||
|
}
|
||||||
|
if (req.token() == null || req.token().isBlank()) {
|
||||||
|
throw new BusinessException(400, "token 不能为空");
|
||||||
|
}
|
||||||
String resolvedAppKey = resolveAppKey(req.appKey(), req.licenseFile());
|
String resolvedAppKey = resolveAppKey(req.appKey(), req.licenseFile());
|
||||||
DeviceService.VerifyResult result = deviceService.verify(resolvedAppKey, req.deviceId(), req.token(), req.userInfo());
|
DeviceService.VerifyResult result = deviceService.verify(resolvedAppKey, req.deviceId(), req.token(), req.userInfo());
|
||||||
Map<String, Object> data = new LinkedHashMap<>();
|
Map<String, Object> data = new LinkedHashMap<>();
|
||||||
@ -95,7 +102,7 @@ public class LicensePublicController {
|
|||||||
String appKey,
|
String appKey,
|
||||||
@JsonProperty("packageName") @JsonAlias("package_name") String packageName,
|
@JsonProperty("packageName") @JsonAlias("package_name") String packageName,
|
||||||
@JsonProperty("licenseFile") @JsonAlias("license_file") String licenseFile,
|
@JsonProperty("licenseFile") @JsonAlias("license_file") String licenseFile,
|
||||||
@NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
|
@JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
|
||||||
@JsonProperty("deviceName") @JsonAlias("device_name") String deviceName,
|
@JsonProperty("deviceName") @JsonAlias("device_name") String deviceName,
|
||||||
@JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel,
|
@JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel,
|
||||||
@JsonProperty("deviceVendor") @JsonAlias("device_vendor") String deviceVendor,
|
@JsonProperty("deviceVendor") @JsonAlias("device_vendor") String deviceVendor,
|
||||||
@ -107,8 +114,8 @@ public class LicensePublicController {
|
|||||||
String appKey,
|
String appKey,
|
||||||
@JsonProperty("packageName") @JsonAlias("package_name") String packageName,
|
@JsonProperty("packageName") @JsonAlias("package_name") String packageName,
|
||||||
@JsonProperty("licenseFile") @JsonAlias("license_file") String licenseFile,
|
@JsonProperty("licenseFile") @JsonAlias("license_file") String licenseFile,
|
||||||
@NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
|
@JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
|
||||||
@NotBlank String token,
|
String token,
|
||||||
@JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo
|
@JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户