From ebbb33409ff4ba36df1915371ab015842d70f9a9 Mon Sep 17 00:00:00 2001 From: zhaojun <873019219@qq.com> Date: Mon, 15 Aug 2022 13:29:35 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E4=BC=98=E5=8C=96=20OneDrive/Shar?= =?UTF-8?q?ePoint=20=E8=8E=B7=E5=8F=96=20token=20=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BF=A1=E6=81=AF=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E4=BC=98=E5=8C=96=E9=A1=B5=E9=9D=A2=E6=95=88?= =?UTF-8?q?=E6=9E=9C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zfile/admin/model/dto/OneDriveToken.java | 35 +++++- .../callback/OneDriveCallbackController.java | 30 ++++- .../base/MicrosoftDriveServiceBase.java | 31 ++++- .../impl/OneDriveChinaServiceImpl.java | 24 ++-- .../service/impl/OneDriveServiceImpl.java | 18 ++- .../impl/SharePointChinaServiceImpl.java | 20 +++- .../service/impl/SharePointServiceImpl.java | 20 +++- src/main/resources/templates/callback.html | 110 +++++++++++++++--- 8 files changed, 232 insertions(+), 56 deletions(-) diff --git a/src/main/java/im/zhaojun/zfile/admin/model/dto/OneDriveToken.java b/src/main/java/im/zhaojun/zfile/admin/model/dto/OneDriveToken.java index 1a0c9a3..a2a4a73 100644 --- a/src/main/java/im/zhaojun/zfile/admin/model/dto/OneDriveToken.java +++ b/src/main/java/im/zhaojun/zfile/admin/model/dto/OneDriveToken.java @@ -1,6 +1,5 @@ package im.zhaojun.zfile.admin.model.dto; -import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; /** @@ -10,11 +9,41 @@ import lombok.Data; */ @Data public class OneDriveToken { + + private String clientId; + + private String clientSecret; + + private String redirectUri; - @JSONField(name = "access_token") private String accessToken; - @JSONField(name = "refresh_token") private String refreshToken; + + private boolean success; + + private String body; + + public static OneDriveToken success(String clientId, String clientSecret, String redirectUri, String accessToken, String refreshToken, String body) { + OneDriveToken token = new OneDriveToken(); + token.setClientId(clientId); + token.setClientSecret(clientSecret); + token.setRedirectUri(redirectUri); + token.setSuccess(true); + token.setBody(body); + token.setAccessToken(accessToken); + token.setRefreshToken(refreshToken); + return token; + } + + public static OneDriveToken fail(String clientId, String clientSecret, String redirectUri, String body) { + OneDriveToken token = new OneDriveToken(); + token.setClientId(clientId); + token.setClientSecret(clientSecret); + token.setRedirectUri(redirectUri); + token.setSuccess(false); + token.setBody(body); + return token; + } } \ No newline at end of file diff --git a/src/main/java/im/zhaojun/zfile/common/controller/callback/OneDriveCallbackController.java b/src/main/java/im/zhaojun/zfile/common/controller/callback/OneDriveCallbackController.java index 155d909..916692a 100644 --- a/src/main/java/im/zhaojun/zfile/common/controller/callback/OneDriveCallbackController.java +++ b/src/main/java/im/zhaojun/zfile/common/controller/callback/OneDriveCallbackController.java @@ -8,6 +8,7 @@ import im.zhaojun.zfile.home.service.impl.OneDriveChinaServiceImpl; import im.zhaojun.zfile.home.service.impl.OneDriveServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -22,6 +23,7 @@ import javax.annotation.Resource; */ @Api(tags = "OneDrive 认证回调模块") @Controller +@Slf4j @RequestMapping(value = {"/onedrive", "/onedirve"}) public class OneDriveCallbackController { @@ -36,19 +38,24 @@ public class OneDriveCallbackController { @ApiOperationSupport(order = 1) @ApiOperation(value = "生成 OAuth2 登陆 URL", notes = "生成 OneDrive OAuth2 登陆 URL,用户国际版,家庭版等非世纪互联运营的 OneDrive.") public String authorize(String clientId, String clientSecret, String redirectUri) { + log.info("onedrive 国际版生成授权链接参数信息: clientId: {}, clientSecret: {}, redirectUri: {}", clientId, clientSecret, redirectUri); + if (StrUtil.isAllEmpty(clientId, clientSecret, redirectUri)) { clientId = oneDriveServiceImpl.getClientId(); redirectUri = oneDriveServiceImpl.getRedirectUri(); clientSecret = oneDriveServiceImpl.getClientSecret(); } + String stateStr = "&state=" + Base64.encodeUrlSafe(StrUtil.join("::", clientId, clientSecret, redirectUri)); - String authorizeUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId + "&response_type=code&redirect_uri=" + redirectUri + "&scope=" + oneDriveServiceImpl.getScope() + stateStr; + + log.info("onedrive 国际版生成授权链接结果: {}", authorizeUrl); + return "redirect:" + authorizeUrl; } @@ -57,11 +64,15 @@ public class OneDriveCallbackController { @ApiOperationSupport(order = 2) @ApiOperation(value = "OAuth2 回调地址", notes = "根据 OAuth2 协议,登录成功后,会返回给网站一个 code,用此 code 去换取 accessToken 和 refreshToken.(oneDrive 会回调此接口)") public String oneDriveCallback(String code, String state, Model model) { + log.info("onedrive 国际版授权回调参数信息: code: {}, state: {}", code, state); + String stateDecode = Base64.decodeStr(state); String[] stateArr = stateDecode.split("::"); + OneDriveToken oneDriveToken = oneDriveServiceImpl.getToken(code, stateArr[0], stateArr[1], stateArr[2]); - model.addAttribute("accessToken", oneDriveToken.getAccessToken()); - model.addAttribute("refreshToken", oneDriveToken.getRefreshToken()); + log.info("onedrive 国际版授权回调获取令牌结果: {}", oneDriveToken); + + model.addAttribute("oneDriveToken", oneDriveToken); return "callback"; } @@ -70,6 +81,8 @@ public class OneDriveCallbackController { @ApiOperationSupport(order = 3) @ApiOperation(value = "生成 OAuth2 登陆 URL(世纪互联)", notes = "生成 OneDrive OAuth2 登陆 URL,用于世纪互联版本.") public String authorizeChina(String clientId, String clientSecret, String redirectUri) { + log.info("onedrive 世纪互联版生成授权链接参数信息: clientId: {}, clientSecret: {}, redirectUri: {}", clientId, clientSecret, redirectUri); + if (StrUtil.isAllEmpty(clientId, clientSecret, redirectUri)) { clientId = oneDriveChinaServiceImpl.getClientId(); redirectUri = oneDriveChinaServiceImpl.getRedirectUri(); @@ -83,6 +96,9 @@ public class OneDriveCallbackController { + "&response_type=code&redirect_uri=" + redirectUri + "&scope=" + oneDriveChinaServiceImpl.getScope() + stateStr; + + log.info("onedrive 世纪互联版生成授权链接结果: {}", authorizeUrl); + return "redirect:" + authorizeUrl; } @@ -91,11 +107,15 @@ public class OneDriveCallbackController { @ApiOperationSupport(order = 4) @ApiOperation(value = "OAuth2 回调地址(世纪互联)", notes = "根据 OAuth2 协议,登录成功后,会返回给网站一个 code,用此 code 去换取 accessToken 和 refreshToken.(oneDrive 会回调此接口)") public String oneDriveChinaCallback(String code, String state, Model model) { + log.info("onedrive 世纪互联版授权回调参数信息: code: {}, state: {}", code, state); + String stateDecode = Base64.decodeStr(state); String[] stateArr = stateDecode.split("::"); + OneDriveToken oneDriveToken = oneDriveChinaServiceImpl.getToken(code, stateArr[0], stateArr[1], stateArr[2]); - model.addAttribute("accessToken", oneDriveToken.getAccessToken()); - model.addAttribute("refreshToken", oneDriveToken.getRefreshToken()); + log.info("onedrive 世纪互联版授权回调获取令牌结果: {}", oneDriveToken); + + model.addAttribute("oneDriveToken", oneDriveToken); return "callback"; } diff --git a/src/main/java/im/zhaojun/zfile/home/service/base/MicrosoftDriveServiceBase.java b/src/main/java/im/zhaojun/zfile/home/service/base/MicrosoftDriveServiceBase.java index 4e5fa48..57568f4 100644 --- a/src/main/java/im/zhaojun/zfile/home/service/base/MicrosoftDriveServiceBase.java +++ b/src/main/java/im/zhaojun/zfile/home/service/base/MicrosoftDriveServiceBase.java @@ -99,16 +99,26 @@ public abstract class MicrosoftDriveServiceBase

e "&client_secret=" + getClientSecret() + "&refresh_token=" + refreshStorageSourceConfig.getValue() + "&grant_type=refresh_token"; - + + log.info("{} 尝试刷新令牌, 参数信息为: {}", this, param); + String fullAuthenticateUrl = AUTHENTICATE_URL.replace("{authenticateEndPoint}", getAuthenticateEndPoint()); HttpRequest post = HttpUtil.createPost(fullAuthenticateUrl); post.body(param, "application/x-www-form-urlencoded"); HttpResponse response = post.execute(); + String body = response.body(); + log.info("{} 尝试刷新令牌成功, 响应信息为: {}", this, body); + + JSONObject jsonBody = JSONObject.parseObject(body); + if (response.getStatus() != HttpStatus.OK.value()) { - throw new RuntimeException(response.body()); + return OneDriveToken.fail(getClientId(), getClientSecret(), getRedirectUri(), body); } - return JSONObject.parseObject(response.body(), OneDriveToken.class); + + String accessToken = jsonBody.getString("access_token"); + String refreshToken = jsonBody.getString("refresh_token"); + return OneDriveToken.success(getClientId(), getClientSecret(), getRedirectUri(), accessToken, refreshToken, body); } /** @@ -120,6 +130,7 @@ public abstract class MicrosoftDriveServiceBase

e * @return 获取的 Token 信息. */ public OneDriveToken getToken(String code, String clientId, String clientSecret, String redirectUri) { + log.info("{} 根据授权回调 code 获取令牌:code: {}, clientId: {}, clientSecret: {}, redirectUri: {}", this, code, clientId, clientSecret, redirectUri); String param = "client_id=" + clientId + "&redirect_uri=" + redirectUri + "&client_secret=" + clientSecret + @@ -132,7 +143,17 @@ public abstract class MicrosoftDriveServiceBase

e post.body(param, "application/x-www-form-urlencoded"); HttpResponse response = post.execute(); - return JSONObject.parseObject(response.body(), OneDriveToken.class); + String body = response.body(); + log.info("{} 根据授权回调 code 获取令牌结果:body: {}", this, body); + JSONObject jsonBody = JSONObject.parseObject(body); + + if (response.getStatus() != HttpStatus.OK.value()) { + return OneDriveToken.fail(clientId, clientSecret, redirectUri, body); + } + + String accessToken = jsonBody.getString("access_token"); + String refreshToken = jsonBody.getString("refresh_token"); + return OneDriveToken.success(clientId, clientSecret, redirectUri, accessToken, refreshToken, body); } @Override @@ -365,7 +386,7 @@ public abstract class MicrosoftDriveServiceBase

e OneDriveToken refreshToken = getRefreshToken(); if (refreshToken.getAccessToken() == null || refreshToken.getRefreshToken() == null) { - return; + throw new StorageSourceRefreshTokenException("获取或刷新 AccessToken 失败, 获取到的令牌为空, 相关诊断信息为: " + refreshToken, storageId); } StorageSourceConfig accessTokenConfig = diff --git a/src/main/java/im/zhaojun/zfile/home/service/impl/OneDriveChinaServiceImpl.java b/src/main/java/im/zhaojun/zfile/home/service/impl/OneDriveChinaServiceImpl.java index 2c4c31c..a5f2380 100644 --- a/src/main/java/im/zhaojun/zfile/home/service/impl/OneDriveChinaServiceImpl.java +++ b/src/main/java/im/zhaojun/zfile/home/service/impl/OneDriveChinaServiceImpl.java @@ -1,6 +1,5 @@ package im.zhaojun.zfile.home.service.impl; -import cn.hutool.core.util.ObjectUtil; import im.zhaojun.zfile.admin.model.param.OneDriveChinaParam; import im.zhaojun.zfile.home.model.enums.StorageTypeEnum; import im.zhaojun.zfile.home.service.base.AbstractOneDriveServiceBase; @@ -44,22 +43,31 @@ public class OneDriveChinaServiceImpl extends AbstractOneDriveServiceBase - CallBack Result + + + + + ZFile OneDrive / SharePoint 令牌获取结果 - - -

accessToken (访问令牌)

-
- + +
+
+
+
+
+
ZFile OneDrive / SharePoint 令牌获取结果
+
+
+ 状态: + 获取成功 +
+
+ 状态: + 获取失败 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ tips: 以下为诊断信息,如获取成功请忽略,获取失败无法自行解决时请截图下方所有内容发送给开发者,github: https://github.com/zfile-dev/zfile/issues。 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+
- -

refreshToken (刷新令牌)

-
- -
- - + + \ No newline at end of file