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 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 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; } } }