mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-12-26 22:25:39 +08:00
新增 SaOAuth2DataResolver 数据解析器,负责 Web 交互层面的数据进出
This commit is contained in:
@@ -16,8 +16,10 @@
|
||||
package cn.dev33.satoken.oauth2;
|
||||
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.dataloader.SaOAuth2DataLoader;
|
||||
import cn.dev33.satoken.oauth2.dataloader.SaOAuth2DataLoaderDefaultImpl;
|
||||
import cn.dev33.satoken.oauth2.data.loader.SaOAuth2DataLoader;
|
||||
import cn.dev33.satoken.oauth2.data.loader.SaOAuth2DataLoaderDefaultImpl;
|
||||
import cn.dev33.satoken.oauth2.data.resolver.SaOAuth2DataResolver;
|
||||
import cn.dev33.satoken.oauth2.data.resolver.SaOAuth2DataResolverDefaultImpl;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 模块 总控类
|
||||
@@ -64,4 +66,22 @@ public class SaOAuth2Manager {
|
||||
SaOAuth2Manager.dataLoader = dataLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 数据解析器 Bean
|
||||
*/
|
||||
private static volatile SaOAuth2DataResolver dataResolver;
|
||||
public static SaOAuth2DataResolver getDataResolver() {
|
||||
if (dataResolver == null) {
|
||||
synchronized (SaOAuth2Manager.class) {
|
||||
if (dataResolver == null) {
|
||||
setDataResolver(new SaOAuth2DataResolverDefaultImpl());
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataResolver;
|
||||
}
|
||||
public static void setDataResolver(SaOAuth2DataResolver dataResolver) {
|
||||
SaOAuth2Manager.dataResolver = dataResolver;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,7 +77,22 @@ public class SaOAuth2Consts {
|
||||
public static String client_credentials = "client_credentials";
|
||||
public static String implicit = "implicit";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 所有 token 类型
|
||||
*/
|
||||
public static final class TokenType {
|
||||
// 全小写
|
||||
public static String basic = "basic";
|
||||
public static String digest = "digest";
|
||||
public static String bearer = "bearer";
|
||||
|
||||
// 首字母大写
|
||||
public static String Basic = "Basic";
|
||||
public static String Digest = "Digest";
|
||||
public static String Bearer = "Bearer";
|
||||
}
|
||||
|
||||
/** 表示OK的返回结果 */
|
||||
public static final String OK = "ok";
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.dataloader;
|
||||
package cn.dev33.satoken.oauth2.data.loader;
|
||||
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.dataloader;
|
||||
package cn.dev33.satoken.oauth2.data.loader;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据加载器 默认实现类
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.resolver;
|
||||
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据解析器,负责 Web 交互层面的数据进出:
|
||||
* <p>1、从请求中按照指定格式读取数据</p>
|
||||
* <p>2、构建数据输出格式</p>
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public interface SaOAuth2DataResolver {
|
||||
|
||||
|
||||
/**
|
||||
* 构建返回值: 获取 token
|
||||
* @param at token信息
|
||||
* @return /
|
||||
*/
|
||||
Map<String, Object> buildTokenReturnValue(AccessTokenModel at);
|
||||
|
||||
/**
|
||||
* 构建返回值: RefreshToken 刷新 Access-Token
|
||||
* @param at token信息
|
||||
* @return /
|
||||
*/
|
||||
default Map<String, Object> buildRefreshTokenReturnValue(AccessTokenModel at) {
|
||||
return buildTokenReturnValue(at);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建返回值: 回收 Access-Token
|
||||
* @return /
|
||||
*/
|
||||
default Map<String, Object> buildRevokeTokenReturnValue() {
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建返回值: password 模式认证 获取 token
|
||||
* @param at token信息
|
||||
* @return /
|
||||
*/
|
||||
default Map<String, Object> buildPasswordReturnValue(AccessTokenModel at) {
|
||||
return buildTokenReturnValue(at);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建返回值: 凭证式 模式认证 获取 token
|
||||
* @param ct token信息
|
||||
*/
|
||||
Map<String, Object> buildClientTokenReturnValue(ClientTokenModel ct);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.resolver;
|
||||
|
||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.TokenType;
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据解析器,负责 Web 交互层面的数据进出:
|
||||
* <p>1、从请求中按照指定格式读取数据</p>
|
||||
* <p>2、构建数据输出格式</p>
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public class SaOAuth2DataResolverDefaultImpl implements SaOAuth2DataResolver {
|
||||
|
||||
/**
|
||||
* 构建返回值: 获取 token
|
||||
*/
|
||||
public Map<String, Object> buildTokenReturnValue(AccessTokenModel at) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("token_type", TokenType.bearer);
|
||||
map.put("access_token", at.accessToken);
|
||||
map.put("refresh_token", at.refreshToken);
|
||||
map.put("expires_in", at.getExpiresIn());
|
||||
map.put("refresh_expires_in", at.getRefreshExpiresIn());
|
||||
map.put("client_id", at.clientId);
|
||||
map.put("scope", at.scope);
|
||||
map.put("openid", at.openid);
|
||||
return SaResult.ok().setMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建返回值: password 模式认证 获取 token
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> buildClientTokenReturnValue(ClientTokenModel ct) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("client_token", ct.clientToken);
|
||||
map.put("access_token", ct.clientToken); // 兼容 OAuth2 协议
|
||||
map.put("expires_in", ct.getExpiresIn());
|
||||
map.put("client_id", ct.clientId);
|
||||
map.put("scope", ct.scope);
|
||||
return SaResult.ok().setMap(map);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ public class SaOAuth2ServerProcessor {
|
||||
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
// ------------------ 路由分发 ------------------
|
||||
@@ -187,14 +186,13 @@ public class SaOAuth2ServerProcessor {
|
||||
public Object token() {
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
// 获取参数
|
||||
String authorizationValue = SaHttpBasicUtil.getAuthorizationValue();
|
||||
String clientId;
|
||||
String clientSecret;
|
||||
// gitlab回调token接口时,按照的是标准的oauth2协议的basic请求头,basic中会包含client_id和client_secret的信息
|
||||
|
||||
// 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);
|
||||
@@ -211,10 +209,10 @@ public class SaOAuth2ServerProcessor {
|
||||
oauth2Template.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
|
||||
// 构建 Access-Token
|
||||
AccessTokenModel token = oauth2Template.generateAccessToken(code);
|
||||
AccessTokenModel accessTokenModel = oauth2Template.generateAccessToken(code);
|
||||
|
||||
// 返回
|
||||
return SaResult.data(token.toLineMap());
|
||||
return SaOAuth2Manager.getDataResolver().buildTokenReturnValue(accessTokenModel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,9 +231,11 @@ public class SaOAuth2ServerProcessor {
|
||||
// 校验参数
|
||||
oauth2Template.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
|
||||
// 获取新Token返回
|
||||
Object data = oauth2Template.refreshAccessToken(refreshToken).toLineMap();
|
||||
return SaResult.data(data);
|
||||
// 获取新 Access-Token
|
||||
AccessTokenModel accessTokenModel = oauth2Template.refreshAccessToken(refreshToken);
|
||||
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildRefreshTokenReturnValue(accessTokenModel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,7 +261,9 @@ public class SaOAuth2ServerProcessor {
|
||||
|
||||
// 回收 Access-Token
|
||||
oauth2Template.revokeAccessToken(accessToken);
|
||||
return SaResult.ok();
|
||||
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildRevokeTokenReturnValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,7 +273,6 @@ public class SaOAuth2ServerProcessor {
|
||||
public Object doLogin() {
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
return cfg.getDoLoginHandle().apply(req.getParamNotNull(Param.name), req.getParamNotNull(Param.pwd));
|
||||
@@ -330,7 +331,7 @@ public class SaOAuth2ServerProcessor {
|
||||
AccessTokenModel at = oauth2Template.generateAccessToken(ra, true);
|
||||
|
||||
// 6、返回 Access-Token
|
||||
return SaResult.data(at.toLineMap());
|
||||
return SaOAuth2Manager.getDataResolver().buildPasswordReturnValue(at);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,8 +341,6 @@ public class SaOAuth2ServerProcessor {
|
||||
public Object clientToken() {
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
@@ -354,11 +353,11 @@ public class SaOAuth2ServerProcessor {
|
||||
// 校验 ClientSecret
|
||||
oauth2Template.checkClientSecret(clientId, clientSecret);
|
||||
|
||||
// 返回 Client-Token
|
||||
// 生成
|
||||
ClientTokenModel ct = oauth2Template.generateClientToken(clientId, scope);
|
||||
|
||||
// 返回 Client-Token
|
||||
return SaResult.data(ct.toLineMap());
|
||||
// 返回
|
||||
return SaOAuth2Manager.getDataResolver().buildClientTokenReturnValue(ct);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user