mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-23 04:23:36 +08:00
目录结构重构完成
This commit is contained in:
13
sa-token-plugin/sa-token-oauth2/.gitignore
vendored
Normal file
13
sa-token-plugin/sa-token-oauth2/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.factorypath
|
||||
|
||||
.idea/
|
||||
.iml
|
12
sa-token-plugin/sa-token-oauth2/README.md
Normal file
12
sa-token-plugin/sa-token-oauth2/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# sa-token-oauth2 内测版
|
||||
|
||||
sa-token-oauth2 模块是 sa-token 实现 oauth2.0 的部分,目前该模块功能完成度较低,为避免不可预知的风险,建议仅做学习测试使用
|
||||
|
||||
## 启动步骤
|
||||
|
||||
1. 启动项目 `sa-token-demo-oauth2-server`, 此为OAuth2.0的服务提供方
|
||||
2. 启动项目 `sa-token-demo-oauth2-client`, 此为OAuth2.0的客户端
|
||||
3. 根据控制台打印,访问测试地址即可:[http://localhost:8002/login.html](http://localhost:8002/login.html)
|
||||
|
||||
可结合代码注释学习查看
|
||||
|
30
sa-token-plugin/sa-token-oauth2/pom.xml
Normal file
30
sa-token-plugin/sa-token-oauth2/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-plugin</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-dao-redis</name>
|
||||
<artifactId>sa-token-oauth2</artifactId>
|
||||
<version>1.15.0-alpha</version>
|
||||
<description>sa-token realization oauth2.0</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- sa-token-core -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
</project>
|
@@ -0,0 +1,54 @@
|
||||
package cn.dev33.satoken.oauth2;
|
||||
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Interface;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2InterfaceDefaultImpl;
|
||||
|
||||
/**
|
||||
* sa-token oauth2 模块 总控类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaOAuth2Manager {
|
||||
|
||||
/**
|
||||
* OAuth2 配置 Bean
|
||||
*/
|
||||
private static SaOAuth2Config config;
|
||||
public static SaOAuth2Config getConfig() {
|
||||
if (config == null) {
|
||||
// 初始化默认值
|
||||
synchronized (SaOAuth2Manager.class) {
|
||||
if (config == null) {
|
||||
setConfig(new SaOAuth2Config());
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
public static void setConfig(SaOAuth2Config config) {
|
||||
SaOAuth2Manager.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* sa-token-oauth2 逻辑 Bean
|
||||
*/
|
||||
private static SaOAuth2Interface saOAuth2Interface;
|
||||
public static SaOAuth2Interface getInterface() {
|
||||
if (saOAuth2Interface == null) {
|
||||
// 初始化默认值
|
||||
synchronized (SaOAuth2Manager.class) {
|
||||
if (saOAuth2Interface == null) {
|
||||
setInterface(new SaOAuth2InterfaceDefaultImpl());
|
||||
}
|
||||
}
|
||||
}
|
||||
return saOAuth2Interface;
|
||||
}
|
||||
public static void setInterface(SaOAuth2Interface interfaceObj) {
|
||||
SaOAuth2Manager.saOAuth2Interface = interfaceObj;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
package cn.dev33.satoken.oauth2.config;
|
||||
|
||||
/**
|
||||
* sa-token oauth2 配置类 Model
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaOAuth2Config {
|
||||
|
||||
/**
|
||||
* 授权码默认保存的时间(单位秒) 默认五分钟
|
||||
*/
|
||||
private long codeTimeout = 60 * 5;
|
||||
|
||||
/**
|
||||
* access_token默认保存的时间(单位秒) 默认两个小时
|
||||
*/
|
||||
private long accessTokenTimeout = 60 * 60 * 2;
|
||||
|
||||
/**
|
||||
* refresh_token默认保存的时间(单位秒) 默认30 天
|
||||
*/
|
||||
private long refreshTokenTimeout = 60 * 60 * 24 * 30;
|
||||
|
||||
|
||||
/**
|
||||
* @return codeTimeout
|
||||
*/
|
||||
public long getCodeTimeout() {
|
||||
return codeTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param codeTimeout 要设置的 codeTimeout
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaOAuth2Config setCodeTimeout(long codeTimeout) {
|
||||
this.codeTimeout = codeTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return accessTokenTimeout
|
||||
*/
|
||||
public long getAccessTokenTimeout() {
|
||||
return accessTokenTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accessTokenTimeout 要设置的 accessTokenTimeout
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaOAuth2Config setAccessTokenTimeout(long accessTokenTimeout) {
|
||||
this.accessTokenTimeout = accessTokenTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return refreshTokenTimeout
|
||||
*/
|
||||
public long getRefreshTokenTimeout() {
|
||||
return refreshTokenTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param refreshTokenTimeout 要设置的 refreshTokenTimeout
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaOAuth2Config setRefreshTokenTimeout(long refreshTokenTimeout) {
|
||||
this.refreshTokenTimeout = refreshTokenTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,554 @@
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||
import cn.dev33.satoken.oauth2.util.SaOAuth2Consts;
|
||||
import cn.dev33.satoken.oauth2.util.SaOAuth2InsideUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* sa-token-oauth2 模块 逻辑接口
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaOAuth2Interface {
|
||||
|
||||
|
||||
// ------------------- 获取数据
|
||||
|
||||
/**
|
||||
* [default] 返回此平台所有权限集合
|
||||
* @return 此平台所有权限名称集合
|
||||
*/
|
||||
public default List<String> getAppScopeList() {
|
||||
return Arrays.asList("userinfo");
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 返回指定Client签约的所有Scope名称集合
|
||||
* @param clientId 应用id
|
||||
* @return Scope集合
|
||||
*/
|
||||
public default List<String> getClientScopeList(String clientId) {
|
||||
// 默认返回此APP的所有权限
|
||||
return getAppScopeList();
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取指定 LoginId 对指定 Client 已经授权过的所有 Scope
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @return Scope集合
|
||||
*/
|
||||
public default List<String> getGrantScopeList(Object loginId, String clientId) {
|
||||
// 默认返回空集合
|
||||
return Arrays.asList();
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 返回指定Client允许的回调域名, 多个用逗号隔开, *代表不限制
|
||||
* @param clientId 应用id
|
||||
* @return domain集合
|
||||
*/
|
||||
public default String getClientDomain(String clientId) {
|
||||
return "*";
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 返回指定ClientId的ClientSecret
|
||||
* @param clientId 应用id
|
||||
* @return 此应用的秘钥
|
||||
*/
|
||||
public default String getClientSecret(String clientId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据ClientId和LoginId返回openid
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @return 此账号在此Client下的openid
|
||||
*/
|
||||
public default String getOpenid(String clientId, Object loginId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据ClientId和openid返回LoginId
|
||||
* @param clientId 应用id
|
||||
* @param openid openid
|
||||
* @return LoginId
|
||||
*/
|
||||
public default Object getLoginId(String clientId, String openid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 数据校验
|
||||
|
||||
/**
|
||||
* [default] 检查一个 Client 是否签约了指定的Scope
|
||||
* @param clientId 应用id
|
||||
* @param scope 权限
|
||||
*/
|
||||
public default void checkContract(String clientId, String scope) {
|
||||
List<String> clientScopeList = getClientScopeList(clientId);
|
||||
List<String> scopelist = Arrays.asList(scope.split(","));
|
||||
if(clientScopeList.containsAll(scopelist) == false) {
|
||||
throw new SaTokenException("请求授权范围超出或无效");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 指定 loginId 是否对一个 Client 授权给了指定 Scope
|
||||
* @param loginId 账号id
|
||||
* @param clientId 应用id
|
||||
* @param scope 权限
|
||||
* @return 是否已经授权
|
||||
*/
|
||||
public default boolean isGrant(Object loginId, String clientId, String scope) {
|
||||
List<String> grantScopeList = getGrantScopeList(loginId, clientId);
|
||||
List<String> scopeList = convertStringToList(scope);
|
||||
return grantScopeList.containsAll(scopeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 指定Client使用指定url作为回调地址,是否合法
|
||||
* @param clientId 应用id
|
||||
* @param url 指定url
|
||||
*/
|
||||
public default void checkRightUrl(String clientId, String url) {
|
||||
// 首先检测url格式
|
||||
if(SaOAuth2InsideUtil.isUrl(url) == false) {
|
||||
throw new SaTokenException("url格式错误");
|
||||
}
|
||||
// ---- 检测
|
||||
|
||||
// 获取此应用允许的域名列表
|
||||
String domain = getClientDomain(clientId);
|
||||
// 如果是null或者空字符串, 则代表任何域名都无法通过检查
|
||||
if(domain == null || "".equals(domain)) {
|
||||
throw new SaTokenException("重定向地址无效");
|
||||
}
|
||||
// 如果是*符号,代表允许任何域名
|
||||
if(SaOAuth2Consts.UNLIMITED_DOMAIN.equals(domain)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取域名进行比对
|
||||
try {
|
||||
String host = new URL(url).getHost();
|
||||
List<String> domainList = convertStringToList(domain);
|
||||
if(domainList.contains(host) == false) {
|
||||
throw new SaTokenException("重定向地址不在列表中");
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
throw new SaTokenException("url格式错误", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 校验code、clientId、clientSecret 三者是否正确
|
||||
* @param code 授权码
|
||||
* @param clientId 应用id
|
||||
* @param clientSecret 秘钥
|
||||
* @return CodeModel对象
|
||||
*/
|
||||
public default CodeModel checkCodeIdSecret(String code, String clientId, String clientSecret) {
|
||||
|
||||
// 获取授权码信息
|
||||
CodeModel codeModel = getCode(code);
|
||||
|
||||
// 验证code、client_id、client_secret
|
||||
if(codeModel == null) {
|
||||
throw new SaTokenException("无效code");
|
||||
}
|
||||
|
||||
if(codeModel.getClientId().equals(clientId) == false){
|
||||
throw new SaTokenException("无效client_id");
|
||||
}
|
||||
String dbClientSecret = getClientSecret(clientId);
|
||||
System.out.println(dbClientSecret);
|
||||
System.out.println(clientSecret);
|
||||
if(dbClientSecret == null || dbClientSecret.equals(clientSecret) == false){
|
||||
throw new SaTokenException("无效client_secret");
|
||||
}
|
||||
|
||||
// 返回CodeMdoel
|
||||
return codeModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 校验access_token、clientId、clientSecret 三者是否正确
|
||||
* @param accessToken access_token
|
||||
* @param clientId 应用id
|
||||
* @param clientSecret 秘钥
|
||||
* @return AccessTokenModel对象
|
||||
*/
|
||||
public default AccessTokenModel checkTokenIdSecret(String accessToken, String clientId, String clientSecret) {
|
||||
|
||||
// 获取授权码信息
|
||||
AccessTokenModel tokenModel = getAccessToken(accessToken);
|
||||
|
||||
// 验证code、client_id、client_secret
|
||||
if(tokenModel == null) {
|
||||
throw new SaTokenException("无效access_token");
|
||||
}
|
||||
if(tokenModel.getClientId().equals(clientId) == false){
|
||||
throw new SaTokenException("无效client_id");
|
||||
}
|
||||
String dbClientSecret = getClientSecret(clientId);
|
||||
if(dbClientSecret == null || dbClientSecret.equals(clientSecret)){
|
||||
throw new SaTokenException("无效client_secret");
|
||||
}
|
||||
|
||||
// 返回AccessTokenModel
|
||||
return tokenModel;
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 逻辑相关
|
||||
|
||||
// ---- 授权码
|
||||
/**
|
||||
* [default] 根据参数生成一个授权码并返回
|
||||
* @param authModel 请求授权参数Model
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public default CodeModel generateCode(RequestAuthModel authModel) {
|
||||
|
||||
// 获取参数
|
||||
String clientId = authModel.getClientId();
|
||||
String scope = authModel.getScope();
|
||||
Object loginId = authModel.getLoginId();
|
||||
String redirectUri = authModel.getRedirectUri();
|
||||
String state = authModel.getState();
|
||||
|
||||
// ------ 参数校验
|
||||
// 此Client是否签约了此Scope
|
||||
checkContract(clientId, scope);
|
||||
|
||||
// 校验重定向域名的格式是否合法
|
||||
checkRightUrl(clientId, redirectUri);
|
||||
|
||||
// ------ 开始生成code码
|
||||
String code = createCode(clientId, scope, loginId);
|
||||
CodeModel codeModel = new CodeModel(code, clientId, scope, loginId);
|
||||
|
||||
// 拼接授权后重定向的域名 (拼接code和state参数)
|
||||
String url = splicingParame(redirectUri, "code=" + code);
|
||||
if(state != null) {
|
||||
url = splicingParame(url, "state=" + state);
|
||||
}
|
||||
codeModel.setRedirectUri(url);
|
||||
|
||||
// 拒绝授权时重定向的地址
|
||||
codeModel.setRejectUri(splicingParame(redirectUri, "handle=reject"));
|
||||
|
||||
// 计算此Scope是否已经授权过了
|
||||
codeModel.setIsConfirm(isGrant(loginId, clientId, scope));
|
||||
|
||||
// ------ 开始保存
|
||||
|
||||
// 将此授权码保存到DB
|
||||
long codeTimeout = SaOAuth2Manager.getConfig().getCodeTimeout();
|
||||
SaManager.getSaTokenDao().setObject(getKeyCodeModel(code), codeModel, codeTimeout);
|
||||
|
||||
// 如果此[Client&账号]已经有code正在存储,则先删除它
|
||||
String key = getKeyClientLoginId(loginId, clientId);
|
||||
SaManager.getSaTokenDao().delete(key);
|
||||
|
||||
// 将此[Client&账号]的最新授权码保存到DB中
|
||||
// 以便于完成授权码覆盖操作: 保证每次只有最新的授权码有效
|
||||
SaManager.getSaTokenDao().set(key, code, codeTimeout);
|
||||
|
||||
// 返回
|
||||
return codeModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据授权码获得授权码Model
|
||||
* @param code 授权码
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public default CodeModel getCode(String code) {
|
||||
return (CodeModel)SaManager.getSaTokenDao().getObject(getKeyCodeModel(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 手动更改授权码对象信息
|
||||
* @param code 授权码
|
||||
* @param codeModel 授权码Model
|
||||
*/
|
||||
public default void updateCode(String code, CodeModel codeModel) {
|
||||
SaManager.getSaTokenDao().updateObject(getKeyCodeModel(code), codeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 确认授权一个code
|
||||
* @param code 授权码
|
||||
*/
|
||||
public default void confirmCode(String code) {
|
||||
// 获取codeModel
|
||||
CodeModel codeModel = getCode(code);
|
||||
// 如果该code码已经确认
|
||||
if(codeModel.getIsConfirm() == true) {
|
||||
return;
|
||||
}
|
||||
// 进行确认
|
||||
codeModel.setIsConfirm(true);
|
||||
updateCode(code, codeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 删除一个授权码
|
||||
* @param code 授权码
|
||||
*/
|
||||
public default void deleteCode(String code) {
|
||||
SaManager.getSaTokenDao().deleteObject(getKeyCodeModel(code));
|
||||
}
|
||||
|
||||
|
||||
// ------------------- access_token 和 refresh_token 相关
|
||||
|
||||
/**
|
||||
* [default] 根据授权码Model生成一个access_token
|
||||
* @param codeModel 授权码Model
|
||||
* @return AccessTokenModel
|
||||
*/
|
||||
public default AccessTokenModel generateAccessToken(CodeModel codeModel) {
|
||||
|
||||
// 先校验
|
||||
if(codeModel == null) {
|
||||
throw new SaTokenException("无效code");
|
||||
}
|
||||
if(codeModel.getIsConfirm() == false) {
|
||||
throw new SaTokenException("该code尚未授权");
|
||||
}
|
||||
|
||||
// 获取 TokenModel 并保存
|
||||
AccessTokenModel tokenModel = converCodeToAccessToken(codeModel);
|
||||
SaManager.getSaTokenDao().setObject(getKeyAccessToken(tokenModel.getAccessToken()), tokenModel, SaOAuth2Manager.getConfig().getAccessTokenTimeout());
|
||||
|
||||
// 将此 CodeModel 当做 refresh_token 保存下来
|
||||
SaManager.getSaTokenDao().setObject(getKeyRefreshToken(tokenModel.getRefreshToken()), codeModel, SaOAuth2Manager.getConfig().getRefreshTokenTimeout());
|
||||
|
||||
// 返回
|
||||
return tokenModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据 access_token 获得其Model详细信息
|
||||
* @param accessToken access_token
|
||||
* @return AccessTokenModel (授权码Model)
|
||||
*/
|
||||
public default AccessTokenModel getAccessToken(String accessToken) {
|
||||
return (AccessTokenModel)SaManager.getSaTokenDao().getObject(getKeyAccessToken(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据 refresh_token 生成一个新的 access_token
|
||||
* @param refreshToken refresh_token
|
||||
* @return 新的 access_token
|
||||
*/
|
||||
public default AccessTokenModel refreshAccessToken(String refreshToken) {
|
||||
// 获取Model信息
|
||||
CodeModel codeModel = getRefreshToken(refreshToken);
|
||||
if(codeModel == null) {
|
||||
throw new SaTokenException("无效refresh_token");
|
||||
}
|
||||
// 获取新的 AccessToken 并保存
|
||||
AccessTokenModel tokenModel = converCodeToAccessToken(codeModel);
|
||||
tokenModel.setRefreshToken(refreshToken);
|
||||
SaManager.getSaTokenDao().setObject(getKeyAccessToken(tokenModel.getAccessToken()), tokenModel, SaOAuth2Manager.getConfig().getAccessTokenTimeout());
|
||||
|
||||
// 返回
|
||||
return tokenModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据 refresh_token 获得其Model详细信息 (授权码Model)
|
||||
* @param refreshToken refresh_token
|
||||
* @return RefreshToken (授权码Model)
|
||||
*/
|
||||
public default CodeModel getRefreshToken(String refreshToken) {
|
||||
return (CodeModel)SaManager.getSaTokenDao().getObject(getKeyRefreshToken(refreshToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取 access_token 的有效期
|
||||
* @param accessToken access_token
|
||||
* @return 有效期
|
||||
*/
|
||||
public default long getAccessTokenExpiresIn(String accessToken) {
|
||||
return SaManager.getSaTokenDao().getObjectTimeout(getKeyAccessToken(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取 refresh_token 的有效期
|
||||
* @param refreshToken refresh_token
|
||||
* @return 有效期
|
||||
*/
|
||||
public default long getRefreshTokenExpiresIn(String refreshToken) {
|
||||
return SaManager.getSaTokenDao().getObjectTimeout(getKeyRefreshToken(refreshToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取 access_token 所代表的LoginId
|
||||
* @param accessToken access_token
|
||||
* @return LoginId
|
||||
*/
|
||||
public default Object getLoginIdByAccessToken(String accessToken) {
|
||||
AccessTokenModel tokenModel = SaOAuth2Util.getAccessToken(accessToken);
|
||||
if(tokenModel == null) {
|
||||
throw new SaTokenException("无效access_token");
|
||||
}
|
||||
return getLoginId(tokenModel.getClientId(), tokenModel.getOpenid());
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 自定义策略相关
|
||||
|
||||
/**
|
||||
* [default] 将指定字符串按照逗号分隔符转化为字符串集合
|
||||
* @param str 字符串
|
||||
* @return 分割后的字符串集合
|
||||
*/
|
||||
public default List<String> convertStringToList(String str) {
|
||||
return Arrays.asList(str.split(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 生成授权码
|
||||
* @param clientId 应用id
|
||||
* @param scope 权限
|
||||
* @param loginId 账号id
|
||||
* @return 授权码
|
||||
*/
|
||||
public default String createCode(String clientId, String scope, Object loginId) {
|
||||
return SaFoxUtil.getRandomString(60).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 生成AccessToken
|
||||
* @param codeModel CodeModel对象
|
||||
* @return AccessToken
|
||||
*/
|
||||
public default String createAccessToken(CodeModel codeModel) {
|
||||
return SaFoxUtil.getRandomString(60).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 生成RefreshToken
|
||||
* @param codeModel CodeModel对象
|
||||
* @return RefreshToken
|
||||
*/
|
||||
public default String createRefreshToken(CodeModel codeModel) {
|
||||
return SaFoxUtil.getRandomString(60).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 在url上拼接上kv参数并返回
|
||||
* @param url url
|
||||
* @param parameStr 参数, 例如 id=1001
|
||||
* @return 拼接后的url字符串
|
||||
*/
|
||||
public default String splicingParame(String url, String parameStr) {
|
||||
// 如果参数为空, 直接返回
|
||||
if(parameStr == null || parameStr.length() == 0) {
|
||||
return url;
|
||||
}
|
||||
int index = url.indexOf('?');
|
||||
// ? 不存在
|
||||
if(index == -1) {
|
||||
return url + '?' + parameStr;
|
||||
}
|
||||
// ? 是最后一位
|
||||
if(index == url.length() - 1) {
|
||||
return url + parameStr;
|
||||
}
|
||||
// ? 是其中一位
|
||||
if(index > -1 && index < url.length() - 1) {
|
||||
String separatorChar = "&";
|
||||
// 如果最后一位是 不是&, 且 arg_str 第一位不是 &, 就增送一个 &
|
||||
if(url.lastIndexOf(separatorChar) != url.length() - 1 && parameStr.indexOf(separatorChar) != 0) {
|
||||
return url + separatorChar + parameStr;
|
||||
} else {
|
||||
return url + parameStr;
|
||||
}
|
||||
}
|
||||
// 正常情况下, 代码不可能执行到此
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 将 CodeModel 转换为 AccessTokenModel
|
||||
* @param codeModel CodeModel对象
|
||||
* @return AccessToken对象
|
||||
*/
|
||||
public default AccessTokenModel converCodeToAccessToken(CodeModel codeModel) {
|
||||
if(codeModel == null) {
|
||||
throw new SaTokenException("无效code");
|
||||
}
|
||||
AccessTokenModel tokenModel = new AccessTokenModel();
|
||||
tokenModel.setAccessToken(createAccessToken(codeModel));
|
||||
tokenModel.setRefreshToken(createRefreshToken(codeModel));
|
||||
tokenModel.setCode(codeModel.getCode());
|
||||
tokenModel.setClientId(codeModel.getClientId());
|
||||
tokenModel.setScope(codeModel.getScope());
|
||||
tokenModel.setOpenid(getOpenid(codeModel.getClientId(), codeModel.getLoginId()));
|
||||
tokenModel.setTag(codeModel.getTag());
|
||||
return tokenModel;
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 返回相应key
|
||||
|
||||
/**
|
||||
* 获取key:授权码持久化使用的key
|
||||
* @param code 授权码
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyCodeModel(String code) {
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:code:" + code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key:[Client and 账号]最新授权码记录, 持久化使用的key
|
||||
* @param loginId 账号id
|
||||
* @param clientId 应用id
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyClientLoginId(Object loginId, String clientId) {
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:newest-code:" + clientId + ":" + loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key:refreshToken持久化使用的key
|
||||
* @param refreshToken refreshToken
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyRefreshToken(String refreshToken) {
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:refresh-token:" + refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key:accessToken持久化使用的key
|
||||
* @param accessToken accessToken
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyAccessToken(String accessToken) {
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:access-token:" + accessToken;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
|
||||
/**
|
||||
* SaOAuth2Interface 默认实现类 (只构建userinfo单个权限)
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaOAuth2InterfaceDefaultImpl implements SaOAuth2Interface {
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,198 @@
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
import cn.dev33.satoken.oauth2.model.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||
|
||||
/**
|
||||
* sa-token-oauth2 模块 静态类接口转发, 方便调用
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaOAuth2Util {
|
||||
|
||||
// ------------------- 获取数据
|
||||
|
||||
/**
|
||||
* 返回此平台所有权限集合
|
||||
* @return 此平台所有权限名称集合
|
||||
*/
|
||||
public static List<String> getAppScopeList() {
|
||||
return SaOAuth2Manager.getInterface().getAppScopeList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回指定Client签约的所有Scope名称集合
|
||||
* @param clientId 应用id
|
||||
* @return Scope集合
|
||||
*/
|
||||
public static List<String> getClientScopeList(String clientId) {
|
||||
return SaOAuth2Manager.getInterface().getClientScopeList(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定 LoginId 对指定 Client 已经授权过的所有 Scope
|
||||
* @param clientId 应用id
|
||||
* @param loginId 账号id
|
||||
* @return Scope集合
|
||||
*/
|
||||
public static List<String> getGrantScopeList(Object loginId, String clientId) {
|
||||
return SaOAuth2Manager.getInterface().getGrantScopeList(loginId, clientId);
|
||||
}
|
||||
|
||||
|
||||
// ------------------- 数据校验
|
||||
|
||||
/**
|
||||
* 指定 loginId 是否对一个 Client 授权给了指定 Scope
|
||||
* @param clientId 应用id
|
||||
* @param scope 权限
|
||||
* @param loginId 账号id
|
||||
* @return 是否已经授权
|
||||
*/
|
||||
public static boolean isGrant(Object loginId, String clientId, String scope) {
|
||||
return SaOAuth2Manager.getInterface().isGrant(loginId, clientId, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验code、clientId、clientSecret 三者是否正确
|
||||
* @param code 授权码
|
||||
* @param clientId 应用id
|
||||
* @param clientSecret 秘钥
|
||||
* @return CodeModel对象
|
||||
*/
|
||||
public static CodeModel checkCodeIdSecret(String code, String clientId, String clientSecret) {
|
||||
return SaOAuth2Manager.getInterface().checkCodeIdSecret(code, clientId, clientSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 校验access_token、clientId、clientSecret 三者是否正确
|
||||
* @param accessToken access_token
|
||||
* @param clientId 应用id
|
||||
* @param clientSecret 秘钥
|
||||
* @return AccessTokenModel对象
|
||||
*/
|
||||
public static AccessTokenModel checkTokenIdSecret(String accessToken, String clientId, String clientSecret) {
|
||||
return SaOAuth2Manager.getInterface().checkTokenIdSecret(accessToken, clientId, clientSecret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------- 逻辑相关
|
||||
|
||||
/**
|
||||
* 根据参数生成一个授权码并返回
|
||||
* @param authModel 请求授权参数Model
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public static CodeModel generateCode(RequestAuthModel authModel) {
|
||||
return SaOAuth2Manager.getInterface().generateCode(authModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据授权码获得授权码Model
|
||||
* @param code 授权码
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public static CodeModel getCode(String code) {
|
||||
return SaOAuth2Manager.getInterface().getCode(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动更改授权码对象信息
|
||||
* @param code 授权码
|
||||
* @param codeModel 授权码Model
|
||||
*/
|
||||
public static void updateCode(String code, CodeModel codeModel) {
|
||||
SaOAuth2Manager.getInterface().updateCode(code, codeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认授权一个code
|
||||
* @param code 授权码
|
||||
*/
|
||||
public static void confirmCode(String code) {
|
||||
SaOAuth2Manager.getInterface().confirmCode(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 删除一个授权码
|
||||
* @param code 授权码
|
||||
*/
|
||||
public static void deleteCode(String code) {
|
||||
SaOAuth2Manager.getInterface().deleteCode(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据授权码Model生成一个access_token
|
||||
* @param codeModel 授权码Model
|
||||
* @return AccessTokenModel
|
||||
*/
|
||||
public static AccessTokenModel generateAccessToken(CodeModel codeModel) {
|
||||
return SaOAuth2Manager.getInterface().generateAccessToken(codeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据 access_token 获得其Model详细信息
|
||||
* @param accessToken access_token
|
||||
* @return AccessTokenModel (授权码Model)
|
||||
*/
|
||||
public static AccessTokenModel getAccessToken(String accessToken) {
|
||||
return SaOAuth2Manager.getInterface().getAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 refresh_token 生成一个新的 access_token
|
||||
* @param refreshToken refresh_token
|
||||
* @return 新的 access_token
|
||||
*/
|
||||
public static AccessTokenModel refreshAccessToken(String refreshToken) {
|
||||
return SaOAuth2Manager.getInterface().refreshAccessToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 根据 refresh_token 获得其Model详细信息 (授权码Model)
|
||||
* @param refreshToken refresh_token
|
||||
* @return RefreshToken (授权码Model)
|
||||
*/
|
||||
public static CodeModel getRefreshToken(String refreshToken) {
|
||||
return SaOAuth2Manager.getInterface().getRefreshToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取 access_token 的有效期
|
||||
* @param accessToken access_token
|
||||
* @return 有效期
|
||||
*/
|
||||
public static long getAccessTokenExpiresIn(String accessToken) {
|
||||
return SaOAuth2Manager.getInterface().getAccessTokenExpiresIn(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取 refresh_token 的有效期
|
||||
* @param refreshToken refresh_token
|
||||
* @return 有效期
|
||||
*/
|
||||
public static long getRefreshTokenExpiresIn(String refreshToken) {
|
||||
return SaOAuth2Manager.getInterface().getRefreshTokenExpiresIn(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* [default] 获取 access_token 所代表的LoginId
|
||||
* @param accessToken access_token
|
||||
* @return LoginId
|
||||
*/
|
||||
public static Object getLoginIdByAccessToken(String accessToken) {
|
||||
return SaOAuth2Manager.getInterface().getLoginIdByAccessToken(accessToken);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,186 @@
|
||||
package cn.dev33.satoken.oauth2.model;
|
||||
|
||||
/**
|
||||
* Model: access_token
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class AccessTokenModel {
|
||||
|
||||
/**
|
||||
* access_token 值
|
||||
*/
|
||||
private String accessToken;
|
||||
|
||||
/**
|
||||
* refresh_token 值
|
||||
*/
|
||||
private String refreshToken;
|
||||
|
||||
/**
|
||||
* access_token 剩余有效时间 (秒)
|
||||
*/
|
||||
private long expiresIn;
|
||||
|
||||
/**
|
||||
* refresh_token 剩余有效期 (秒)
|
||||
*/
|
||||
private long refreshExpiresIn;
|
||||
|
||||
/**
|
||||
* 此 access_token令牌 是由哪个code码创建
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 应用id
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 开放账号id
|
||||
*/
|
||||
private String openid;
|
||||
|
||||
/**
|
||||
* 其他自定义数据
|
||||
*/
|
||||
private Object tag;
|
||||
|
||||
|
||||
/**
|
||||
* @return accessToken
|
||||
*/
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accessToken 要设置的 accessToken
|
||||
*/
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return refreshToken
|
||||
*/
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param refreshToken 要设置的 refreshToken
|
||||
*/
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return expiresIn
|
||||
*/
|
||||
public long getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expiresIn 要设置的 expiresIn
|
||||
*/
|
||||
public void setExpiresIn(long expiresIn) {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return refreshExpiresIn
|
||||
*/
|
||||
public long getRefreshExpiresIn() {
|
||||
return refreshExpiresIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param refreshExpiresIn 要设置的 refreshExpiresIn
|
||||
*/
|
||||
public void setRefreshExpiresIn(long refreshExpiresIn) {
|
||||
this.refreshExpiresIn = refreshExpiresIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return code
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param code 要设置的 code
|
||||
*/
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return clientId
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId 要设置的 clientId
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return scope
|
||||
*/
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scope 要设置的 scope
|
||||
*/
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return openid
|
||||
*/
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param openid 要设置的 openid
|
||||
*/
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tag
|
||||
*/
|
||||
public Object getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tag 要设置的 tag
|
||||
*/
|
||||
public void setTag(Object tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,191 @@
|
||||
package cn.dev33.satoken.oauth2.model;
|
||||
|
||||
/**
|
||||
* Model: [授权码 - 数据 对应关系]
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class CodeModel {
|
||||
|
||||
/**
|
||||
* 授权码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 应用id
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 对应账号id
|
||||
*/
|
||||
private Object loginId;
|
||||
|
||||
/**
|
||||
* 用户是否已经确认了这个授权
|
||||
*/
|
||||
private Boolean isConfirm;
|
||||
|
||||
/**
|
||||
* 确认授权后重定向的地址
|
||||
*/
|
||||
private String redirectUri;
|
||||
|
||||
/**
|
||||
* 拒绝授权后重定向的地址
|
||||
*/
|
||||
private String rejectUri;
|
||||
|
||||
|
||||
/**
|
||||
* 其他自定义数据
|
||||
*/
|
||||
private Object tag;
|
||||
|
||||
|
||||
/**
|
||||
* 构建一个
|
||||
*/
|
||||
public CodeModel() {
|
||||
|
||||
}
|
||||
/**
|
||||
* 构建一个
|
||||
* @param code 授权码
|
||||
* @param clientId 应用id
|
||||
* @param scope 请求授权范围
|
||||
* @param loginId 对应的账号id
|
||||
*/
|
||||
public CodeModel(String code, String clientId, String scope, Object loginId) {
|
||||
super();
|
||||
this.code = code;
|
||||
this.clientId = clientId;
|
||||
this.scope = scope;
|
||||
this.loginId = loginId;
|
||||
this.isConfirm = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return code
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param code 要设置的 code
|
||||
*/
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return clientId
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId 要设置的 clientId
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return scope
|
||||
*/
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scope 要设置的 scope
|
||||
*/
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loginId
|
||||
*/
|
||||
public Object getLoginId() {
|
||||
return loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginId 要设置的 loginId
|
||||
*/
|
||||
public void setLoginId(Object loginId) {
|
||||
this.loginId = loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isConfirm
|
||||
*/
|
||||
public Boolean getIsConfirm() {
|
||||
return isConfirm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isConfirm 要设置的 isConfirm
|
||||
*/
|
||||
public void setIsConfirm(Boolean isConfirm) {
|
||||
this.isConfirm = isConfirm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return redirectUri
|
||||
*/
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redirectUri 要设置的 redirectUri
|
||||
*/
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return rejectUri
|
||||
*/
|
||||
public String getRejectUri() {
|
||||
return rejectUri;
|
||||
}
|
||||
/**
|
||||
* @param rejectUri 要设置的 rejectUri
|
||||
*/
|
||||
public void setRejectUri(String rejectUri) {
|
||||
this.rejectUri = rejectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tag
|
||||
*/
|
||||
public Object getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tag 要设置的 tag
|
||||
*/
|
||||
public void setTag(Object tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,160 @@
|
||||
package cn.dev33.satoken.oauth2.model;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* 请求授权参数的Model
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class RequestAuthModel {
|
||||
|
||||
/**
|
||||
* 应用id
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 对应的账号id
|
||||
*/
|
||||
private Object loginId;
|
||||
|
||||
/**
|
||||
* 待重定向URL
|
||||
*/
|
||||
private String redirectUri;
|
||||
|
||||
/**
|
||||
* 授权类型, 非必填
|
||||
*/
|
||||
private String responseType;
|
||||
|
||||
/**
|
||||
* 状态标识, 可为null
|
||||
*/
|
||||
private String state;
|
||||
|
||||
|
||||
/**
|
||||
* @return clientId
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId 要设置的 clientId
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return scope
|
||||
*/
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scope 要设置的 scope
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel setScope(String scope) {
|
||||
this.scope = scope;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loginId
|
||||
*/
|
||||
public Object getLoginId() {
|
||||
return loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginId 要设置的 loginId
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel setLoginId(Object loginId) {
|
||||
this.loginId = loginId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return redirectUri
|
||||
*/
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redirectUri 要设置的 redirectUri
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return responseType
|
||||
*/
|
||||
public String getResponseType() {
|
||||
return responseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param responseType 要设置的 responseType
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel setResponseType(String responseType) {
|
||||
this.responseType = responseType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return state
|
||||
*/
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state 要设置的 state
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel setState(String state) {
|
||||
this.state = state;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查此Model参数是否有效
|
||||
* @return 对象自身
|
||||
*/
|
||||
public RequestAuthModel checkModel() {
|
||||
if(SaFoxUtil.isEmpty(clientId)) {
|
||||
throw new SaTokenException("无效client_id");
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(scope)) {
|
||||
throw new SaTokenException("无效scope");
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(redirectUri)) {
|
||||
throw new SaTokenException("无效redirect_uri");
|
||||
}
|
||||
if(SaFoxUtil.isEmpty(String.valueOf(loginId))) {
|
||||
throw new SaTokenException("无效LoginId");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package cn.dev33.satoken.oauth2.model;
|
||||
|
||||
/**
|
||||
* 权限Model
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class ScopeModel {
|
||||
|
||||
/**
|
||||
* 权限名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 详细介绍
|
||||
*/
|
||||
private String introduce;
|
||||
|
||||
|
||||
/**
|
||||
* 构造一个
|
||||
*/
|
||||
public ScopeModel() {
|
||||
super();
|
||||
}
|
||||
/**
|
||||
* 构造一个
|
||||
* @param name 权限名称
|
||||
* @param introduce 权限详细介绍
|
||||
*/
|
||||
public ScopeModel(String name, String introduce) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.introduce = introduce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name 要设置的 name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return introduce
|
||||
*/
|
||||
public String getIntroduce() {
|
||||
return introduce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param introduce 要设置的 introduce
|
||||
*/
|
||||
public void setIntroduce(String introduce) {
|
||||
this.introduce = introduce;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package cn.dev33.satoken.oauth2.util;
|
||||
|
||||
/**
|
||||
* sa-token oauth2 模块 用到的所有常量
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaOAuth2Consts {
|
||||
|
||||
/**
|
||||
* 在保存授权码时用到的key
|
||||
*/
|
||||
public static final String UNLIMITED_DOMAIN = "*";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package cn.dev33.satoken.oauth2.util;
|
||||
|
||||
/**
|
||||
* sa-token-oauth2 模块内部算法util
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaOAuth2InsideUtil {
|
||||
|
||||
/**
|
||||
* 验证URL的正则表达式
|
||||
*/
|
||||
static final String URL_REGEX = "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]";
|
||||
|
||||
/**
|
||||
* 使用正则表达式判断一个字符串是否为URL
|
||||
* @param str 字符串
|
||||
* @return 拼接后的url字符串
|
||||
*/
|
||||
public static boolean isUrl(String str) {
|
||||
if(str == null) {
|
||||
return false;
|
||||
}
|
||||
return str.toLowerCase().matches(URL_REGEX);
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user