diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java index aa7c4cc..706245c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java @@ -7,7 +7,10 @@ import com.ruoyi.jarvis.service.IWPS365OAuthService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -35,23 +38,47 @@ public class WPS365CallbackController extends BaseController { * 授权URL中的redirect_uri参数会自动使用配置中的完整URL:https://jarvis.van333.cn/wps365-callback */ @Anonymous - @GetMapping(produces = MediaType.TEXT_HTML_VALUE) - public String oauthCallback(@RequestParam(value = "code", required = false) String code, + @GetMapping + public ResponseEntity oauthCallback(@RequestParam(value = "code", required = false) String code, @RequestParam(value = "state", required = false) String state, @RequestParam(value = "error", required = false) String error, - @RequestParam(value = "error_description", required = false) String errorDescription) { + @RequestParam(value = "error_description", required = false) String errorDescription, + @RequestParam(value = "challenge", required = false) String challenge) { try { + // 处理challenge验证(WPS365后台配置时用于验证回调URL) + if (challenge != null && !challenge.trim().isEmpty()) { + log.info("收到WPS365 challenge验证请求 - challenge: {}", challenge); + // 尝试返回JSON格式(符合OAuth标准) + // 格式:{"challenge": "xxx"} 或直接返回challenge值 + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + String jsonResponse = "{\"challenge\":\"" + challenge + "\"}"; + return new ResponseEntity<>(jsonResponse, headers, HttpStatus.OK); + } catch (Exception e) { + log.warn("返回JSON格式失败,尝试纯文本格式", e); + // 如果JSON失败,尝试纯文本 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_PLAIN); + return new ResponseEntity<>(challenge, headers, HttpStatus.OK); + } + } + // 处理授权错误 if (error != null) { log.error("WPS365授权失败 - error: {}, error_description: {}", error, errorDescription); String errorMsg = errorDescription != null ? errorDescription : error; - return generateCallbackHtml(false, "授权失败: " + errorMsg, null); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(false, "授权失败: " + errorMsg, null), headers, HttpStatus.OK); } - // 验证授权码 + // 如果没有code也没有challenge,可能是直接访问,显示提示信息 if (code == null || code.trim().isEmpty()) { - log.error("授权码为空"); - return generateCallbackHtml(false, "授权码不能为空", null); + log.warn("访问回调地址但没有授权码,可能是测试访问"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(false, "等待授权回调... 如果没有授权码,请通过授权流程访问", null), headers, HttpStatus.OK); } log.info("收到WPS365授权回调 - code: {}, state: {}", code, state); @@ -62,7 +89,9 @@ public class WPS365CallbackController extends BaseController { // 验证返回的token信息 if (tokenInfo == null || tokenInfo.getAccessToken() == null) { log.error("获取访问令牌失败 - tokenInfo: {}", tokenInfo); - return generateCallbackHtml(false, "获取访问令牌失败,响应数据格式不正确", null); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(false, "获取访问令牌失败,响应数据格式不正确", null), headers, HttpStatus.OK); } log.info("成功获取访问令牌 - userId: {}, access_token: {}", @@ -76,17 +105,25 @@ public class WPS365CallbackController extends BaseController { log.info("访问令牌已自动保存到后端缓存 - userId: {}", tokenInfo.getUserId()); } else { log.warn("userId为空,无法保存Token"); - return generateCallbackHtml(false, "获取用户ID失败,无法保存Token", null); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(false, "获取用户ID失败,无法保存Token", null), headers, HttpStatus.OK); } } catch (Exception e) { log.error("保存访问令牌失败", e); - return generateCallbackHtml(false, "保存访问令牌失败: " + e.getMessage(), null); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(false, "保存访问令牌失败: " + e.getMessage(), null), headers, HttpStatus.OK); } - return generateCallbackHtml(true, "授权成功,访问令牌已自动保存", tokenInfo); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(true, "授权成功,访问令牌已自动保存", tokenInfo), headers, HttpStatus.OK); } catch (Exception e) { log.error("OAuth回调处理失败", e); - return generateCallbackHtml(false, "授权失败: " + e.getMessage(), null); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_HTML); + return new ResponseEntity<>(generateCallbackHtml(false, "授权失败: " + e.getMessage(), null), headers, HttpStatus.OK); } }