!239 增加 sa-token-demo-sso-client-solon 相关示例

Merge pull request !239 from 西东/dev
This commit is contained in:
孔明 2023-03-13 10:21:49 +00:00 committed by Gitee
commit 139606bcc2
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
22 changed files with 637 additions and 4 deletions

View File

@ -10,7 +10,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.34.0</sa-token.version>
<solon.version>2.2.1</solon.version>
<solon.version>2.2.3</solon.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

View File

@ -9,7 +9,7 @@
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.34.0</sa-token.version>
<solon.version>2.2.1</solon.version>
<solon.version>2.2.3</solon.version>
</properties>
<dependencies>

View File

@ -0,0 +1,54 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-demo-sso1-client-solon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- Solon -->
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.2.3</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.34.0</sa-token.version>
</properties>
<dependencies>
<!-- Solon 依赖 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-api</artifactId>
</dependency>
<!-- Sa-Token 权限认证, 在线文档https://sa-token.cc/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-solon-plugin</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 插件整合SSO -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 redisx -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redisx</artifactId>
<version>${sa-token.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.pj;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoOfRedis;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* @author noear 2023/3/13 created
*/
@Configuration
public class SaConfig {
/**
* 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token-dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
}

View File

@ -0,0 +1,20 @@
package com.pj;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
/**
* SSO模式一Client端 Demo
* @author kong
*
*/
@SolonMain
public class SaSso1ClientApp {
public static void main(String[] args) {
Solon.start(SaSso1ClientApp.class, args);
System.out.println("\nSa-Token SSO模式一 Client端启动成功");
}
}

View File

@ -0,0 +1,40 @@
package com.pj.sso;
import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;
/**
* Sa-Token-SSO Client端 Controller
* @author kong
*/
@Controller
public class SsoClientController implements Render {
// SSO-Client端首页
@Mapping("/")
public String index() {
String authUrl = SaSsoManager.getConfig().splicingAuthUrl();
String solUrl = SaSsoManager.getConfig().splicingSloUrl();
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
"<p><a href=\"javascript:location.href='" + authUrl + "?mode=simple&redirect=' + encodeURIComponent(location.href);\">登录</a> " +
"<a href=\"javascript:location.href='" + solUrl + "?back=' + encodeURIComponent(location.href);\">注销</a> </p>";
return str;
}
// 全局异常拦截并转换
@Override
public void render(Object data, Context ctx) throws Throwable {
if(data instanceof Exception){
data = SaResult.error(((Exception)data).getMessage());
}
ctx.render(data);
}
}

View File

@ -0,0 +1,25 @@
# 端口
server:
port: 9001
# Sa-Token 配置
sa-token:
# SSO-相关配置
sso:
# SSO-Server端-单点登录授权地址
auth-url: http://sso.stp.com:9000/sso/auth
# SSO-Server端-单点注销地址
slo-url: http://sso.stp.com:9000/sso/signout
# 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
sa-token-dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
db: 1
maxTotal: 200

View File

@ -0,0 +1,53 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-demo-sso2-client-solon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- Solon -->
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.2.3</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.34.0</sa-token.version>
</properties>
<dependencies>
<!-- Solon 依赖 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-api</artifactId>
</dependency>
<!-- Sa-Token 权限认证, 在线文档https://sa-token.cc/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-solon-plugin</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 插件整合SSO -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 redisx -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redisx</artifactId>
<version>${sa-token.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.pj;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoOfRedis;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* @author noear 2023/3/13 created
*/
@Configuration
public class SaConfig {
/**
* 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token-dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
}

View File

@ -0,0 +1,15 @@
package com.pj;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
@SolonMain
public class SaSso2ClientApp {
public static void main(String[] args) {
Solon.start(SaSso2ClientApp.class, args);
System.out.println("\nSa-Token SSO模式二 Client端启动成功");
}
}

View File

@ -0,0 +1,38 @@
package com.pj.h5;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
/**
* 跨域过滤器
* @author kong
*/
@Component(index = -200)
public class CorsFilter implements Filter {
static final String OPTIONS = "OPTIONS";
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
// 允许指定域访问跨域资源
ctx.headerSet("Access-Control-Allow-Origin", "*");
// 允许所有请求方式
ctx.headerSet("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
// 有效时间
ctx.headerSet("Access-Control-Max-Age", "3600");
// 允许的header参数
ctx.headerSet("Access-Control-Allow-Headers", "x-requested-with,satoken");
// 如果是预检请求直接返回
if (OPTIONS.equals(ctx.method())) {
System.out.println("=======================浏览器发来了OPTIONS预检请求==========");
ctx.output("");
return;
}
// System.out.println("*********************************过滤器被使用**************************");
chain.doFilter(ctx);
}
}

View File

@ -0,0 +1,55 @@
package com.pj.h5;
import cn.dev33.satoken.sso.SaSsoProcessor;
import cn.dev33.satoken.sso.SaSsoUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;
/**
* 前后台分离架构下集成SSO所需的代码 SSO-Client端
* <p>如果不需要前后端分离架构下集成SSO可删除此包下所有代码</p>
* @author kong
*
*/
@Controller
public class H5Controller implements Render {
// 当前是否登录
@Mapping("/sso/isLogin")
public Object isLogin() {
return SaResult.data(StpUtil.isLogin());
}
// 返回SSO认证中心登录地址
@Mapping("/sso/getSsoAuthUrl")
public SaResult getSsoAuthUrl(String clientLoginUrl) {
String serverAuthUrl = SaSsoUtil.buildServerAuthUrl(clientLoginUrl, "");
return SaResult.data(serverAuthUrl);
}
// 根据ticket进行登录
@Mapping("/sso/doLoginByTicket")
public SaResult doLoginByTicket(String ticket) {
Object loginId = SaSsoProcessor.instance.checkTicket(ticket, "/sso/doLoginByTicket");
if(loginId != null) {
StpUtil.login(loginId);
return SaResult.data(StpUtil.getTokenValue());
}
return SaResult.error("无效ticket" + ticket);
}
// 全局异常拦截并转换
@Override
public void render(Object data, Context ctx) throws Throwable {
if(data instanceof Exception){
data = SaResult.error(((Exception)data).getMessage());
}
ctx.render(data);
}
}

View File

@ -0,0 +1,49 @@
package com.pj.sso;
import cn.dev33.satoken.sso.SaSsoProcessor;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;
/**
* Sa-Token-SSO Client端 Controller
* @author kong
*/
@Controller
public class SsoClientController implements Render {
// 首页
@Mapping("/")
public String index() {
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a> " +
"<a href='/sso/logout?back=self'>注销</a></p>";
return str;
}
/*
* SSO-Client端处理所有SSO相关请求
* http://{host}:{port}/sso/login -- Client端登录地址接受参数back=登录后的跳转地址
* http://{host}:{port}/sso/logout -- Client端单点注销地址isSlo=true时打开接受参数back=注销后的跳转地址
* http://{host}:{port}/sso/logoutCall -- Client端单点注销回调地址isSlo=true时打开此接口为框架回调开发者无需关心
*/
@Mapping("/sso/*")
public Object ssoRequest() {
return SaSsoProcessor.instance.clientDister();
}
// 全局异常拦截并转换
@Override
public void render(Object data, Context ctx) throws Throwable {
if(data instanceof Exception){
data = SaResult.error(((Exception)data).getMessage());
}
ctx.render(data);
}
}

View File

@ -0,0 +1,26 @@
# 端口
server:
port: 9001
# sa-token配置
sa-token:
# SSO-相关配置
sso:
# SSO-Server端 统一认证地址
auth-url: http://sa-sso-server.com:9000/sso/auth
# auth-url: http://127.0.0.1:8848/sa-token-demo-sso-server-h5/sso-auth.html
# 是否打开单点注销接口
is-slo: true
# 配置 Sa-Token 单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
sa-token-dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
db: 1
maxTotal: 200

View File

@ -0,0 +1,62 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-demo-sso3-client-solon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- Solon -->
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>2.2.3</version>
<relativePath/>
</parent>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<sa-token.version>1.34.0</sa-token.version>
</properties>
<dependencies>
<!-- Solon 依赖 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-api</artifactId>
</dependency>
<!-- Sa-Token 权限认证, 在线文档https://sa-token.cc/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-solon-plugin</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 插件整合SSO -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 redisx -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redisx</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Http 请求工具 -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-solon-plugin</artifactId>
<version>1.5.29</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.pj;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoOfRedis;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* @author noear 2023/3/13 created
*/
@Configuration
public class SaConfig {
/**
* 构建建 SaToken redis dao如果不需要 redis可以注释掉
* */
@Bean
public SaTokenDao saTokenDaoInit(@Inject("${sa-token-dao.redis}") SaTokenDaoOfRedis saTokenDao) {
return saTokenDao;
}
}

View File

@ -0,0 +1,14 @@
package com.pj;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
@SolonMain
public class SaSso3ClientApp {
public static void main(String[] args) {
Solon.start(SaSso3ClientApp.class, args);
System.out.println("\nSa-Token SSO模式三 Client端启动成功");
}
}

View File

@ -0,0 +1,57 @@
package com.pj.sso;
import cn.dev33.satoken.sso.SaSsoProcessor;
import cn.dev33.satoken.sso.SaSsoUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;
/**
* Sa-Token-SSO Client端 Controller
* @author kong
*/
@Controller
public class SsoClientController implements Render {
// SSO-Client端首页
@Mapping("/")
public String index() {
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a>" +
" <a href='/sso/logout?back=self'>注销</a></p>";
return str;
}
/*
* SSO-Client端处理所有SSO相关请求
* http://{host}:{port}/sso/login -- Client端登录地址接受参数back=登录后的跳转地址
* http://{host}:{port}/sso/logout -- Client端单点注销地址isSlo=true时打开接受参数back=注销后的跳转地址
* http://{host}:{port}/sso/logoutCall -- Client端单点注销回调地址isSlo=true时打开此接口为框架回调开发者无需关心
*/
@Mapping("/sso/*")
public Object ssoRequest() {
return SaSsoProcessor.instance.clientDister();
}
// 查询我的账号信息
@Mapping("/sso/myinfo")
public Object myinfo() {
Object userinfo = SaSsoUtil.getUserinfo(StpUtil.getLoginId());
System.out.println("--------info" + userinfo);
return userinfo;
}
// 全局异常拦截并转换
@Override
public void render(Object data, Context ctx) throws Throwable {
if(data instanceof Exception){
data = SaResult.error(((Exception)data).getMessage());
}
ctx.render(data);
}
}

View File

@ -0,0 +1,22 @@
package com.pj.sso;
import cn.dev33.satoken.config.SaSsoConfig;
import com.dtflys.forest.Forest;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
/**
* @author noear 2023/3/13 created
*/
@Configuration
public class SsoConfig {
// 配置SSO相关参数
@Bean
private void configSso(SaSsoConfig sso) {
// 配置Http请求处理器
sso.setSendHttp(url -> {
System.out.println("------ 发起请求:" + url);
return Forest.get(url).executeAsString();
});
}
}

View File

@ -0,0 +1,38 @@
# 端口
server:
port: 9001
# sa-token配置
sa-token:
# SSO-相关配置
sso:
# SSO-Server端 统一认证地址
auth-url: http://sa-sso-server.com:9000/sso/auth
# 使用Http请求校验ticket
is-http: true
# SSO-Server端 ticket校验地址
check-ticket-url: http://sa-sso-server.com:9000/sso/checkTicket
# 打开单点注销功能
is-slo: true
# 单点注销地址
slo-url: http://sa-sso-server.com:9000/sso/signout
# 接口调用秘钥
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# SSO-Server端 查询userinfo地址
userinfo-url: http://sa-sso-server.com:9000/sso/userinfo
# 配置 Sa-Token Dao此处与SSO-Server端连接不同的Redis
sa-token-dao: #名字可以随意取
redis:
server: "localhost:6379"
password: 123456
db: 2
maxTotal: 200
forest:
# 关闭 forest 请求日志打印
log-enabled: false

View File

@ -23,7 +23,7 @@
<servlet-api.version>3.1.0</servlet-api.version>
<jakarta-servlet-api.version>6.0.0</jakarta-servlet-api.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<solon.version>2.2.1</solon.version>
<solon.version>2.2.3</solon.version>
<noear-redisx.version>1.4.5</noear-redisx.version>
<noear-snack3.version>3.2.54</noear-snack3.version>
<jfinal.version>4.9.17</jfinal.version>

View File

@ -10,7 +10,6 @@ import java.util.Properties;
* @author noear
* @since 1.6
*/
@Deprecated
public class SaTokenDaoOfRedis extends SaTokenDaoOfRedisBase64 {
public SaTokenDaoOfRedis(Properties props) {