优化 OneDrive/SharePoint 获取令牌相关代码

This commit is contained in:
zhaojun
2022-08-26 18:14:25 +08:00
parent 7da1405798
commit 774a8e184a
7 changed files with 138 additions and 111 deletions

View File

@@ -8,24 +8,24 @@ import lombok.Data;
* @author zhaojun
*/
@Data
public class OneDriveToken {
public class OAuth2Token {
private String clientId;
private String clientSecret;
private String redirectUri;
private String accessToken;
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();
public static OAuth2Token success(String clientId, String clientSecret, String redirectUri, String accessToken, String refreshToken, String body) {
OAuth2Token token = new OAuth2Token();
token.setClientId(clientId);
token.setClientSecret(clientSecret);
token.setRedirectUri(redirectUri);
@@ -36,8 +36,8 @@ public class OneDriveToken {
return token;
}
public static OneDriveToken fail(String clientId, String clientSecret, String redirectUri, String body) {
OneDriveToken token = new OneDriveToken();
public static OAuth2Token fail(String clientId, String clientSecret, String redirectUri, String body) {
OAuth2Token token = new OAuth2Token();
token.setClientId(clientId);
token.setClientSecret(clientSecret);
token.setRedirectUri(redirectUri);
@@ -45,5 +45,5 @@ public class OneDriveToken {
token.setBody(body);
return token;
}
}

View File

@@ -17,7 +17,7 @@ public class MicrosoftDriveParam implements IStorageParam {
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 如 https://xxx.com/onedrive/callback, 且需在 api 中配置为回调域名.", defaultValue = "${zfile.onedrive.redirectUri}", order = 3)
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 且需在 api 中配置为回调域名.", defaultValue = "${zfile.onedrive.redirectUri}", order = 3)
private String redirectUri;
@StorageParamItem(name = "访问令牌", link = "/onedrive/authorize", linkName = "前往获取令牌", order = 3)

View File

@@ -17,7 +17,7 @@ public class OneDriveChinaParam extends OneDriveParam {
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive-china.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 如 https://xxx.com/onedrive/china-callback, 且需在 api 中配置为回调域名.",
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 且需在 api 中配置为回调域名.",
defaultValue = "${zfile.onedrive-china.redirectUri}", order = 3)
private String redirectUri;

View File

@@ -17,7 +17,7 @@ public class SharePointChinaParam extends SharePointParam {
@StorageParamItem(name = "SecretKey", defaultValue = "${zfile.onedrive-china.clientSecret}", order = 2)
private String clientSecret;
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 如 https://xxx.com/onedrive/china-callback, 且需在 api 中配置为回调域名.",
@StorageParamItem(name = "回调地址", description = "如使用自定义 api, 需将此处默认的域名修改为您的域名, 且需在 api 中配置为回调域名.",
defaultValue = "${zfile.onedrive-china.redirectUri}", order = 3)
private String redirectUri;

View File

@@ -3,7 +3,7 @@ package im.zhaojun.zfile.common.controller.callback;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import im.zhaojun.zfile.admin.model.dto.OneDriveToken;
import im.zhaojun.zfile.admin.model.dto.OAuth2Token;
import im.zhaojun.zfile.home.service.impl.OneDriveChinaServiceImpl;
import im.zhaojun.zfile.home.service.impl.OneDriveServiceImpl;
import io.swagger.annotations.Api;
@@ -26,97 +26,121 @@ import javax.annotation.Resource;
@Slf4j
@RequestMapping(value = {"/onedrive", "/onedirve"})
public class OneDriveCallbackController {
@Resource
private OneDriveServiceImpl oneDriveServiceImpl;
@Resource
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
@GetMapping("/authorize")
@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;
+ "&response_type=code&redirect_uri=" + redirectUri
+ "&scope=" + oneDriveServiceImpl.getScope()
+ stateStr;
log.info("onedrive 国际版生成授权链接结果: {}", authorizeUrl);
return "redirect:" + authorizeUrl;
}
@GetMapping("/callback")
@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("::");
String clientId, clientSecret, redirectUri;
OneDriveToken oneDriveToken = oneDriveServiceImpl.getToken(code, stateArr[0], stateArr[1], stateArr[2]);
log.info("onedrive 国际版授权回调获取令牌结果: {}", oneDriveToken);
model.addAttribute("oneDriveToken", oneDriveToken);
if (StrUtil.isEmpty(state)) {
clientId = oneDriveServiceImpl.getClientId();
clientSecret = oneDriveServiceImpl.getClientSecret();
redirectUri = oneDriveServiceImpl.getRedirectUri();
} else {
String stateDecode = Base64.decodeStr(state);
String[] stateArr = stateDecode.split("::");
clientId = stateArr[0];
clientSecret = stateArr[1];
redirectUri = stateArr[2];
}
OAuth2Token OAuth2Token = oneDriveServiceImpl.getToken(code, clientId, clientSecret, redirectUri);
log.info("onedrive 国际版授权回调获取令牌结果: {}", OAuth2Token);
model.addAttribute("oauth2Token", OAuth2Token);
model.addAttribute("type", "OneDrive 国际版");
return "callback";
}
@GetMapping("/china-authorize")
@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();
clientSecret = oneDriveChinaServiceImpl.getClientSecret();
}
String stateStr = "&state=" + Base64.encodeUrlSafe(StrUtil.join("::", clientId, clientSecret, redirectUri));
String authorizeUrl = "https://login.chinacloudapi.cn/common/oauth2/v2.0/authorize?client_id=" + clientId
+ "&response_type=code&redirect_uri=" + redirectUri
+ "&scope=" + oneDriveChinaServiceImpl.getScope()
+ stateStr;
log.info("onedrive 世纪互联版生成授权链接结果: {}", authorizeUrl);
return "redirect:" + authorizeUrl;
}
@GetMapping("/china-callback")
@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]);
log.info("onedrive 世纪互联版授权回调获取令牌结果: {}", oneDriveToken);
model.addAttribute("oneDriveToken", oneDriveToken);
String clientId, clientSecret, redirectUri;
if (StrUtil.isEmpty(state)) {
clientId = oneDriveChinaServiceImpl.getClientId();
clientSecret = oneDriveChinaServiceImpl.getClientSecret();
redirectUri = oneDriveChinaServiceImpl.getRedirectUri();
} else {
String stateDecode = Base64.decodeStr(state);
String[] stateArr = stateDecode.split("::");
clientId = stateArr[0];
clientSecret = stateArr[1];
redirectUri = stateArr[2];
}
OAuth2Token OAuth2Token = oneDriveChinaServiceImpl.getToken(code, clientId, clientSecret, redirectUri);
log.info("onedrive 世纪互联版授权回调获取令牌结果: {}", OAuth2Token);
model.addAttribute("oauth2Token", OAuth2Token);
model.addAttribute("type", "OneDrive 世纪互联");
return "callback";
}
}

View File

@@ -8,7 +8,7 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import im.zhaojun.zfile.admin.constant.StorageConfigConstant;
import im.zhaojun.zfile.admin.model.dto.OneDriveToken;
import im.zhaojun.zfile.admin.model.dto.OAuth2Token;
import im.zhaojun.zfile.admin.model.entity.StorageSourceConfig;
import im.zhaojun.zfile.admin.model.param.MicrosoftDriveParam;
import im.zhaojun.zfile.admin.service.StorageSourceConfigService;
@@ -90,7 +90,7 @@ public abstract class MicrosoftDriveServiceBase<P extends MicrosoftDriveParam> e
*
* @return 刷新后的 Token
*/
public OneDriveToken getRefreshToken() {
public OAuth2Token getRefreshToken() {
StorageSourceConfig refreshStorageSourceConfig =
storageSourceConfigService.findByStorageIdAndName(storageId, StorageConfigConstant.REFRESH_TOKEN_KEY);
@@ -113,12 +113,12 @@ public abstract class MicrosoftDriveServiceBase<P extends MicrosoftDriveParam> e
JSONObject jsonBody = JSONObject.parseObject(body);
if (response.getStatus() != HttpStatus.OK.value()) {
return OneDriveToken.fail(getClientId(), getClientSecret(), getRedirectUri(), body);
return OAuth2Token.fail(getClientId(), getClientSecret(), getRedirectUri(), body);
}
String accessToken = jsonBody.getString("access_token");
String refreshToken = jsonBody.getString("refresh_token");
return OneDriveToken.success(getClientId(), getClientSecret(), getRedirectUri(), accessToken, refreshToken, body);
return OAuth2Token.success(getClientId(), getClientSecret(), getRedirectUri(), accessToken, refreshToken, body);
}
/**
@@ -129,7 +129,7 @@ public abstract class MicrosoftDriveServiceBase<P extends MicrosoftDriveParam> e
*
* @return 获取的 Token 信息.
*/
public OneDriveToken getToken(String code, String clientId, String clientSecret, String redirectUri) {
public OAuth2Token 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 +
@@ -148,12 +148,12 @@ public abstract class MicrosoftDriveServiceBase<P extends MicrosoftDriveParam> e
JSONObject jsonBody = JSONObject.parseObject(body);
if (response.getStatus() != HttpStatus.OK.value()) {
return OneDriveToken.fail(clientId, clientSecret, redirectUri, body);
return OAuth2Token.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);
return OAuth2Token.success(clientId, clientSecret, redirectUri, accessToken, refreshToken, body);
}
@Override
@@ -383,7 +383,7 @@ public abstract class MicrosoftDriveServiceBase<P extends MicrosoftDriveParam> e
@Override
public void refreshAccessToken() {
try {
OneDriveToken refreshToken = getRefreshToken();
OAuth2Token refreshToken = getRefreshToken();
if (refreshToken.getAccessToken() == null || refreshToken.getRefreshToken() == null) {
throw new StorageSourceRefreshTokenException("获取或刷新 AccessToken 失败, 获取到的令牌为空, 相关诊断信息为: " + refreshToken, storageId);