mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
新增自定义 scope 处理器支持
This commit is contained in:
@@ -73,14 +73,11 @@ public class SaOAuth2DataConverterDefaultImpl implements SaOAuth2DataConverter {
|
||||
public AccessTokenModel convertCodeToAccessToken(CodeModel cm) {
|
||||
AccessTokenModel at = new AccessTokenModel();
|
||||
at.accessToken = SaOAuth2Manager.getDataLoader().randomAccessToken(cm.clientId, cm.loginId, cm.scopes);
|
||||
// at.refreshToken = randomRefreshToken(cm.clientId, cm.loginId, cm.scope);
|
||||
at.clientId = cm.clientId;
|
||||
at.loginId = cm.loginId;
|
||||
at.scopes = cm.scopes;
|
||||
at.openid = SaOAuth2Manager.getDataLoader().getOpenid(cm.clientId, cm.loginId);
|
||||
SaClientModel clientModel = SaOAuth2Manager.getDataLoader().getClientModelNotNull(cm.clientId);
|
||||
at.expiresTime = System.currentTimeMillis() + (clientModel.getAccessTokenTimeout() * 1000);
|
||||
// at.refreshExpiresTime = System.currentTimeMillis() + (checkClientModel(cm.clientId).getRefreshTokenTimeout() * 1000);
|
||||
return at;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@ package cn.dev33.satoken.oauth2.data.generate;
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts;
|
||||
import cn.dev33.satoken.oauth2.dao.SaOAuth2Dao;
|
||||
import cn.dev33.satoken.oauth2.data.convert.SaOAuth2DataConverter;
|
||||
import cn.dev33.satoken.oauth2.data.model.*;
|
||||
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
|
||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||
import cn.dev33.satoken.oauth2.strategy.SaOAuth2Strategy;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
import java.util.List;
|
||||
@@ -68,6 +70,7 @@ public class SaOAuth2DataGenerateDefaultImpl implements SaOAuth2DataGenerate {
|
||||
public AccessTokenModel generateAccessToken(String code) {
|
||||
|
||||
SaOAuth2Dao dao = SaOAuth2Manager.getDao();
|
||||
SaOAuth2DataConverter dataConverter = SaOAuth2Manager.getDataConverter();
|
||||
|
||||
// 1、先校验
|
||||
CodeModel cm = dao.getCode(code);
|
||||
@@ -78,8 +81,9 @@ public class SaOAuth2DataGenerateDefaultImpl implements SaOAuth2DataGenerate {
|
||||
dao.deleteRefreshToken(dao.getRefreshTokenValue(cm.clientId, cm.loginId));
|
||||
|
||||
// 3、生成token
|
||||
AccessTokenModel at = SaOAuth2Manager.getDataConverter().convertCodeToAccessToken(cm);
|
||||
RefreshTokenModel rt = SaOAuth2Manager.getDataConverter().convertAccessTokenToRefreshToken(at);
|
||||
AccessTokenModel at = dataConverter.convertCodeToAccessToken(cm);
|
||||
SaOAuth2Strategy.instance.workAccessTokenByScope.accept(at);
|
||||
RefreshTokenModel rt = dataConverter.convertAccessTokenToRefreshToken(at);
|
||||
at.refreshToken = rt.refreshToken;
|
||||
at.refreshExpiresTime = rt.expiresTime;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package cn.dev33.satoken.oauth2.data.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.function.strategy;
|
||||
|
||||
import cn.dev33.satoken.oauth2.data.model.AccessTokenModel;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 函数式接口:AccessTokenModel 加工
|
||||
*
|
||||
* <p> 参数:AccessTokenModel </p>
|
||||
* <p> 返回:无 </p>
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.35.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SaScopeWorkFunction extends Consumer<AccessTokenModel> {
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ 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.data.generate.SaOAuth2DataGenerate;
|
||||
import cn.dev33.satoken.oauth2.data.model.*;
|
||||
import cn.dev33.satoken.oauth2.data.model.other.ClientIdAndSecretModel;
|
||||
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
|
||||
@@ -140,6 +141,7 @@ public class SaOAuth2ServerProcessor {
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
SaOAuth2DataGenerate dataGenerate = SaOAuth2Manager.getDataGenerate();
|
||||
|
||||
// 1、如果尚未登录, 则先去登录
|
||||
if( ! getStpLogic().isLogin()) {
|
||||
@@ -161,18 +163,19 @@ public class SaOAuth2ServerProcessor {
|
||||
return cfg.confirmView.apply(ra.clientId, ra.scopes);
|
||||
}
|
||||
|
||||
|
||||
// 6、判断授权类型
|
||||
// 如果是 授权码式,则:开始重定向授权,下放code
|
||||
if(ResponseType.code.equals(ra.responseType)) {
|
||||
CodeModel codeModel = SaOAuth2Manager.getDataGenerate().generateCode(ra);
|
||||
String redirectUri = SaOAuth2Manager.getDataGenerate().buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
CodeModel codeModel = dataGenerate.generateCode(ra);
|
||||
String redirectUri = dataGenerate.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
if(ResponseType.token.equals(ra.responseType)) {
|
||||
AccessTokenModel at = SaOAuth2Manager.getDataGenerate().generateAccessToken(ra, false);
|
||||
String redirectUri = SaOAuth2Manager.getDataGenerate().buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
AccessTokenModel at = dataGenerate.generateAccessToken(ra, false);
|
||||
String redirectUri = dataGenerate.buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.scope.handler;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.data.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.scope.CommonScope;
|
||||
|
||||
/**
|
||||
* 所有OAuth2 权限处理器的父接口
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public class OpenIdScopeHandler implements SaOAuth2ScopeAbstractHandler {
|
||||
|
||||
/**
|
||||
* 获取所要处理的权限
|
||||
*/
|
||||
public String getHandlerScope() {
|
||||
return CommonScope.OPENID;
|
||||
}
|
||||
|
||||
/**
|
||||
* 所需要执行的方法
|
||||
*/
|
||||
public void work(AccessTokenModel at) {
|
||||
System.out.println("追加 openid " + at.accessToken);
|
||||
at.openid = SaOAuth2Manager.getDataLoader().getOpenid(at.clientId, at.loginId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.scope.handler;
|
||||
|
||||
import cn.dev33.satoken.oauth2.data.model.AccessTokenModel;
|
||||
|
||||
/**
|
||||
* 所有OAuth2 权限处理器的父接口
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public interface SaOAuth2ScopeAbstractHandler {
|
||||
|
||||
/**
|
||||
* 获取所要处理的权限
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
String getHandlerScope();
|
||||
|
||||
/**
|
||||
* 所需要执行的方法
|
||||
*
|
||||
* @param at /
|
||||
*/
|
||||
default void work(AccessTokenModel at) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.strategy;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.oauth2.function.strategy.SaScopeWorkFunction;
|
||||
import cn.dev33.satoken.oauth2.scope.CommonScope;
|
||||
import cn.dev33.satoken.oauth2.scope.handler.OpenIdScopeHandler;
|
||||
import cn.dev33.satoken.oauth2.scope.handler.SaOAuth2ScopeAbstractHandler;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sa-Token OAuth2 相关策略
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.39.0
|
||||
*/
|
||||
public final class SaOAuth2Strategy {
|
||||
|
||||
private SaOAuth2Strategy() {
|
||||
registerDefaultScopeHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局单例引用
|
||||
*/
|
||||
public static final SaOAuth2Strategy instance = new SaOAuth2Strategy();
|
||||
|
||||
|
||||
// ----------------------- 所有策略
|
||||
|
||||
/**
|
||||
* 权限处理器集合
|
||||
*/
|
||||
public Map<String, SaOAuth2ScopeAbstractHandler> scopeHandlerMap = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* 注册所有默认的权限处理器
|
||||
*/
|
||||
public void registerDefaultScopeHandler() {
|
||||
scopeHandlerMap.put(CommonScope.OPENID, new OpenIdScopeHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册一个权限处理器
|
||||
*/
|
||||
public void registerScopeHandler(SaOAuth2ScopeAbstractHandler handler) {
|
||||
scopeHandlerMap.put(handler.getHandlerScope(), handler);
|
||||
// TODO 优化日志输出
|
||||
SaManager.getLog().info("新增权限处理器:" + handler.getHandlerScope());
|
||||
// SaTokenEventCenter.doRegisterAnnotationHandler(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个权限处理器
|
||||
*/
|
||||
public void removeScopeHandler(String scope) {
|
||||
scopeHandlerMap.remove(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 scope 信息对一个 AccessTokenModel 进行加工处理
|
||||
*/
|
||||
public SaScopeWorkFunction workAccessTokenByScope = (at) -> {
|
||||
System.out.println("增强:" + at.accessToken);
|
||||
System.out.println("权限:" + at.scopes);
|
||||
// 遍历所有的权限处理器,如果此 AccessToken 具有这些权限,则开始加工
|
||||
if(at.scopes != null && !at.scopes.isEmpty()) {
|
||||
for (Map.Entry<String, SaOAuth2ScopeAbstractHandler> entry: scopeHandlerMap.entrySet()) {
|
||||
if(at.scopes.contains(entry.getKey())) {
|
||||
entry.getValue().work(at);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -47,16 +47,6 @@ public class SaOAuth2Template {
|
||||
return SaOAuth2Manager.getDataLoader().getClientModel(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ClientId 和 LoginId 获取openid
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @return 此账号在此Client下的openid
|
||||
*/
|
||||
public String getOpenid(String clientId, Object loginId) {
|
||||
return SaOAuth2Manager.getDataLoader().getOpenid(clientId, loginId);
|
||||
}
|
||||
|
||||
// ------------------- 资源校验API
|
||||
/**
|
||||
* 根据id获取Client信息, 如果Client为空,则抛出异常
|
||||
|
||||
Reference in New Issue
Block a user