diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java index aa818ac2..523e3f9e 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/convert/SaOAuth2DataConverterDefaultImpl.java @@ -60,5 +60,6 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter { } return SaFoxUtil.convertStringToList(allowUrl); } + } diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/other/ClientIdAndSecretModel.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/other/ClientIdAndSecretModel.java new file mode 100644 index 00000000..b5180f3f --- /dev/null +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/model/other/ClientIdAndSecretModel.java @@ -0,0 +1,87 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.oauth2.data.model.other; + +import java.io.Serializable; + +/** + * Client 的 id 和 secret + * + * @author click33 + * @since 1.39.0 + */ +public class ClientIdAndSecretModel implements Serializable { + + private static final long serialVersionUID = -6541180061782004705L; + + /** + * 应用id + */ + public String clientId; + + /** + * 应用秘钥 + */ + public String clientSecret; + + public ClientIdAndSecretModel() { + } + public ClientIdAndSecretModel(String clientId, String clientSecret) { + super(); + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + /** + * @return 应用id + */ + public String getClientId() { + return clientId; + } + + /** + * @param clientId 应用id + * @return 对象自身 + */ + public ClientIdAndSecretModel setClientId(String clientId) { + this.clientId = clientId; + return this; + } + + /** + * @return 应用秘钥 + */ + public String getClientSecret() { + return clientSecret; + } + + /** + * @param clientSecret 应用秘钥 + * @return 对象自身 + */ + public ClientIdAndSecretModel setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + + @Override + public String toString() { + return "ClientIdAndSecretModel{" + + "clientId='" + clientId + '\'' + + ", clientSecret='" + clientSecret + '\'' + + '}'; + } +} diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolver.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolver.java index 67d8da7f..7b6ff223 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolver.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolver.java @@ -15,8 +15,10 @@ */ package cn.dev33.satoken.oauth2.data.resolver; +import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.oauth2.data.model.AccessTokenModel; import cn.dev33.satoken.oauth2.data.model.ClientTokenModel; +import cn.dev33.satoken.oauth2.data.model.other.ClientIdAndSecretModel; import cn.dev33.satoken.util.SaResult; import java.util.Map; @@ -31,6 +33,14 @@ import java.util.Map; */ public interface SaOAuth2DataResolver { + /** + * 数据读取:从请求对象中读取 ClientId、Secret + * + * @param request / + * @return / + */ + ClientIdAndSecretModel readClientIdAndSecret(SaRequest request); + /** * 构建返回值: 获取 token diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolverDefaultImpl.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolverDefaultImpl.java index 1d437eb7..cd7641a2 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolverDefaultImpl.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/data/resolver/SaOAuth2DataResolverDefaultImpl.java @@ -15,10 +15,16 @@ */ package cn.dev33.satoken.oauth2.data.resolver; +import cn.dev33.satoken.context.model.SaRequest; +import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil; import cn.dev33.satoken.oauth2.SaOAuth2Manager; +import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.TokenType; import cn.dev33.satoken.oauth2.data.model.AccessTokenModel; import cn.dev33.satoken.oauth2.data.model.ClientTokenModel; +import cn.dev33.satoken.oauth2.data.model.other.ClientIdAndSecretModel; +import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception; +import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaResult; import java.util.LinkedHashMap; @@ -34,6 +40,37 @@ import java.util.Map; */ public class SaOAuth2DataResolverDefaultImpl implements SaOAuth2DataResolver { + + /** + * 数据读取:从请求对象中读取 ClientId、Secret,如果获取不到则抛出异常 + * + * @param request / + * @return / + */ + @Override + public ClientIdAndSecretModel readClientIdAndSecret(SaRequest request) { + // 优先从请求参数中获取 + String clientId = request.getParam(SaOAuth2Consts.Param.client_id); + String clientSecret = request.getParam(SaOAuth2Consts.Param.client_secret); + if(SaFoxUtil.isNotEmpty(clientId)) { + return new ClientIdAndSecretModel(clientId, clientSecret); + } + + // 如果请求参数中没有提供 client_id 参数,则尝试从 base auth 中获取 + String authorizationValue = SaHttpBasicUtil.getAuthorizationValue(); + if(SaFoxUtil.isNotEmpty(authorizationValue)) { + String[] arr = authorizationValue.split(":"); + clientId = arr[0]; + if(arr.length > 1) { + clientSecret = arr[1]; + } + return new ClientIdAndSecretModel(clientId, clientSecret); + } + + // 如果都没有提供,则抛出异常 + throw new SaOAuth2Exception("请提供 client 信息"); + } + /** * 构建返回值: 获取 token */ diff --git a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java index f732d813..fccf246d 100644 --- a/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java +++ b/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/processor/SaOAuth2ServerProcessor.java @@ -18,7 +18,6 @@ package cn.dev33.satoken.oauth2.processor; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.model.SaRequest; import cn.dev33.satoken.context.model.SaResponse; -import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil; import cn.dev33.satoken.oauth2.SaOAuth2Manager; import cn.dev33.satoken.oauth2.config.SaOAuth2Config; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts; @@ -27,12 +26,12 @@ import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.GrantType; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Param; import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.ResponseType; import cn.dev33.satoken.oauth2.data.model.*; +import cn.dev33.satoken.oauth2.data.model.other.ClientIdAndSecretModel; import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode; import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception; import cn.dev33.satoken.oauth2.template.SaOAuth2Template; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; -import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaResult; import java.util.List; @@ -190,20 +189,9 @@ public class SaOAuth2ServerProcessor { SaRequest req = SaHolder.getRequest(); // 获取参数 - String authorizationValue = SaHttpBasicUtil.getAuthorizationValue(); - String clientId; - String clientSecret; - - // gitlab 回调 token 接口时,按照的是标准的oauth2协议的basic请求头,basic中会包含client_id和client_secret的信息 - if(SaFoxUtil.isEmpty(authorizationValue)){ - clientId = req.getParamNotNull(Param.client_id); - clientSecret = req.getParamNotNull(Param.client_secret); - } else { - String[] clientIdAndSecret = authorizationValue.split(":"); - clientId = clientIdAndSecret[0]; - clientSecret = clientIdAndSecret[1]; - } - + ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req); + String clientId = clientIdAndSecret.clientId; + String clientSecret = clientIdAndSecret.clientSecret; String code = req.getParamNotNull(Param.code); String redirectUri = req.getParam(Param.redirect_uri); @@ -226,8 +214,10 @@ public class SaOAuth2ServerProcessor { SaRequest req = SaHolder.getRequest(); // 获取参数 - String clientId = req.getParamNotNull(Param.client_id); - String clientSecret = req.getParamNotNull(Param.client_secret); + + ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req); + String clientId = clientIdAndSecret.clientId; + String clientSecret = clientIdAndSecret.clientSecret; String refreshToken = req.getParamNotNull(Param.refresh_token); // 校验参数 @@ -249,8 +239,9 @@ public class SaOAuth2ServerProcessor { SaRequest req = SaHolder.getRequest(); // 获取参数 - String clientId = req.getParamNotNull(Param.client_id); - String clientSecret = req.getParamNotNull(Param.client_secret); + ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req); + String clientId = clientIdAndSecret.clientId; + String clientSecret = clientIdAndSecret.clientSecret; String accessToken = req.getParamNotNull(Param.access_token); // 如果 Access-Token 不存在,直接返回 @@ -308,8 +299,9 @@ public class SaOAuth2ServerProcessor { // 1、获取请求参数 String username = req.getParamNotNull(Param.username); String password = req.getParamNotNull(Param.password); - String clientId = req.getParamNotNull(Param.client_id); - String clientSecret = req.getParamNotNull(Param.client_secret); + ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req); + String clientId = clientIdAndSecret.clientId; + String clientSecret = clientIdAndSecret.clientSecret; String scope = req.getParam(Param.scope, ""); List scopes = SaOAuth2Manager.getDataConverter().convertScopeStringToList(scope); @@ -347,8 +339,9 @@ public class SaOAuth2ServerProcessor { SaRequest req = SaHolder.getRequest(); // 获取参数 - String clientId = req.getParamNotNull(Param.client_id); - String clientSecret = req.getParamNotNull(Param.client_secret); + ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req); + String clientId = clientIdAndSecret.clientId; + String clientSecret = clientIdAndSecret.clientSecret; String scope = req.getParam(Param.scope, ""); List scopes = SaOAuth2Manager.getDataConverter().convertScopeStringToList(scope); @@ -370,8 +363,8 @@ public class SaOAuth2ServerProcessor { * @return / */ public SaClientModel currClientModel() { - String clientId = SaHolder.getRequest().getParam(Param.client_id); - return oauth2Template.checkClientModel(clientId); + ClientIdAndSecretModel clientIdAndSecret = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(SaHolder.getRequest()); + return oauth2Template.checkClientModel(clientIdAndSecret.clientId); } /**