mirror of
https://gitee.com/dromara/sa-token.git
synced 2024-11-29 18:37:49 +08:00
重构 sa-token-oauth2:提取数据加载器 Bean,提供更方便的自定义数据加载方案。
This commit is contained in:
parent
101a577ded
commit
eeed140424
@ -60,11 +60,11 @@
|
||||
</dependency>
|
||||
|
||||
<!-- 热刷新 -->
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
|
||||
<!-- ConfigurationProperties -->
|
||||
<dependency>
|
||||
|
@ -1,18 +1,18 @@
|
||||
package com.pj.oauth2;
|
||||
|
||||
import cn.dev33.satoken.oauth2.dataloader.SaOAuth2DataLoader;
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2.0 整合实现
|
||||
* Sa-Token OAuth2:自定义数据加载器
|
||||
*
|
||||
* @author click33
|
||||
*/
|
||||
@Component
|
||||
public class SaOAuth2TemplateImpl extends SaOAuth2Template {
|
||||
public class SaOAuth2DataLoaderImpl implements SaOAuth2DataLoader {
|
||||
|
||||
// 根据 id 获取 Client 信息
|
||||
// 根据 client_id 获取 Client 信息
|
||||
@Override
|
||||
public SaClientModel getClientModel(String clientId) {
|
||||
// 此为模拟数据,真实环境需要从数据库查询
|
||||
@ -33,7 +33,5 @@ public class SaOAuth2TemplateImpl extends SaOAuth2Template {
|
||||
// 此为模拟数据,真实环境需要从数据库查询
|
||||
return "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__";
|
||||
}
|
||||
|
||||
// -------------- 其它需要重写的函数
|
||||
|
||||
|
||||
}
|
@ -1,21 +1,20 @@
|
||||
package com.pj.oauth2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.processor.SaOAuth2ServerProcessor;
|
||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Util;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sa-OAuth2 Server端 控制器
|
||||
@ -29,7 +28,7 @@ public class SaOAuth2ServerController {
|
||||
@RequestMapping("/oauth2/*")
|
||||
public Object request() {
|
||||
System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
|
||||
return SaOAuth2Handle.serverRequest();
|
||||
return SaOAuth2ServerProcessor.instance.dister();
|
||||
}
|
||||
|
||||
// Sa-OAuth2 定制化配置
|
||||
|
@ -16,6 +16,8 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 模块 总控类
|
||||
@ -44,4 +46,22 @@ public class SaOAuth2Manager {
|
||||
SaOAuth2Manager.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 数据加载器 Bean
|
||||
*/
|
||||
private static volatile SaOAuth2DataLoader dataLoader;
|
||||
public static SaOAuth2DataLoader getDataLoader() {
|
||||
if (dataLoader == null) {
|
||||
synchronized (SaOAuth2Manager.class) {
|
||||
if (dataLoader == null) {
|
||||
setDataLoader(new SaOAuth2DataLoaderDefaultImpl());
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataLoader;
|
||||
}
|
||||
public static void setDataLoader(SaOAuth2DataLoader dataLoader) {
|
||||
SaOAuth2Manager.dataLoader = dataLoader;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,10 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
package cn.dev33.satoken.oauth2.consts;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 所有常量
|
||||
* Sa-Token OAuth2 所有常量
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.23.0
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.dataloader;
|
||||
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据加载器
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public interface SaOAuth2DataLoader {
|
||||
|
||||
/**
|
||||
* 根据 id 获取 Client 信息
|
||||
*
|
||||
* @param clientId 应用id
|
||||
* @return ClientModel
|
||||
*/
|
||||
default SaClientModel getClientModel(String clientId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ClientId 和 LoginId 获取openid
|
||||
*
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @return 此账号在此Client下的openid
|
||||
*/
|
||||
default String getOpenid(String clientId, Object loginId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.dataloader;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 数据加载器 默认实现类
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public class SaOAuth2DataLoaderDefaultImpl implements SaOAuth2DataLoader{
|
||||
|
||||
// be empty of
|
||||
|
||||
}
|
@ -1,348 +1,360 @@
|
||||
/*
|
||||
* 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.logic;
|
||||
|
||||
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.error.SaOAuth2ErrorCode;
|
||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Api;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.GrantType;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Param;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.ResponseType;
|
||||
import cn.dev33.satoken.oauth2.model.*;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 请求处理类封装
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.23.0
|
||||
*/
|
||||
public class SaOAuth2Handle {
|
||||
|
||||
/**
|
||||
* 处理Server端请求, 路由分发
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object serverRequest() {
|
||||
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
// ------------------ 路由分发 ------------------
|
||||
|
||||
// 模式一:Code授权码
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsCode() && (cm.isCode || cm.isAutoMode)) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30131);
|
||||
}
|
||||
|
||||
// Code授权码 获取 Access-Token
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) {
|
||||
return token(req, res, cfg);
|
||||
}
|
||||
|
||||
// Refresh-Token 刷新 Access-Token
|
||||
if(req.isPath(Api.refresh) && req.isParam(Param.grant_type, GrantType.refresh_token)) {
|
||||
return refreshToken(req);
|
||||
}
|
||||
|
||||
// 回收 Access-Token
|
||||
if(req.isPath(Api.revoke)) {
|
||||
return revokeToken(req);
|
||||
}
|
||||
|
||||
// doLogin 登录接口
|
||||
if(req.isPath(Api.doLogin)) {
|
||||
return doLogin(req, res, cfg);
|
||||
}
|
||||
|
||||
// doConfirm 确认授权接口
|
||||
if(req.isPath(Api.doConfirm)) {
|
||||
return doConfirm(req);
|
||||
}
|
||||
|
||||
// 模式二:隐藏式
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsImplicit() && (cm.isImplicit || cm.isAutoMode)) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30132);
|
||||
}
|
||||
|
||||
// 模式三:密码式
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsPassword() && (cm.isPassword || cm.isAutoMode)) {
|
||||
return password(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30133);
|
||||
}
|
||||
|
||||
// 模式四:凭证式
|
||||
if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsClient() && (cm.isClient || cm.isAutoMode)) {
|
||||
return clientToken(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30134);
|
||||
}
|
||||
|
||||
// 默认返回
|
||||
return SaOAuth2Consts.NOT_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式一:Code授权码 / 模式二:隐藏式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 1、如果尚未登录, 则先去登录
|
||||
if( ! StpUtil.isLogin()) {
|
||||
return cfg.getNotLoginView().get();
|
||||
}
|
||||
|
||||
// 2、构建请求Model
|
||||
RequestAuthModel ra = SaOAuth2Util.generateRequestAuth(req, StpUtil.getLoginId());
|
||||
|
||||
// 3、校验:重定向域名是否合法
|
||||
SaOAuth2Util.checkRightUrl(ra.clientId, ra.redirectUri);
|
||||
|
||||
// 4、校验:此次申请的Scope,该Client是否已经签约
|
||||
SaOAuth2Util.checkContract(ra.clientId, ra.scope);
|
||||
|
||||
// 5、判断:如果此次申请的Scope,该用户尚未授权,则转到授权页面
|
||||
boolean isGrant = SaOAuth2Util.isGrant(ra.loginId, ra.clientId, ra.scope);
|
||||
if( ! isGrant) {
|
||||
return cfg.getConfirmView().apply(ra.clientId, ra.scope);
|
||||
}
|
||||
|
||||
// 6、判断授权类型
|
||||
// 如果是 授权码式,则:开始重定向授权,下放code
|
||||
if(ResponseType.code.equals(ra.responseType)) {
|
||||
CodeModel codeModel = SaOAuth2Util.generateCode(ra);
|
||||
String redirectUri = SaOAuth2Util.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
if(ResponseType.token.equals(ra.responseType)) {
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false);
|
||||
String redirectUri = SaOAuth2Util.buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 默认返回
|
||||
throw new SaOAuth2Exception("无效response_type: " + ra.responseType).setCode(SaOAuth2ErrorCode.CODE_30125);
|
||||
}
|
||||
|
||||
/**
|
||||
* Code授权码 获取 Access-Token
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
// 获取参数
|
||||
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];
|
||||
}
|
||||
|
||||
String code = req.getParamNotNull(Param.code);
|
||||
String redirectUri = req.getParam(Param.redirect_uri);
|
||||
|
||||
// 校验参数
|
||||
SaOAuth2Util.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
|
||||
// 构建 Access-Token
|
||||
AccessTokenModel token = SaOAuth2Util.generateAccessToken(code);
|
||||
|
||||
// 返回
|
||||
return SaResult.data(token.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh-Token 刷新 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object refreshToken(SaRequest req) {
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String refreshToken = req.getParamNotNull(Param.refresh_token);
|
||||
|
||||
// 校验参数
|
||||
SaOAuth2Util.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
|
||||
// 获取新Token返回
|
||||
Object data = SaOAuth2Util.refreshAccessToken(refreshToken).toLineMap();
|
||||
return SaResult.data(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object revokeToken(SaRequest req) {
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String accessToken = req.getParamNotNull(Param.access_token);
|
||||
|
||||
// 如果 Access-Token 不存在,直接返回
|
||||
if(SaOAuth2Util.getAccessToken(accessToken) == null) {
|
||||
return SaResult.ok("access_token不存在:" + accessToken);
|
||||
}
|
||||
|
||||
// 校验参数
|
||||
SaOAuth2Util.checkAccessTokenParam(clientId, clientSecret, accessToken);
|
||||
|
||||
// 回收 Access-Token
|
||||
SaOAuth2Util.revokeAccessToken(accessToken);
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* doLogin 登录接口
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object doLogin(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
return cfg.getDoLoginHandle().apply(req.getParamNotNull(Param.name), req.getParamNotNull(Param.pwd));
|
||||
}
|
||||
|
||||
/**
|
||||
* doConfirm 确认授权接口
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object doConfirm(SaRequest req) {
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String scope = req.getParamNotNull(Param.scope);
|
||||
Object loginId = StpUtil.getLoginId();
|
||||
SaOAuth2Util.saveGrantScope(clientId, loginId, scope);
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式三:密码式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object password(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 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);
|
||||
String scope = req.getParam(Param.scope, "");
|
||||
|
||||
// 2、校验 ClientScope 和 scope
|
||||
SaOAuth2Util.checkClientSecretAndScope(clientId, clientSecret, scope);
|
||||
|
||||
// 3、防止因前端误传token造成逻辑干扰
|
||||
// SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token");
|
||||
|
||||
// 3、调用API 开始登录,如果没能成功登录,则直接退出
|
||||
Object retObj = cfg.getDoLoginHandle().apply(username, password);
|
||||
if( ! StpUtil.isLogin()) {
|
||||
return retObj;
|
||||
}
|
||||
|
||||
// 4、构建 ra对象
|
||||
RequestAuthModel ra = new RequestAuthModel();
|
||||
ra.clientId = clientId;
|
||||
ra.loginId = StpUtil.getLoginId();
|
||||
ra.scope = scope;
|
||||
|
||||
// 5、生成 Access-Token
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true);
|
||||
|
||||
// 6、返回 Access-Token
|
||||
return SaResult.data(at.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式四:凭证式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object clientToken(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String scope = req.getParam(Param.scope);
|
||||
|
||||
//校验 ClientScope
|
||||
SaOAuth2Util.checkContract(clientId, scope);
|
||||
|
||||
// 校验 ClientSecret
|
||||
SaOAuth2Util.checkClientSecret(clientId, clientSecret);
|
||||
|
||||
// 返回 Client-Token
|
||||
ClientTokenModel ct = SaOAuth2Util.generateClientToken(clientId, scope);
|
||||
|
||||
// 返回 Client-Token
|
||||
return SaResult.data(ct.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前请求提交的 client_id 参数获取 SaClientModel 对象
|
||||
* @return /
|
||||
*/
|
||||
public static SaClientModel currClientModel() {
|
||||
String clientId = SaHolder.getRequest().getParam(Param.client_id);
|
||||
return SaOAuth2Util.checkClientModel(clientId);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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.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.error.SaOAuth2ErrorCode;
|
||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||
import cn.dev33.satoken.oauth2.model.*;
|
||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Api;
|
||||
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.template.SaOAuth2Template;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 请求处理器
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.23.0
|
||||
*/
|
||||
public class SaOAuth2ServerProcessor {
|
||||
|
||||
/**
|
||||
* 全局默认实例
|
||||
*/
|
||||
public static SaOAuth2ServerProcessor instance = new SaOAuth2ServerProcessor();
|
||||
|
||||
/**
|
||||
* 底层 SaOAuth2Template 对象
|
||||
*/
|
||||
public SaOAuth2Template oauth2Template = new SaOAuth2Template();
|
||||
|
||||
/**
|
||||
* 处理 Server 端请求, 路由分发
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object dister() {
|
||||
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
// ------------------ 路由分发 ------------------
|
||||
|
||||
// 模式一:Code授权码
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsCode() && (cm.isCode || cm.isAutoMode)) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30131);
|
||||
}
|
||||
|
||||
// Code授权码 获取 Access-Token
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) {
|
||||
return token(req, res, cfg);
|
||||
}
|
||||
|
||||
// Refresh-Token 刷新 Access-Token
|
||||
if(req.isPath(Api.refresh) && req.isParam(Param.grant_type, GrantType.refresh_token)) {
|
||||
return refreshToken(req);
|
||||
}
|
||||
|
||||
// 回收 Access-Token
|
||||
if(req.isPath(Api.revoke)) {
|
||||
return revokeToken(req);
|
||||
}
|
||||
|
||||
// doLogin 登录接口
|
||||
if(req.isPath(Api.doLogin)) {
|
||||
return doLogin(req, res, cfg);
|
||||
}
|
||||
|
||||
// doConfirm 确认授权接口
|
||||
if(req.isPath(Api.doConfirm)) {
|
||||
return doConfirm(req);
|
||||
}
|
||||
|
||||
// 模式二:隐藏式
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsImplicit() && (cm.isImplicit || cm.isAutoMode)) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30132);
|
||||
}
|
||||
|
||||
// 模式三:密码式
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsPassword() && (cm.isPassword || cm.isAutoMode)) {
|
||||
return password(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30133);
|
||||
}
|
||||
|
||||
// 模式四:凭证式
|
||||
if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.getIsClient() && (cm.isClient || cm.isAutoMode)) {
|
||||
return clientToken(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30134);
|
||||
}
|
||||
|
||||
// 默认返回
|
||||
return SaOAuth2Consts.NOT_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式一:Code授权码 / 模式二:隐藏式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 1、如果尚未登录, 则先去登录
|
||||
if( ! StpUtil.isLogin()) {
|
||||
return cfg.getNotLoginView().get();
|
||||
}
|
||||
|
||||
// 2、构建请求Model
|
||||
RequestAuthModel ra = oauth2Template.generateRequestAuth(req, StpUtil.getLoginId());
|
||||
|
||||
// 3、校验:重定向域名是否合法
|
||||
oauth2Template.checkRightUrl(ra.clientId, ra.redirectUri);
|
||||
|
||||
// 4、校验:此次申请的Scope,该Client是否已经签约
|
||||
oauth2Template.checkContract(ra.clientId, ra.scope);
|
||||
|
||||
// 5、判断:如果此次申请的Scope,该用户尚未授权,则转到授权页面
|
||||
boolean isGrant = oauth2Template.isGrant(ra.loginId, ra.clientId, ra.scope);
|
||||
if( ! isGrant) {
|
||||
return cfg.getConfirmView().apply(ra.clientId, ra.scope);
|
||||
}
|
||||
|
||||
// 6、判断授权类型
|
||||
// 如果是 授权码式,则:开始重定向授权,下放code
|
||||
if(ResponseType.code.equals(ra.responseType)) {
|
||||
CodeModel codeModel = oauth2Template.generateCode(ra);
|
||||
String redirectUri = oauth2Template.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
if(ResponseType.token.equals(ra.responseType)) {
|
||||
AccessTokenModel at = oauth2Template.generateAccessToken(ra, false);
|
||||
String redirectUri = oauth2Template.buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 默认返回
|
||||
throw new SaOAuth2Exception("无效response_type: " + ra.responseType).setCode(SaOAuth2ErrorCode.CODE_30125);
|
||||
}
|
||||
|
||||
/**
|
||||
* Code授权码 获取 Access-Token
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
// 获取参数
|
||||
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];
|
||||
}
|
||||
|
||||
String code = req.getParamNotNull(Param.code);
|
||||
String redirectUri = req.getParam(Param.redirect_uri);
|
||||
|
||||
// 校验参数
|
||||
oauth2Template.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
|
||||
// 构建 Access-Token
|
||||
AccessTokenModel token = oauth2Template.generateAccessToken(code);
|
||||
|
||||
// 返回
|
||||
return SaResult.data(token.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh-Token 刷新 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object refreshToken(SaRequest req) {
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String refreshToken = req.getParamNotNull(Param.refresh_token);
|
||||
|
||||
// 校验参数
|
||||
oauth2Template.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
|
||||
// 获取新Token返回
|
||||
Object data = oauth2Template.refreshAccessToken(refreshToken).toLineMap();
|
||||
return SaResult.data(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object revokeToken(SaRequest req) {
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String accessToken = req.getParamNotNull(Param.access_token);
|
||||
|
||||
// 如果 Access-Token 不存在,直接返回
|
||||
if(oauth2Template.getAccessToken(accessToken) == null) {
|
||||
return SaResult.ok("access_token不存在:" + accessToken);
|
||||
}
|
||||
|
||||
// 校验参数
|
||||
oauth2Template.checkAccessTokenParam(clientId, clientSecret, accessToken);
|
||||
|
||||
// 回收 Access-Token
|
||||
oauth2Template.revokeAccessToken(accessToken);
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* doLogin 登录接口
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object doLogin(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
return cfg.getDoLoginHandle().apply(req.getParamNotNull(Param.name), req.getParamNotNull(Param.pwd));
|
||||
}
|
||||
|
||||
/**
|
||||
* doConfirm 确认授权接口
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object doConfirm(SaRequest req) {
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String scope = req.getParamNotNull(Param.scope);
|
||||
Object loginId = StpUtil.getLoginId();
|
||||
oauth2Template.saveGrantScope(clientId, loginId, scope);
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式三:密码式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object password(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 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);
|
||||
String scope = req.getParam(Param.scope, "");
|
||||
|
||||
// 2、校验 ClientScope 和 scope
|
||||
oauth2Template.checkClientSecretAndScope(clientId, clientSecret, scope);
|
||||
|
||||
// 3、防止因前端误传token造成逻辑干扰
|
||||
// SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token");
|
||||
|
||||
// 3、调用API 开始登录,如果没能成功登录,则直接退出
|
||||
Object retObj = cfg.getDoLoginHandle().apply(username, password);
|
||||
if( ! StpUtil.isLogin()) {
|
||||
return retObj;
|
||||
}
|
||||
|
||||
// 4、构建 ra对象
|
||||
RequestAuthModel ra = new RequestAuthModel();
|
||||
ra.clientId = clientId;
|
||||
ra.loginId = StpUtil.getLoginId();
|
||||
ra.scope = scope;
|
||||
|
||||
// 5、生成 Access-Token
|
||||
AccessTokenModel at = oauth2Template.generateAccessToken(ra, true);
|
||||
|
||||
// 6、返回 Access-Token
|
||||
return SaResult.data(at.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式四:凭证式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public Object clientToken(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String scope = req.getParam(Param.scope);
|
||||
|
||||
//校验 ClientScope
|
||||
oauth2Template.checkContract(clientId, scope);
|
||||
|
||||
// 校验 ClientSecret
|
||||
oauth2Template.checkClientSecret(clientId, clientSecret);
|
||||
|
||||
// 返回 Client-Token
|
||||
ClientTokenModel ct = oauth2Template.generateClientToken(clientId, scope);
|
||||
|
||||
// 返回 Client-Token
|
||||
return SaResult.data(ct.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前请求提交的 client_id 参数获取 SaClientModel 对象
|
||||
* @return /
|
||||
*/
|
||||
public SaClientModel currClientModel() {
|
||||
String clientId = SaHolder.getRequest().getParam(Param.client_id);
|
||||
return oauth2Template.checkClientModel(clientId);
|
||||
}
|
||||
|
||||
}
|
@ -13,25 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
|
||||
import java.util.List;
|
||||
package cn.dev33.satoken.oauth2.template;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts.Param;
|
||||
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
|
||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Param;
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.model.RefreshTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
import cn.dev33.satoken.oauth2.model.*;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 模块 代码实现
|
||||
*
|
||||
@ -40,15 +35,17 @@ import cn.dev33.satoken.util.SaFoxUtil;
|
||||
*/
|
||||
public class SaOAuth2Template {
|
||||
|
||||
// ------------------- 获取数据 (开发者必须重写的函数)
|
||||
// ------------------- 数据加载
|
||||
|
||||
/**
|
||||
* 根据id获取Client信息
|
||||
* @param clientId 应用id
|
||||
* @return ClientModel
|
||||
*/
|
||||
public SaClientModel getClientModel(String clientId) {
|
||||
return null;
|
||||
return SaOAuth2Manager.getDataLoader().getClientModel(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ClientId 和 LoginId 获取openid
|
||||
* @param clientId 应用id
|
||||
@ -56,7 +53,7 @@ public class SaOAuth2Template {
|
||||
* @return 此账号在此Client下的openid
|
||||
*/
|
||||
public String getOpenid(String clientId, Object loginId) {
|
||||
return null;
|
||||
return SaOAuth2Manager.getDataLoader().getOpenid(clientId, loginId);
|
||||
}
|
||||
|
||||
// ------------------- 资源校验API
|
@ -13,15 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
package cn.dev33.satoken.oauth2.template;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.model.RefreshTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
import cn.dev33.satoken.oauth2.model.*;
|
||||
import cn.dev33.satoken.oauth2.processor.SaOAuth2ServerProcessor;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 模块 工具类
|
||||
@ -30,12 +26,6 @@ import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
* @since 1.23.0
|
||||
*/
|
||||
public class SaOAuth2Util {
|
||||
|
||||
/**
|
||||
* 模板代码对象
|
||||
*/
|
||||
public static SaOAuth2Template saOAuth2Template = new SaOAuth2Template();
|
||||
|
||||
|
||||
// ------------------- 资源校验API
|
||||
|
||||
@ -45,7 +35,7 @@ public class SaOAuth2Util {
|
||||
* @return ClientModel
|
||||
*/
|
||||
public static SaClientModel checkClientModel(String clientId) {
|
||||
return saOAuth2Template.checkClientModel(clientId);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkClientModel(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,7 +44,7 @@ public class SaOAuth2Util {
|
||||
* @return .
|
||||
*/
|
||||
public static AccessTokenModel checkAccessToken(String accessToken) {
|
||||
return saOAuth2Template.checkAccessToken(accessToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +53,7 @@ public class SaOAuth2Util {
|
||||
* @return .
|
||||
*/
|
||||
public static ClientTokenModel checkClientToken(String clientToken) {
|
||||
return saOAuth2Template.checkClientToken(clientToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkClientToken(clientToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +62,7 @@ public class SaOAuth2Util {
|
||||
* @return LoginId
|
||||
*/
|
||||
public static Object getLoginIdByAccessToken(String accessToken) {
|
||||
return saOAuth2Template.getLoginIdByAccessToken(accessToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.getLoginIdByAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,7 +71,7 @@ public class SaOAuth2Util {
|
||||
* @param scopes 需要校验的权限列表
|
||||
*/
|
||||
public static void checkScope(String accessToken, String... scopes) {
|
||||
saOAuth2Template.checkScope(accessToken, scopes);
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.checkScope(accessToken, scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +80,7 @@ public class SaOAuth2Util {
|
||||
* @param scopes 需要校验的权限列表
|
||||
*/
|
||||
public static void checkClientTokenScope(String clientToken, String... scopes) {
|
||||
saOAuth2Template.checkClientTokenScope(clientToken, scopes);
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.checkClientTokenScope(clientToken, scopes);
|
||||
}
|
||||
|
||||
// ------------------- generate 构建数据
|
||||
@ -102,7 +92,7 @@ public class SaOAuth2Util {
|
||||
* @return RequestAuthModel对象
|
||||
*/
|
||||
public static RequestAuthModel generateRequestAuth(SaRequest req, Object loginId) {
|
||||
return saOAuth2Template.generateRequestAuth(req, loginId);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateRequestAuth(req, loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +101,7 @@ public class SaOAuth2Util {
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public static CodeModel generateCode(RequestAuthModel ra) {
|
||||
return saOAuth2Template.generateCode(ra);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateCode(ra);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,7 +110,7 @@ public class SaOAuth2Util {
|
||||
* @return AccessToken Model
|
||||
*/
|
||||
public static AccessTokenModel generateAccessToken(String code) {
|
||||
return saOAuth2Template.generateAccessToken(code);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateAccessToken(code);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,7 +119,7 @@ public class SaOAuth2Util {
|
||||
* @return 新的 Access-Token
|
||||
*/
|
||||
public static AccessTokenModel refreshAccessToken(String refreshToken) {
|
||||
return saOAuth2Template.refreshAccessToken(refreshToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.refreshAccessToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +129,7 @@ public class SaOAuth2Util {
|
||||
* @return Access-Token Model
|
||||
*/
|
||||
public static AccessTokenModel generateAccessToken(RequestAuthModel ra, boolean isCreateRt) {
|
||||
return saOAuth2Template.generateAccessToken(ra, isCreateRt);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateAccessToken(ra, isCreateRt);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,7 +139,7 @@ public class SaOAuth2Util {
|
||||
* @return Client-Token Model
|
||||
*/
|
||||
public static ClientTokenModel generateClientToken(String clientId, String scope) {
|
||||
return saOAuth2Template.generateClientToken(clientId, scope);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.generateClientToken(clientId, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +150,7 @@ public class SaOAuth2Util {
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public static String buildRedirectUri(String redirectUri, String code, String state) {
|
||||
return saOAuth2Template.buildRedirectUri(redirectUri, code, state);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.buildRedirectUri(redirectUri, code, state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,7 +161,7 @@ public class SaOAuth2Util {
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public static String buildImplicitRedirectUri(String redirectUri, String token, String state) {
|
||||
return saOAuth2Template.buildImplicitRedirectUri(redirectUri, token, state);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.buildImplicitRedirectUri(redirectUri, token, state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,7 +169,7 @@ public class SaOAuth2Util {
|
||||
* @param accessToken Access-Token值
|
||||
*/
|
||||
public static void revokeAccessToken(String accessToken) {
|
||||
saOAuth2Template.revokeAccessToken(accessToken);
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.revokeAccessToken(accessToken);
|
||||
}
|
||||
|
||||
// ------------------- 数据校验
|
||||
@ -192,7 +182,7 @@ public class SaOAuth2Util {
|
||||
* @return 是否已经授权
|
||||
*/
|
||||
public static boolean isGrant(Object loginId, String clientId, String scope) {
|
||||
return saOAuth2Template.isGrant(loginId, clientId, scope);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.isGrant(loginId, clientId, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,7 +191,7 @@ public class SaOAuth2Util {
|
||||
* @param scope 权限(多个用逗号隔开)
|
||||
*/
|
||||
public static void checkContract(String clientId, String scope) {
|
||||
saOAuth2Template.checkContract(clientId, scope);
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.checkContract(clientId, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,7 +200,7 @@ public class SaOAuth2Util {
|
||||
* @param url 指定url
|
||||
*/
|
||||
public static void checkRightUrl(String clientId, String url) {
|
||||
saOAuth2Template.checkRightUrl(clientId, url);
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.checkRightUrl(clientId, url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +210,7 @@ public class SaOAuth2Util {
|
||||
* @return SaClientModel对象
|
||||
*/
|
||||
public static SaClientModel checkClientSecret(String clientId, String clientSecret) {
|
||||
return saOAuth2Template.checkClientSecret(clientId, clientSecret);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkClientSecret(clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +221,7 @@ public class SaOAuth2Util {
|
||||
* @return SaClientModel对象
|
||||
*/
|
||||
public static SaClientModel checkClientSecretAndScope(String clientId, String clientSecret, String scopes) {
|
||||
return saOAuth2Template.checkClientSecretAndScope(clientId, clientSecret, scopes);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkClientSecretAndScope(clientId, clientSecret, scopes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,7 +233,7 @@ public class SaOAuth2Util {
|
||||
* @return CodeModel对象
|
||||
*/
|
||||
public static CodeModel checkGainTokenParam(String code, String clientId, String clientSecret, String redirectUri) {
|
||||
return saOAuth2Template.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,7 +244,7 @@ public class SaOAuth2Util {
|
||||
* @return CodeModel对象
|
||||
*/
|
||||
public static RefreshTokenModel checkRefreshTokenParam(String clientId, String clientSecret, String refreshToken) {
|
||||
return saOAuth2Template.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,7 +255,7 @@ public class SaOAuth2Util {
|
||||
* @return SaClientModel对象
|
||||
*/
|
||||
public static AccessTokenModel checkAccessTokenParam(String clientId, String clientSecret, String accessToken) {
|
||||
return saOAuth2Template.checkAccessTokenParam(clientId, clientSecret, accessToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.checkAccessTokenParam(clientId, clientSecret, accessToken);
|
||||
}
|
||||
|
||||
// ------------------- save 数据
|
||||
@ -277,7 +267,7 @@ public class SaOAuth2Util {
|
||||
* @param scope 权限列表(多个逗号隔开)
|
||||
*/
|
||||
public static void saveGrantScope(String clientId, Object loginId, String scope) {
|
||||
saOAuth2Template.saveGrantScope(clientId, loginId, scope);
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template.saveGrantScope(clientId, loginId, scope);
|
||||
}
|
||||
|
||||
|
||||
@ -289,7 +279,7 @@ public class SaOAuth2Util {
|
||||
* @return .
|
||||
*/
|
||||
public static CodeModel getCode(String code) {
|
||||
return saOAuth2Template.getCode(code);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.getCode(code);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,7 +288,7 @@ public class SaOAuth2Util {
|
||||
* @return .
|
||||
*/
|
||||
public static AccessTokenModel getAccessToken(String accessToken) {
|
||||
return saOAuth2Template.getAccessToken(accessToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.getAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,7 +297,7 @@ public class SaOAuth2Util {
|
||||
* @return .
|
||||
*/
|
||||
public static RefreshTokenModel getRefreshToken(String refreshToken) {
|
||||
return saOAuth2Template.getRefreshToken(refreshToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.getRefreshToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,7 +306,7 @@ public class SaOAuth2Util {
|
||||
* @return .
|
||||
*/
|
||||
public static ClientTokenModel getClientToken(String clientToken) {
|
||||
return saOAuth2Template.getClientToken(clientToken);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.getClientToken(clientToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,7 +316,7 @@ public class SaOAuth2Util {
|
||||
* @return 权限
|
||||
*/
|
||||
public static String getGrantScope(String clientId, Object loginId) {
|
||||
return saOAuth2Template.getGrantScope(clientId, loginId);
|
||||
return SaOAuth2ServerProcessor.instance.oauth2Template.getGrantScope(clientId, loginId);
|
||||
}
|
||||
|
||||
}
|
@ -17,8 +17,8 @@ package cn.dev33.satoken.solon.oauth2;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
|
||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Template;
|
||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Util;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Condition;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
|
@ -15,18 +15,18 @@
|
||||
*/
|
||||
package cn.dev33.satoken.spring.oauth2;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.dataloader.SaOAuth2DataLoader;
|
||||
import cn.dev33.satoken.oauth2.processor.SaOAuth2ServerProcessor;
|
||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Template;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
|
||||
|
||||
/*
|
||||
小提示:如果你在 idea 中运行源码时出现异常:java: 程序包cn.dev33.satoken.oauth2不存在。
|
||||
在项目根目录进入 cmd,执行 mvn package 即可解决
|
||||
*/
|
||||
// 小提示:如果你在 idea 中运行源码时出现异常:java: 程序包cn.dev33.satoken.oauth2不存在。
|
||||
// 在项目根目录进入 cmd,执行 mvn package 即可解决
|
||||
|
||||
|
||||
/**
|
||||
* 注入 Sa-Token-OAuth2 所需要的组件
|
||||
@ -54,7 +54,17 @@ public class SaOAuth2BeanInject {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaOAuth2Interface(SaOAuth2Template saOAuth2Template) {
|
||||
SaOAuth2Util.saOAuth2Template = saOAuth2Template;
|
||||
SaOAuth2ServerProcessor.instance.oauth2Template = saOAuth2Template;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注入 OAuth2 数据加载器
|
||||
*
|
||||
* @param dataLoader /
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaOAuth2Interface(SaOAuth2DataLoader dataLoader) {
|
||||
SaOAuth2Manager.setDataLoader(dataLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import org.springframework.context.annotation.Bean;
|
||||
public class SaOAuth2BeanRegister {
|
||||
|
||||
/**
|
||||
* 获取 OAuth2 配置对象
|
||||
* 获取 OAuth2 配置 Bean
|
||||
*
|
||||
* @return 配置对象
|
||||
*/
|
||||
@ -40,5 +40,5 @@ public class SaOAuth2BeanRegister {
|
||||
public SaOAuth2Config getSaOAuth2Config() {
|
||||
return new SaOAuth2Config();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ package cn.dev33.satoken.integrate.configure.inject;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
|
||||
import cn.dev33.satoken.oauth2.template.SaOAuth2Template;
|
||||
|
||||
/**
|
||||
* 自定义 Sa-OAuth2 模板方法
|
||||
|
Loading…
Reference in New Issue
Block a user