From 6dfaecddf87f3669a3f0108d2a77313dd18d6190 Mon Sep 17 00:00:00 2001 From: zhaoyixiang Date: Wed, 24 Apr 2024 00:00:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../entity/user/AccessTokenResponse.java | 17 +++++ .../configuration/entity/user/User.java | 2 + .../configuration/entity/user/UserFull.java | 67 ++++++++++++++++ .../server/user/login/LoginController.java | 44 +++++++++-- .../server/user/login/LoginService.java | 76 ++++++++++++++++++- 6 files changed, 197 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/realtime/protection/configuration/entity/user/AccessTokenResponse.java create mode 100644 src/main/java/com/realtime/protection/configuration/entity/user/UserFull.java diff --git a/build.gradle b/build.gradle index 4eb220c..63ab739 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,7 @@ dependencies { implementation 'com.alibaba:easyexcel:3.3.3' implementation 'com.baomidou:dynamic-datasource-spring-boot3-starter:4.3.0' implementation 'com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:4.4.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' } tasks.named('test') { diff --git a/src/main/java/com/realtime/protection/configuration/entity/user/AccessTokenResponse.java b/src/main/java/com/realtime/protection/configuration/entity/user/AccessTokenResponse.java new file mode 100644 index 0000000..f360ab6 --- /dev/null +++ b/src/main/java/com/realtime/protection/configuration/entity/user/AccessTokenResponse.java @@ -0,0 +1,17 @@ +package com.realtime.protection.configuration.entity.user; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author Yixiang Zhao + **/ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AccessTokenResponse { + private String access_token; + private String token_type; + private int expires_in; +} diff --git a/src/main/java/com/realtime/protection/configuration/entity/user/User.java b/src/main/java/com/realtime/protection/configuration/entity/user/User.java index 687f14f..73cb4f9 100644 --- a/src/main/java/com/realtime/protection/configuration/entity/user/User.java +++ b/src/main/java/com/realtime/protection/configuration/entity/user/User.java @@ -2,9 +2,11 @@ package com.realtime.protection.configuration.entity.user; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Data @AllArgsConstructor +@NoArgsConstructor public class User { private Long userId; diff --git a/src/main/java/com/realtime/protection/configuration/entity/user/UserFull.java b/src/main/java/com/realtime/protection/configuration/entity/user/UserFull.java new file mode 100644 index 0000000..dc5fd4b --- /dev/null +++ b/src/main/java/com/realtime/protection/configuration/entity/user/UserFull.java @@ -0,0 +1,67 @@ +package com.realtime.protection.configuration.entity.user; + +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * @author Yixiang Zhao + **/ +public class UserFull { + public String ticket; + public List groups; + public List roles; + public List orgs; + public String mobile; + public String nickName; + public String email; + public String uid; + public String employeeNumber; + public String name; + public List resoures; + + public String getOrgCode() { + if (orgs.size() > 0) { + return orgs.get(0).orgCode; + } + return ""; + } + + public String getRoleKey() { + if (roles.size() > 0) { + return roles.get(0).roleKey; + } + return ""; + } +} + +class Group { + public int groupId; + public int applicationId; + public String groupKey; + public String groupName; + public String groupTag; // Assume it's a JSON String, otherwise it could be List or similar + public String groupRemark; +} + +class Role { + public int roleId; + public int applicationId; + public String roleKey; + public String roleName; + public String roleRemark; + public String roleTag; // Same assumption as above + public List res; // Assuming a Resource class exists + public List resources; // Assuming a Resource class exists +} + +class Org { + public String orgName; + public String orgDescription; + public int orgParentId; + public String orgCode; + public String orgTag; // Same assumption as above + public int orgId; + public String userOrgworkType; +} diff --git a/src/main/java/com/realtime/protection/server/user/login/LoginController.java b/src/main/java/com/realtime/protection/server/user/login/LoginController.java index b69f1b8..e3e161d 100644 --- a/src/main/java/com/realtime/protection/server/user/login/LoginController.java +++ b/src/main/java/com/realtime/protection/server/user/login/LoginController.java @@ -1,11 +1,22 @@ package com.realtime.protection.server.user.login; -import com.realtime.protection.configuration.entity.user.User; -import com.realtime.protection.configuration.response.ResponseResult; -import org.springframework.web.bind.annotation.*; - import javax.security.auth.login.LoginException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.realtime.protection.configuration.entity.user.User; +import com.realtime.protection.configuration.entity.user.UserFull; +import com.realtime.protection.configuration.response.ResponseResult; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + // Just for example, not in production environment @RestController @RequestMapping("/user") @@ -36,10 +47,29 @@ public class LoginController { @PostMapping("/auth") public ResponseResult auth(@RequestParam("sessionData") String sessionData, - @RequestParam("accessToken") String accessToken, + @Autowired HttpServletRequest request, @RequestParam(value = "scopes", required = false) String scopes) { - return ResponseResult.ok().setMessage("success") - .setData("success", true); + try { + UserFull userFull = loginService.loginWithSSO(sessionData); + if (userFull == null) { + throw new LoginException("登录失败,无法获取用户信息"); + } + // 设置 session + HttpSession session = request.getSession(); + session.setAttribute("user", userFull); + // 返回结果 + return ResponseResult.ok().setMessage("success") + .setData("userId", userFull.uid) + .setData("userName", userFull.name) + .setData("userRole", userFull.getRoleKey()); + } catch (Exception e) { + return ResponseResult.error(e.getMessage()); + } } + @GetMapping("/auth_redirect") + public String authRedirect(@RequestParam(value = "SESSION_DATA", required = false) String sessionData) { + System.out.println("SESSION_DATA: " + sessionData); + return ""; + } } diff --git a/src/main/java/com/realtime/protection/server/user/login/LoginService.java b/src/main/java/com/realtime/protection/server/user/login/LoginService.java index e36afb4..0567b53 100644 --- a/src/main/java/com/realtime/protection/server/user/login/LoginService.java +++ b/src/main/java/com/realtime/protection/server/user/login/LoginService.java @@ -1,11 +1,26 @@ package com.realtime.protection.server.user.login; -import cn.dev33.satoken.stp.StpUtil; -import com.realtime.protection.configuration.entity.user.User; -import org.springframework.stereotype.Service; +import org.apache.logging.log4j.util.Strings; import javax.security.auth.login.LoginException; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.realtime.protection.configuration.entity.user.AccessTokenResponse; +import com.realtime.protection.configuration.entity.user.User; +import com.realtime.protection.configuration.entity.user.UserFull; + +import cn.dev33.satoken.stp.StpUtil; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import io.micrometer.common.util.StringUtils; + @Service // just for example, not for production environment public class LoginService { @@ -28,4 +43,59 @@ public class LoginService { StpUtil.login(userId); return userId; } + + public UserFull loginWithSSO(String sessionData) throws LoginException { + String accessToken = ""; + // 获取 ACCESS_TOKEN + ObjectMapper objectMapper = new ObjectMapper(); + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url("http://114.243.134.122:9217/passport/accessToken?grant_type=client_credentials") + .header("Authorization", "Basic TlNBRERAWlguT1JHOk14a1hHZ1ltOUNROUE3TCRSOCNLRW02R1pSeEhwd1c2") + .post(okhttp3.internal.Util.EMPTY_REQUEST) + .build(); + try { + Response response = client.newCall(request).execute(); + String rsp = response.body().string(); + try { + AccessTokenResponse atr = objectMapper.readValue(rsp, AccessTokenResponse.class); + accessToken = atr.getAccess_token(); + } catch (Exception e) { + throw new LoginException("解析 ACCESS_TOKEN 失败"); + } + } catch (Exception e) { + e.printStackTrace(); + throw new LoginException("获取 ACCESS_TOKEN 失败,网络请求错误"); + } + if (Strings.isBlank(accessToken)) { + throw new LoginException("获取 ACCESS_TOKEN 失败"); + } + // 校验 SESSION_DATA + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("sessionData", sessionData).build(); + request = new Request.Builder() + .url("http://114.243.134.122:9217/passport/accessApplication") + .header("Authorization", "Bearer " + accessToken) + .header("Content-Type", "application/x-www-form-urlencoded") + .post(body) + .build(); + try { + Response response = client.newCall(request).execute(); + String rsp = response.body().string(); + // System.out.println("user: " + rsp); + if (StringUtils.isBlank(rsp)) { + throw new LoginException("解析用户数据为空"); + } + try { + UserFull userFull = objectMapper.readValue(rsp, UserFull.class); + return userFull; + } catch (Exception e) { + e.printStackTrace(); + throw new LoginException("解析 ACCESS_TOKEN 失败"); + } + } catch (Exception e) { + e.printStackTrace(); + throw new LoginException("校验 SESSION_DATA 失败"); + } + } }