兼容从 basic auth 请求头中读取 client 信息

This commit is contained in:
click33 2024-08-16 18:50:10 +08:00
parent 12c645aaed
commit 7f745a7ba4
5 changed files with 154 additions and 26 deletions

View File

@ -60,5 +60,6 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter {
}
return SaFoxUtil.convertStringToList(allowUrl);
}
}

View File

@ -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 + '\'' +
'}';
}
}

View File

@ -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 {
/**
* 数据读取从请求对象中读取 ClientIdSecret
*
* @param request /
* @return /
*/
ClientIdAndSecretModel readClientIdAndSecret(SaRequest request);
/**
* 构建返回值: 获取 token

View File

@ -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 {
/**
* 数据读取从请求对象中读取 ClientIdSecret如果获取不到则抛出异常
*
* @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
*/

View File

@ -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<String> 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<String> 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);
}
/**