init:初始化项目

master
HuangHuiKang 2 months ago
commit c79d96e14b

33
.gitignore vendored

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

@ -0,0 +1,264 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ngskcloud</groupId>
<artifactId>bpms-sso</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>bpms-sso</name>
<description>bpms-sso</description>
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.2.3</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
<!-- 如果你想要使用 Jackson 处理 JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 如果你想要完整的 Jackson 支持 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>12.1</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!-- </dependency>-->
<!-- Sa-Token 权限认证在线文档https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>1.44.0</version>
</dependency>
<!-- Sa-Token 插件整合SSO -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-sso</artifactId>
<version>1.44.0</version>
</dependency>
<!-- Sa-Token 插件:整合 RedisTemplate -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-template</artifactId>
<version>1.44.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Sa-Token 插件:整合 Forest 请求工具 (模式三需要通过 http 请求推送消息) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-forest</artifactId>
<version>1.44.0</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>1.44.0</version>
</dependency>
<!-- spring-cloud-alibaba -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2023.0.3.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2023.0.3.3</version>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.12.6</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mybatis -->
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>3.0.5</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
<version>5.8.39</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>5.8.39</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.39</version>
</dependency>
<!--feign-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!-- </dependency>-->
<!-- &lt;!&ndash;客户端负载均衡策略替换原来的Ribbon&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-loadbalancer</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.github.openfeign</groupId>-->
<!-- <artifactId>feign-httpclient</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.github.openfeign.form</groupId>-->
<!-- <artifactId>feign-form</artifactId>-->
<!-- <version>3.8.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.github.openfeign.form</groupId>-->
<!-- <artifactId>feign-form-spring</artifactId>-->
<!-- <version>3.8.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.github.openfeign</groupId>-->
<!-- <artifactId>feign-httpclient</artifactId>-->
<!-- <version>10.10.1</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>commons-logging</groupId>-->
<!-- <artifactId>commons-logging</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>druid-spring-boot-3-starter</artifactId>-->
<!-- <version>1.2.25</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>javax.servlet</groupId>-->
<!-- <artifactId>javax.servlet-api</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>21</source>
<target>21</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.ngskcloud.BpmsSsoApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,30 @@
package com.ngskcloud;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.sso.SaSsoManager;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.net.UnknownHostException;
@SpringBootApplication
@MapperScan("com.ngskcloud.mapper") // 添加在这里
public class BpmsSsoApplication {
public static void main(String[] args) throws UnknownHostException {
SpringApplication.run(BpmsSsoApplication.class, args);
System.out.println();
System.out.println("---------------------- Sa-Token SSO 统一认证中心启动成功 ----------------------");
System.out.println("配置信息:" + SaSsoManager.getServerConfig());
System.out.println("统一认证登录地址http://sa-sso-server.com:9000/sso/auth");
System.out.println("测试前需要根据官网文档修改 hosts 文件测试账号密码sa / 123456");
System.out.println();
}
}

@ -0,0 +1,15 @@
package com.ngskcloud.advise;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 全局异常拦截
@ExceptionHandler
public SaResult handlerException(Exception e) {
e.printStackTrace();
return SaResult.error(e.getMessage());
}
}

@ -0,0 +1,24 @@
package com.ngskcloud.config;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfig {
@Bean
public Encoder feignEncoder() {
return new JacksonEncoder();
}
@Bean
public Decoder feignDecoder() {
return new JacksonDecoder();
}
}

@ -0,0 +1,9 @@
package com.ngskcloud.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
//@Configuration
//@MapperScan("com.ngskcloud.mapper")
//public class MybatisConfig {
//}

@ -0,0 +1,17 @@
package com.ngskcloud.config;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.stp.StpLogic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SaTokenConfig {
// Sa-Token 整合 jwt (Simple 简单模式)
@Bean
public StpLogic getStpLogicJwt() {
return new StpLogicJwtForSimple();
}
}

@ -0,0 +1,20 @@
package com.ngskcloud.constant;
public class SystemConstant {
public static final String VERSION = "v1.0-beta1";
public static final String ENV_PROD = "prod";
public static final String REDIS_PREFIX = "playedu:";
public static final String JWT_PRV_ADMIN_USER =
"dc14511e97e7eb725fb2976bc939b375"; // AdminUser的md5加密
public static final String JWT_PRV_USER = "8f9bfe9d1345237cb3b2b205864da075"; // User的md5加密
public static final String INTERNAL_IP = "127.0.0.1";
public static final String INTERNAL_IP_AREA = "内网";
public static final String CONFIG_MASK = "********";
}

@ -0,0 +1,348 @@
package com.ngskcloud.controller;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.sso.model.TicketModel;
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
import cn.dev33.satoken.sso.processor.SaSsoServerProcessor;
import cn.dev33.satoken.sso.template.SaSsoClientTemplate;
import cn.dev33.satoken.sso.template.SaSsoServerTemplate;
import cn.dev33.satoken.sso.template.SaSsoServerUtil;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.ngskcloud.constant.SystemConstant;
import com.ngskcloud.entity.AdminUser;
import com.ngskcloud.entity.User;
import com.ngskcloud.service.AdminUserService;
import com.ngskcloud.service.UserService;
import com.ngskcloud.utils.DigestUtil;
import com.ngskcloud.utils.JwtUtil;
import com.ngskcloud.utils.RequestUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* SSO
*/
@RestController
@RequestMapping
@RequiredArgsConstructor
public class SsoServerController {
@Value("${sa-token.timeout}")
private Integer expired;
@Value("${sa-token.sso-server.clients.sso-client2.client}")
private String clientName;
@Autowired
private JwtUtil jwtUtil;
private final UserService userService;
private final AdminUserService adminUserService;
// private final RedisTemplate redisTemplate;
// /**
// * 统一认证入口 - 处理未明确指定的SSO请求
// */
// @RequestMapping("/auth")
// public Object auth(HttpServletRequest request) {
// return SaSsoServerProcessor.instance.dister();
// }
//
/**
*
*/
@GetMapping("/sso/doLogin")
public SaResult doLogin(@RequestParam("username") String username, @RequestParam("pwd") String pwd,@RequestParam("identity") Integer identity) {
// 根据identity判断登录类型
if (identity == null ){
return SaResult.error("identity字段不能为空");
}else if (1==identity) {
return getUserSaResult(username, pwd,identity);
} else if (2==identity) {
return getAdminSaResult(username, pwd,identity);
} else {
return SaResult.error("identity字段仅能为1-用户或者2-admin");
}
}
private SaResult getUserSaResult(String account, String pwd,Integer identity) {
User user = userService.find(account);
if (user == null) {
return SaResult.error("账号或密码错误");
}
if (!DigestUtil.encrypt(pwd).equals(user.getPassword())) {
return SaResult.error("账号或密码错误");
}
if (user.getIsLock() == 1) {
return SaResult.error("当前学员已锁定无法登录");
}
StpUtil.login(
user.getId(),
SaLoginConfig.setExtra("url", RequestUtil.url())
.setExtra("user_name",user.getName())
.setExtra("account",user.getAccount())
.setExtra("user_id",user.getId())
.setExtra("avatar",user.getAvatar())
.setExtra("jti", UUID.randomUUID().toString())
.setExtra("prv", SystemConstant.JWT_PRV_USER)
.setExtra("tenant_id", "000000")
.setExtra(
"exp",
String.valueOf(
System.currentTimeMillis() / 1000
+ expired)));
String ticketAndSave = SaSsoServerUtil.createTicketAndSave(clientName, user.getId(), StpUtil.getTokenValue());
return SaResult.ok("登录成功!").setData(ticketAndSave);
}
private SaResult getAdminSaResult(String account, String pwd,Integer identity) {
AdminUser adminUser = adminUserService.findByAccount(account);
if (adminUser == null) {
return SaResult.error("账号密码错误!");
}
String password = DigestUtil.encrypt(pwd);
if (!adminUser.getPassword().equals(password)) {
return SaResult.error("账号或密码错误");
}
if (adminUser.getIsBanLogin().equals(1)) {
return SaResult.error("当前管理员已禁止登录");
}
// StpUtil.login(adminUser.getId());
StpUtil.login(
adminUser.getId(),
SaLoginConfig.setExtra("url", RequestUtil.url())
.setExtra("prv", SystemConstant.JWT_PRV_ADMIN_USER)
.setExtra("identity", identity)
.setExtra(
"exp",
String.valueOf(
System.currentTimeMillis() / 1000
+expired)));
String ticketAndSave = SaSsoServerUtil.createTicketAndSave(clientName, adminUser.getId(), StpUtil.getTokenValue());
return SaResult.ok("登录成功!").setData(ticketAndSave);
}
// 注销
@PostMapping("/sso/logout")
public SaResult logout() {
try {
StpUtil.logout();
return SaResult.ok();
}catch (Exception e){
throw new RuntimeException("登出错误");
}
}
// 验证ticket是否有效
@GetMapping("/sso/checkTicket")
public SaResult checkTicket(@RequestParam(value = "ticket") String ticket,@RequestParam(value = "identity") Integer identity) {
//验证票据
// TicketModel ticketModel = SaSsoServerUtil.checkTicketParamAndDelete(ticket);
TicketModel ticketModel = SaSsoServerUtil.checkTicket(ticket);
if (ticketModel != null) {
// 将当前会话设置为ticket对应的登录状态
StpUtil.setTokenValue(ticketModel.getTokenValue());
}
// StpUtil.isLogin() 为 true
boolean currentIsLogin = StpUtil.isLogin();
Map<String,Object> map= new HashMap<>();
if (1==identity){
User user = userService.find((Long)ticketModel.getLoginId());
map.put("token",ticketModel.getTokenValue());
map.put("id",user.getId());
map.put("ticketModel",ticketModel);
map.put("account",user.getAccount());
}else if(2==identity){
AdminUser adminUser = adminUserService.findById((Long)ticketModel.getLoginId());
map.put("token",ticketModel.getTokenValue());
map.put("id",adminUser.getId());
map.put("loginTimes",adminUser.getLoginTimes());
map.put("ticketModel",ticketModel);
}
return SaResult.ok("验证成功!").setData(map);
}
// // 会话是否登录
// @GetMapping("/sso/isLogin")
// public SaResult isLogin(@RequestParam(value = "token", required = false) String token) {
//// StpUtil.getTokenValue();
//
//// if (token != null && !token.trim().isEmpty()) {
//// StpUtil.setTokenValue(token);
//// }
//// return SaResult.ok("验证成功!").setData(StpUtil.isLogin());
//
// try {
// // 1. 参数校验
// if (token == null || token.trim().isEmpty()) {
// return SaResult.error("token不能为空").setData(400);
// }
////
//// if (identity == null) {
//// return SaResult.error("identity身份类型不能为空").setCode(400);
//// }
////
//// if (identity != 1 && identity != 2) {
//// return SaResult.error("identity只能为1(用户)或2(管理员)").setCode(400);
//// }
////
// // 2. 设置当前token上下文
// StpUtil.setTokenValue(token);
//
// // 3. 基础登录状态验证
// if (!StpUtil.isLogin()) {
// return SaResult.error("token无效或已过期").setCode(401);
// }
//
// // 4. 获取登录ID并验证身份一致性
// Object loginId = StpUtil.getLoginIdDefaultNull();
// if (loginId == null) {
// return SaResult.error("无法获取用户信息").setCode(401);
// }
//
// // 5. 验证token活跃状态防止token被踢出
// if (!StpUtil.isLogin(loginId)) {
// return SaResult.error("token已被踢出或失效").setCode(401);
// }
//
//
// // 6. 根据身份类型进行额外验证
// Integer identity = (Integer) StpUtil.getExtra("identity","");
//
// boolean isValid = validateUserIdentity(loginId,identity,token);
// if (!isValid) {
// return SaResult.error("身份类型与token不匹配").setCode(403);
// }
//
// // 7. 获取token剩余有效期
// long timeout = StpUtil.getTokenTimeout();
//
//// // 8. 返回详细的验证结果
//// Map<String, Object> result = new HashMap<>();
//// result.put("isLogin", true);
//// result.put("loginId", loginId);
//// result.put("tokenTimeout", timeout);
//// result.put("tokenActive", StpUtil.getTokenActiveTimeout());
//// result.put("sessionTimeout", StpUtil.getTokenSessionTimeout());
//
// // 添加用户基本信息
//// addUserInfoToResult(result, loginId, identity);
//
// return SaResult.ok("token验证成功").setData(Boolean.TRUE);
//
// } catch (Exception e) {
// // 记录日志
// // log.error("token验证异常: {}", e.getMessage(), e);
// return SaResult.error("token验证异常: " + e.getMessage()).setCode(500);
// }
//
// }
// // 会话是否登录
// @GetMapping("/sso/isLogin")
// public SaResult isLogin() {
// StpUtil.getTokenValue();
//
// return SaResult.ok("验证成功!").setData(StpUtil.isLogin());
// }
// 会话是否登录
@GetMapping("/sso/isLogin")
public SaResult isLogin() {
StpUtil.getTokenValue();
// System.out.println( StpUtil.getTokenValue());
// if (token != null && !token.trim().isEmpty()) {
// StpUtil.setTokenValue(token);
// }
return SaResult.ok("验证成功!").setData(StpUtil.isLogin());
}
/**
*
*/
private boolean validateUserIdentity(Object loginId, Integer identity, String token) {
try {
// 从token中获取prv字段进行验证
String prv = StpUtil.getExtra("prv", "").toString();
if (identity == 1) {
// 用户身份验证
return SystemConstant.JWT_PRV_USER.equals(prv);
} else if (identity == 2) {
// 管理员身份验证
return SystemConstant.JWT_PRV_ADMIN_USER.equals(prv);
}
return false;
} catch (Exception e) {
// 如果无法从token中获取prv则通过数据库验证
return validateUserIdentityFromDB(loginId, identity);
}
}
/**
*
*/
private boolean validateUserIdentityFromDB(Object loginId, Integer identity) {
try {
Long userId = Long.parseLong(loginId.toString());
if (identity == 1) {
User user = userService.find(userId);
return user != null && user.getIsLock() == 0; // 同时验证是否被锁定
} else if (identity == 2) {
AdminUser adminUser = adminUserService.findById(userId);
return adminUser != null && adminUser.getIsBanLogin() == 0; // 验证是否被禁止登录
}
return false;
} catch (Exception e) {
return false;
}
}
}

@ -0,0 +1,174 @@
package com.ngskcloud.entity;/*
*
*
* 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.
*/
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
import java.util.Date;
/**
* @TableName admin_users
*/
@TableName(value = "admin_users")
@Data
@Slf4j
public class AdminUser implements Serializable {
/** */
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/** 姓名 */
private String name;
/** 邮箱 */
private String email;
/** 密码 */
@JsonIgnore private String password;
/** Salt */
@JsonIgnore private String salt;
/** 登录IP */
@JsonProperty("login_ip")
private String loginIp;
/** 登录时间 */
@JsonProperty("login_at")
private Date loginAt;
/** 1禁止登录,0否 */
@JsonProperty("is_ban_login")
private Integer isBanLogin;
/** 登录次数 */
@JsonProperty("login_times")
private Integer loginTimes;
/** 登陆账号 */
@JsonProperty("account")
private String account;
@JsonProperty("created_at")
private Date createdAt;
@JsonProperty("updated_at")
private Date updatedAt;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
// @JsonGetter("email")
// public String transformEmail() {
// return BackendBus.valueHidden(
// BPermissionConstant.DATA_ADMIN_EMAIL,
// BackendConstant.PRIVACY_FIELD_TYPE_EMAIL,
// email);
// }
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
AdminUser other = (AdminUser) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getName() == null
? other.getName() == null
: this.getName().equals(other.getName()))
&& (this.getEmail() == null
? other.getEmail() == null
: this.getEmail().equals(other.getEmail()))
&& (this.getPassword() == null
? other.getPassword() == null
: this.getPassword().equals(other.getPassword()))
&& (this.getSalt() == null
? other.getSalt() == null
: this.getSalt().equals(other.getSalt()))
&& (this.getLoginIp() == null
? other.getLoginIp() == null
: this.getLoginIp().equals(other.getLoginIp()))
&& (this.getLoginAt() == null
? other.getLoginAt() == null
: this.getLoginAt().equals(other.getLoginAt()))
&& (this.getIsBanLogin() == null
? other.getIsBanLogin() == null
: this.getIsBanLogin().equals(other.getIsBanLogin()))
&& (this.getLoginTimes() == null
? other.getLoginTimes() == null
: this.getLoginTimes().equals(other.getLoginTimes()))
&& (this.getCreatedAt() == null
? other.getCreatedAt() == null
: this.getCreatedAt().equals(other.getCreatedAt()))
&& (this.getUpdatedAt() == null
? other.getUpdatedAt() == null
: this.getUpdatedAt().equals(other.getUpdatedAt()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
result = prime * result + ((getEmail() == null) ? 0 : getEmail().hashCode());
result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
result = prime * result + ((getSalt() == null) ? 0 : getSalt().hashCode());
result = prime * result + ((getLoginIp() == null) ? 0 : getLoginIp().hashCode());
result = prime * result + ((getLoginAt() == null) ? 0 : getLoginAt().hashCode());
result = prime * result + ((getIsBanLogin() == null) ? 0 : getIsBanLogin().hashCode());
result = prime * result + ((getLoginTimes() == null) ? 0 : getLoginTimes().hashCode());
result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", name=").append(name);
sb.append(", email=").append(email);
sb.append(", password=").append(password);
sb.append(", salt=").append(salt);
sb.append(", loginIp=").append(loginIp);
sb.append(", loginAt=").append(loginAt);
sb.append(", isBanLogin=").append(isBanLogin);
sb.append(", loginTimes=").append(loginTimes);
sb.append(", createdAt=").append(createdAt);
sb.append(", updatedAt=").append(updatedAt);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

@ -0,0 +1,266 @@
package com.ngskcloud.entity;/*
*
*
* 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.
*/
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* @TableName users
*/
@TableName(value = "users")
@Data
public class User implements Serializable {
/** */
@TableId(type = IdType.ASSIGN_ID)
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long id;
/** 邮件 */
private String email;
/** 真实姓名 */
private String name;
/** 头像 */
private String avatar;
/** 密码 */
@JsonIgnore private String password;
/** salt */
@JsonIgnore private String salt;
/** 身份证号 */
@JsonProperty("id_card")
private String idCard;
/** 学分 */
private Integer credit1;
/** 注册Ip */
@JsonProperty("create_ip")
private String createIp;
/** 注册城市 */
@JsonProperty("create_city")
private String createCity;
/** 激活[1:是,0:否] */
@JsonProperty("is_active")
private Integer isActive;
/** 锁定[1:是,0:否] */
@JsonProperty("is_lock")
private Integer isLock;
/** 实名认证[1:是,0:否] */
@JsonProperty("is_verify")
private Integer isVerify;
/** 实名认证时间 */
@JsonProperty("verify_at")
private Date verifyAt;
/** 设置密码[1:是,0:否] */
@JsonProperty("is_set_password")
private Integer isSetPassword;
/** 登录时间 */
@JsonProperty("login_at")
private Date loginAt;
@JsonProperty("created_at")
private Date createdAt;
@JsonProperty("updated_at")
private Date updatedAt;
@TableLogic
private Integer isDeleted;
/** 同步状态 0-未同步 1-同步成功 2-同步失败 */
@JsonProperty("sync_status")
private int syncStatus;
/** 同步失败原因 */
@JsonProperty("sync_remark")
private String syncRemark;
/** 同步时间 */
@JsonProperty("sync_time")
private Date syncTime;
/** gitea账号 */
@JsonProperty("gitea_user")
private String giteaUser;
/** 账号 */
@JsonProperty("account")
private String account;
/** 管理员关联账号 */
@JsonProperty("admin_user")
private Integer adminUser;
// @TableField(exist = false)
// private List<UserSyncInfo> userSyncInfoList;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
// @JsonGetter("name")
// public String transformName() {
// return BackendBus.valueHidden(
// BPermissionConstant.DATA_USER_NAME,
// BackendConstant.PRIVACY_FIELD_TYPE_NAME,
// getName());
// }
// @JsonGetter("email")
// public String transformEmail() {
// return BackendBus.valueHidden(
// BPermissionConstant.DATA_USER_EMAIL,
// BackendConstant.PRIVACY_FIELD_TYPE_EMAIL,
// getEmail());
// }
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
User other = (User) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getEmail() == null
? other.getEmail() == null
: this.getEmail().equals(other.getEmail()))
&& (this.getName() == null
? other.getName() == null
: this.getName().equals(other.getName()))
&& (this.getAvatar() == null
? other.getAvatar() == null
: this.getAvatar().equals(other.getAvatar()))
&& (this.getPassword() == null
? other.getPassword() == null
: this.getPassword().equals(other.getPassword()))
&& (this.getSalt() == null
? other.getSalt() == null
: this.getSalt().equals(other.getSalt()))
&& (this.getIdCard() == null
? other.getIdCard() == null
: this.getIdCard().equals(other.getIdCard()))
&& (this.getCredit1() == null
? other.getCredit1() == null
: this.getCredit1().equals(other.getCredit1()))
&& (this.getCreateIp() == null
? other.getCreateIp() == null
: this.getCreateIp().equals(other.getCreateIp()))
&& (this.getCreateCity() == null
? other.getCreateCity() == null
: this.getCreateCity().equals(other.getCreateCity()))
&& (this.getIsActive() == null
? other.getIsActive() == null
: this.getIsActive().equals(other.getIsActive()))
&& (this.getIsLock() == null
? other.getIsLock() == null
: this.getIsLock().equals(other.getIsLock()))
&& (this.getIsVerify() == null
? other.getIsVerify() == null
: this.getIsVerify().equals(other.getIsVerify()))
&& (this.getVerifyAt() == null
? other.getVerifyAt() == null
: this.getVerifyAt().equals(other.getVerifyAt()))
&& (this.getIsSetPassword() == null
? other.getIsSetPassword() == null
: this.getIsSetPassword().equals(other.getIsSetPassword()))
&& (this.getLoginAt() == null
? other.getLoginAt() == null
: this.getLoginAt().equals(other.getLoginAt()))
&& (this.getCreatedAt() == null
? other.getCreatedAt() == null
: this.getCreatedAt().equals(other.getCreatedAt()))
&& (this.getUpdatedAt() == null
? other.getUpdatedAt() == null
: this.getUpdatedAt().equals(other.getUpdatedAt()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getEmail() == null) ? 0 : getEmail().hashCode());
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
result = prime * result + ((getAvatar() == null) ? 0 : getAvatar().hashCode());
result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
result = prime * result + ((getSalt() == null) ? 0 : getSalt().hashCode());
result = prime * result + ((getIdCard() == null) ? 0 : getIdCard().hashCode());
result = prime * result + ((getCredit1() == null) ? 0 : getCredit1().hashCode());
result = prime * result + ((getCreateIp() == null) ? 0 : getCreateIp().hashCode());
result = prime * result + ((getCreateCity() == null) ? 0 : getCreateCity().hashCode());
result = prime * result + ((getIsActive() == null) ? 0 : getIsActive().hashCode());
result = prime * result + ((getIsLock() == null) ? 0 : getIsLock().hashCode());
result = prime * result + ((getIsVerify() == null) ? 0 : getIsVerify().hashCode());
result = prime * result + ((getVerifyAt() == null) ? 0 : getVerifyAt().hashCode());
result =
prime * result + ((getIsSetPassword() == null) ? 0 : getIsSetPassword().hashCode());
result = prime * result + ((getLoginAt() == null) ? 0 : getLoginAt().hashCode());
result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", email=").append(email);
sb.append(", name=").append(name);
sb.append(", avatar=").append(avatar);
sb.append(", password=").append(password);
sb.append(", salt=").append(salt);
sb.append(", idCard=").append(idCard);
sb.append(", credit1=").append(credit1);
sb.append(", createIp=").append(createIp);
sb.append(", createCity=").append(createCity);
sb.append(", isActive=").append(isActive);
sb.append(", isLock=").append(isLock);
sb.append(", isVerify=").append(isVerify);
sb.append(", verifyAt=").append(verifyAt);
sb.append(", isSetPassword=").append(isSetPassword);
sb.append(", loginAt=").append(loginAt);
sb.append(", createdAt=").append(createdAt);
sb.append(", updatedAt=").append(updatedAt);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

@ -0,0 +1,46 @@
package com.ngskcloud.feign;
import cn.dev33.satoken.util.SaResult;
import com.ngskcloud.config.FeignConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
/**
* SSO OpenFeign
* Nacos SSO
*/
@FeignClient(name = "sso-server", path = "/sso", configuration = FeignConfig.class)
public interface SsoServerClient {
/**
*
*/
@GetMapping("/doLogin")
SaResult doLogin(@RequestParam("username") String account,
@RequestParam("pwd") String pwd,
@RequestParam("identity") Integer identity);
/**
* ticket
*/
@GetMapping("/checkTicket")
SaResult checkTicket(@RequestParam("ticket") String ticket,
@RequestParam("identity") Integer identity);
/**
*
*/
@GetMapping("/isLogin")
SaResult isLogin();
/**
*
*/
@PostMapping("/logout")
SaResult logout();
}

@ -0,0 +1,18 @@
package com.ngskcloud.interceptor;
import cn.dev33.satoken.interceptor.SaInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SaTokenInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
registry.addInterceptor(new SaInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/sso/**", "/error");
}
}

@ -0,0 +1,10 @@
package com.ngskcloud.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ngskcloud.entity.AdminUser;
import org.apache.ibatis.annotations.Mapper;
//@Mapper
public interface AdminUserMapper extends BaseMapper<AdminUser> {
}

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ngskcloud.mapper.AdminUserMapper">
<resultMap id="BaseResultMap" type="com.ngskcloud.entity.AdminUser">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="email" column="email" jdbcType="VARCHAR"/>
<result property="password" column="password" jdbcType="VARCHAR"/>
<result property="salt" column="salt" jdbcType="VARCHAR"/>
<result property="loginIp" column="login_ip" jdbcType="VARCHAR"/>
<result property="loginAt" column="login_at" jdbcType="TIMESTAMP"/>
<result property="isBanLogin" column="is_ban_login" jdbcType="TINYINT"/>
<result property="loginTimes" column="login_times" jdbcType="INTEGER"/>
<result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
<result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id
,name,email,
password,salt,login_ip,
login_at,is_ban_login,login_times,
created_at,updated_at
</sql>
</mapper>

@ -0,0 +1,10 @@
package com.ngskcloud.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ngskcloud.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ngskcloud.mapper.UserMapper">
</mapper>

@ -0,0 +1,12 @@
package com.ngskcloud.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ngskcloud.entity.AdminUser;
public interface AdminUserService extends IService<AdminUser> {
AdminUser findByAccount(String account);
AdminUser findById(Long id);
}

@ -0,0 +1,20 @@
package com.ngskcloud.service.Impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ngskcloud.entity.AdminUser;
import com.ngskcloud.mapper.AdminUserMapper;
import com.ngskcloud.service.AdminUserService;
import org.springframework.stereotype.Service;
@Service
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements AdminUserService {
@Override
public AdminUser findByAccount(String account) {
return getOne(query().getWrapper().eq("account", account));
}
@Override
public AdminUser findById(Long id) {
return getOne((query().getWrapper().eq("id", id)));
}
}

@ -0,0 +1,22 @@
package com.ngskcloud.service.Impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ngskcloud.entity.User;
import com.ngskcloud.mapper.UserMapper;
import com.ngskcloud.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public User find(String account) {
return getOne(query().getWrapper().eq("account", account));
}
@Override
public User find(Long id) {
return getOne(query().getWrapper().eq("id", id));
}
}

@ -0,0 +1,12 @@
package com.ngskcloud.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ngskcloud.entity.User;
import org.springframework.stereotype.Service;
public interface UserService extends IService<User> {
User find(String account);
User find(Long id);
}

@ -0,0 +1,62 @@
package com.ngskcloud.utils;
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import com.alibaba.cloud.commons.lang.StringUtils;
import org.apache.commons.codec.Charsets;
import org.springframework.util.DigestUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class DigestUtil {
private static final char[] HEX_CODE = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
public static String encrypt(String data) {
return StringUtils.isBlank(data) ? "" : sha1Hex(md5Hex(data));
}
public static String md5Hex(final String data) {
return DigestUtils.md5DigestAsHex(data.getBytes(Charsets.UTF_8));
}
public static String sha1Hex(String data) {
return sha1Hex((data.getBytes(Charsets.UTF_8)));
}
public static String sha1Hex(final byte[] bytes) {
return digestHex("SHA-1", bytes);
}
public static String digestHex(String algorithm, byte[] bytes) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
return encodeHex(md.digest(bytes));
} catch (NoSuchAlgorithmException var3) {
throw new RuntimeException(var3.getMessage());
}
}
public static String encodeHex(byte[] bytes) {
StringBuilder r = new StringBuilder(bytes.length * 2);
byte[] var2 = bytes;
int var3 = bytes.length;
for(int var4 = 0; var4 < var3; ++var4) {
byte b = var2[var4];
r.append(HEX_CODE[b >> 4 & 15]);
r.append(HEX_CODE[b & 15]);
}
return r.toString();
}
public static String hex(String data) {
return StringUtils.isBlank(data) ? "" : sha1Hex(data);
}
}

@ -0,0 +1,222 @@
package com.ngskcloud.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* JWT
* JWT Token
*/
@Component
public class JwtUtil {
// JWT签名密钥从配置文件读取
@Value("${jwt.secret:your-secret-key-here-make-it-long-enough}")
private String secret;
// Token过期时间默认1小时
@Value("${jwt.expiration:3600000}")
private Long expiration;
// Token前缀
@Value("${jwt.tokenHead:Bearer }")
private String tokenHead;
/**
* JWT Token
*
* @param username
* @return JWT Token
*/
public String generateToken(String username) {
Map<String, Object> claims = buildClaims(username);
return generateToken(claims);
}
/**
* JWT Token
*
* @param claims
* @return JWT Token
*/
public String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setClaims(claims)
.setExpiration(generateExpirationDate())
.setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
/**
* Token
*
* @param token JWT Token
* @return Claims
*/
public Claims getClaimsFromToken(String token) {
try {
return Jwts.parser()
.verifyWith(getSigningKey()) // 使用 verifyWith 替代 setSigningKey
.build()
.parseSignedClaims(token) // 使用 parseSignedClaims 替代 parseClaimsJws
.getPayload(); // 使用 getPayload() 替代 getBody()
} catch (Exception e) {
throw new RuntimeException("JWT格式验证失败", e);
}
}
// 获取签名密钥的辅助方法
private SecretKey getSigningKey() {
// 确保您的密钥是 SecretKey 类型,而不是普通的 Key
return Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
}
/**
* Token
*
* @param token JWT Token
* @return
*/
public boolean validateToken(String token) {
try {
getClaimsFromToken(token);
return true;
} catch (Exception e) {
return false;
}
}
/**
* Token
*
* @param token JWT Token
* @return
*/
public boolean isTokenExpired(String token) {
Date expirationDate = getExpirationDateFromToken(token);
return expirationDate.before(new Date());
}
/**
* Token
*
* @param token JWT Token
* @return
*/
public Date getExpirationDateFromToken(String token) {
Claims claims = getClaimsFromToken(token);
return claims.getExpiration();
}
/**
* Token
*
* @param token JWT Token
* @return
*/
public String getUsernameFromToken(String token) {
Claims claims = getClaimsFromToken(token);
return claims.get("user_name", String.class);
}
/**
* Token
*
* @param token Token
* @return Token
*/
public String refreshToken(String token) {
Claims oldClaims = getClaimsFromToken(token);
// 创建新的 Claims 构建器,复制原有声明并更新时间
return Jwts.builder()
.claims(oldClaims) // 复制原有声明
.issuedAt(new Date()) // 设置新的签发时间
.expiration(generateExpirationDate()) // 设置新的过期时间
.signWith(getSigningKey()) // 签名
.compact();
}
/**
*
*
* @param username
* @return Map
*/
private Map<String, Object> buildClaims(String username) {
Map<String, Object> claims = new HashMap<>();
// 用户基本信息
claims.put("tenant_id", "000000");
claims.put("user_name", username);
claims.put("real_name", "管理员");
claims.put("avatar", "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamRoxxVxka.png");
claims.put("authorities", new String[]{"administrator"});
claims.put("client_id", "isdp2");
claims.put("role_name", "administrator");
claims.put("license", "powered by bladex");
claims.put("post_id", "1769936598361804802");
claims.put("user_id", "1123598821738675201");
claims.put("role_id", "1123598816738675201");
claims.put("scope", new String[]{"all"});
claims.put("nick_name", username);
claims.put("oauth_id", "");
claims.put("account", username);
claims.put("dept_id", "1769934936519839746");
claims.put("jti", "6575dce1-26ce-433a-bd2f-e792e9067ba4");
// 添加detail信息
Map<String, String> detail = new HashMap<>();
detail.put("type", "web");
claims.put("detail", detail);
return claims;
}
/**
*
*
* @return
*/
private Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + expiration);
}
// Getter和Setter方法
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public Long getExpiration() {
return expiration;
}
public void setExpiration(Long expiration) {
this.expiration = expiration;
}
public String getTokenHead() {
return tokenHead;
}
public void setTokenHead(String tokenHead) {
this.tokenHead = tokenHead;
}
}

@ -0,0 +1,106 @@
/*
*
*
* 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 com.ngskcloud.utils;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.Arrays;
import java.util.List;
public class RequestUtil {
public static HttpServletRequest handler() {
ServletRequestAttributes servletRequestAttributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return servletRequestAttributes == null ? null : servletRequestAttributes.getRequest();
}
public static UserAgent ua() {
HttpServletRequest request = RequestUtil.handler();
if (request == null) {
return null;
}
return UserAgentUtil.parse(request.getHeader("User-Agent"));
}
public static String token() {
HttpServletRequest request = RequestUtil.handler();
if (request == null) {
return "";
}
String token = request.getHeader("Authorization");
if (token == null || token.length() == 0 || token.split(" ").length != 2) {
return "";
}
return token.split(" ")[1];
}
public static String url() {
HttpServletRequest request = RequestUtil.handler();
return request == null ? "" : request.getRequestURL().toString();
}
public static String uri() {
Integer portNumber = port();
return RequestUtil.domain()
+ (Arrays.asList(443, 80, 0).contains(portNumber) ? "" : ":" + portNumber);
}
public static String uriWithProtocol() {
Integer portNumber = port();
return RequestUtil.protocol()
+ RequestUtil.domain()
+ (Arrays.asList(443, 80, 0).contains(portNumber) ? "" : ":" + portNumber);
}
public static String pathname() {
HttpServletRequest request = RequestUtil.handler();
return request == null ? "" : request.getRequestURI();
}
public static Integer port() {
HttpServletRequest request = RequestUtil.handler();
return request == null ? 0 : request.getServerPort();
}
public static String domain() {
HttpServletRequest request = RequestUtil.handler();
if (request != null) {
String requestUrl = request.getRequestURL().toString();
List<String> urls = Arrays.asList(requestUrl.split("/"));
return urls.get(2).split(":")[0];
}
return null;
}
public static String protocol() {
HttpServletRequest request = RequestUtil.handler();
if (request != null) {
String requestUrl = request.getRequestURL().toString();
List<String> urls = Arrays.asList(requestUrl.split("//"));
return urls.get(0) + "//";
}
return null;
}
}

@ -0,0 +1,112 @@
server:
# 端口
port: 8027
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: satoken
# token 有效期(单位:秒) 默认30天-1 代表永久有效
timeout: 1296000
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: -1
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token
is-share: false
jwt-secret-key: "playeduxyz"
token-prefix: "Bearer"
# token 风格默认可取值uuid、simple-uuid、random-32、random-64、random-128、tik
# token-style: jwt
is-log: true
sso-server:
is-slo: true
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 3000
# 应用列表:配置接入的应用信息
clients:
# 应用 sso-client2采用模式三对接
sso-client2:
client: playedu-client
allow-url: "*"
secret-key: SSO-C2-kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# MyBatis-Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
spring:
datasource:
# 移除type配置使用默认的HikariCP
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.5.119:3306/video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: ngskcloud0809
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 300000
connection-timeout: 20000
max-lifetime: 1200000
main:
allow-circular-references: true # 临时允许循环依赖
cache:
type: redis # 缓存配置,这里集成了redis和ehcache两种缓存方式基本是使用redis。
ehcache:
config: classpath:config/ehcache.xml
application:
name: bpms-sso # 服务名称
profiles:
active: dev #启动环境 dev开发环境 local本地环境(需要将EnableTurbine注释掉)
cloud:
nacos:
discovery:
server-addr: http://192.168.5.119:8848
namespace: ng
username: nacos
password: ngsk0809
config:
server-addr: http://192.168.5.119:8848
namespace: ng
file-extension: yml
username: nacos
password: ngsk0809
import-check:
enabled: false
data:
redis:
open: true
host: 192.168.5.119 # 需替换
port: 6379 # 需替换
database: 0 # 需替换
timeout: 6000
password: ngsk0809 # 需替换
lettuce:
cluster:
refresh:
adaptive: true
period: 20
shutdown-timeout: 6000ms
pool:
max-active: 20
max-idle: 10
max-wait: -1ms
min-idle: 5
template:
defaultSerializer:
org.springframework.data.redis.serializer.StringRedisSerializer
jwt:
secret: bladexisapowerfulmicroservicearchitectureupgradedandoptimizedfromacommercialproject
expiration: 3600000 # 1小时单位毫秒
tokenHead: "Bearer "

@ -0,0 +1,6 @@
<html>
<body>
<h1>hello word!!!</h1>
<p>this is a html page</p>
</body>
</html>

@ -0,0 +1,13 @@
package com.ngskcloud;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BpmsSsoApplicationTests {
@Test
void contextLoads() {
}
}
Loading…
Cancel
Save