You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
12 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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("当前学员已锁定无法登录");
}
Boolean isAdmin = false;
if(user.getAdminUser() != null ){
isAdmin = true;
}
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("isAdmin", isAdmin)
.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("登出错误");
}
}
// 注销
@GetMapping("/sso/switchIdentity")
public SaResult switchIdentity(@RequestParam("userId") Long userId,@RequestParam("identity") Integer identity) {
try {
// 根据identity判断登录类型
if (identity == null ){
return SaResult.error("identity字段不能为空");
}else if (1==identity) {
return getUserToken(userId);
} else if (2==identity) {
return getAdminToken(userId,identity);
} else {
return SaResult.error("identity字段仅能为1-用户或者2-admin");
}
}catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
private SaResult getAdminToken(Long userId,Integer identity) {
AdminUser adminUser = adminUserService.findById(userId);
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)));
return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
}
private SaResult getUserToken(Long userId) {
User user = userService.find(userId);
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("isAdmin", Boolean.TRUE)
.setExtra(
"exp",
String.valueOf(
System.currentTimeMillis() / 1000
+ expired)));
return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
}
// 验证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() {
StpUtil.getTokenValue();
// System.out.println( StpUtil.getTokenValue());
// if (token != null && !token.trim().isEmpty()) {
// StpUtil.setTokenValue(token);
// }
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("isLogin",StpUtil.isLogin());
if (StpUtil.isLogin()){
resultMap.put("userId",StpUtil.getLoginIdAsLong());
}
return SaResult.ok("验证成功!").setData(resultMap);
}
/**
* 验证用户身份类型是否匹配
*/
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;
}
}
}