From e9ac9d5f996e2439b9e6ff6729193bed5bf92d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=8E=89=E4=B8=9C?= <129883742+liyudong2018@users.noreply.github.com> Date: Wed, 24 Sep 2025 09:20:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 8 +- .../hshh/nation/config/SecurityConfig.java | 2 +- .../login/controller/LoginController.java | 258 ++++++++++++++--- .../nation/login/model/ExtendUserDetails.java | 3 +- .../com/hshh/nation/user/entity/User.java | 3 + .../hshh/nation/user/service/UserService.java | 1 + .../user/service/impl/UserServiceImpl.java | 11 + src/main/resources/application.yaml | 25 +- .../resources/templates/fragments/header.html | 2 +- src/main/resources/templates/login.html | 260 +++++++++--------- 10 files changed, 392 insertions(+), 181 deletions(-) diff --git a/pom.xml b/pom.xml index 1885adf..0efb75b 100644 --- a/pom.xml +++ b/pom.xml @@ -17,13 +17,17 @@ - 11 - 11 + 8 + 8 UTF-8 + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot-dependencies diff --git a/src/main/java/com/hshh/nation/config/SecurityConfig.java b/src/main/java/com/hshh/nation/config/SecurityConfig.java index b2633ec..07277c5 100644 --- a/src/main/java/com/hshh/nation/config/SecurityConfig.java +++ b/src/main/java/com/hshh/nation/config/SecurityConfig.java @@ -44,7 +44,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() - .antMatchers("/login", "/css/**", "/js/**", "/img/**", "/libs/**", "/captcha", "/toAuth", + .antMatchers("/login", "/css/**", "/js/**", "/img/**", "/libs/**", "/captcha", "/toAuth","/redirect", "/ws", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs", diff --git a/src/main/java/com/hshh/nation/login/controller/LoginController.java b/src/main/java/com/hshh/nation/login/controller/LoginController.java index 31752e5..da44c08 100644 --- a/src/main/java/com/hshh/nation/login/controller/LoginController.java +++ b/src/main/java/com/hshh/nation/login/controller/LoginController.java @@ -1,76 +1,246 @@ package com.hshh.nation.login.controller; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.hshh.nation.advice.GlobalExceptionHandler; import com.hshh.nation.common.BaseController; import com.hshh.nation.common.OperateResult; -import com.hshh.nation.advice.GlobalExceptionHandler; import com.hshh.nation.login.model.ExtendUserDetails; import com.hshh.nation.set.service.ConfigService; +import com.hshh.nation.user.entity.User; +import com.hshh.nation.user.service.UserService; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Map; +import java.util.Random; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.util.Map; +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.ResponseBody; +import org.springframework.web.reactive.function.client.WebClient; @Controller @Slf4j public class LoginController extends BaseController { - @Resource - private ConfigService configService;//全局配置service + @Resource + private ConfigService configService;//全局配置service + private final WebClient webClient = WebClient.create(); + @Autowired + private AuthenticationManager authenticationManager; - @Autowired - private AuthenticationManager authenticationManager; + @Value("${third.auth.client_id}") + private String clientId; + @Value("${third.auth.client_secret}") + private String clientSecret; - //导向到登录页面 - @RequestMapping("/login") - public String loginPage(Model model) { - Map setMap = configService.getMapAllSet(); - String systemTitle = setMap.get("system.title"); - model.addAttribute("systemTitle", systemTitle); - return "login"; + @Value("${third.auth.token-url}") + private String tokenUrl; + @Value("${third.auth.userinfo-url}") + private String getUserUrl; + @Resource + private UserService userService; + @Value("${third.auth.jump_url}") + private String jumpUrl; + @Value("${third.auth.redirect_url}") + private String redirectUrl; + @Value("${third.auth.logout_url}") + private String logoutUrl; + + //导向到登录页面 + @RequestMapping("/login") + public String loginPage(Model model) { + Random random = new Random(); + + Map setMap = configService.getMapAllSet(); + + String url = jumpUrl + "?response_type=code&client_id=" + clientId + "&redirect_uri=" + + Base64.getUrlEncoder().encodeToString(redirectUrl.getBytes(StandardCharsets.UTF_8)) + + "&active_type=user&state=" + random.nextDouble(); + log.info("jumpUrl::{}", url); + String systemTitle = setMap.get("system.title"); + model.addAttribute("systemTitle", systemTitle); + model.addAttribute("jumpUrl", url); + return "login"; + } + + @GetMapping("/redirect") + + public String redirect(String code, HttpServletRequest request) { + //获取token + String token = token(code); + LoginForm loginForm = getThirdUserAndSaveUserIfNotExit(token); + log.info("loginForm::{}", JSON.toJSONString(loginForm)); + if (loginForm != null) { + authLoginForm(loginForm, request); } + request.getSession().setAttribute("token", token); + return "redirect:/home"; + } - //登录 - @PostMapping("/toAuth") - @ResponseBody - public OperateResult login(@RequestBody LoginForm loginForm, HttpServletRequest request) { - try { - log.info("username={}", loginForm.getUsername()); - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginForm.getUsername(), loginForm.getPassword()); - authenticationManager.authenticate(token); - Authentication authentication = authenticationManager.authenticate(token); - SecurityContextHolder.getContext().setAuthentication(authentication); - request.getSession().setAttribute("user", authentication.getPrincipal()); - request.getSession(true).setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); - } catch (Exception e) { - log.error(e.getMessage()); - return OperateResult.error(null, e.getMessage(), GlobalExceptionHandler.SERVER_ERROR_CODE); + @GetMapping("/out") + public String logout(HttpServletRequest request) { + log.info("logout....."); + String token = request.getSession().getAttribute("token") == null ? "" + : request.getSession().getAttribute("token").toString(); + if (StringUtils.isNotBlank(token)) { + //回收token + String url = + logoutUrl + "?client_id=" + clientId + "&client_secret=" + clientSecret + "&access_token=" + + token; + String result = webClient.get() + .uri(url) + .retrieve() + .bodyToMono(String.class) + .block(); + log.info("result::{}", result); + if (result != null) { + JSONObject jsonObject = JSON.parseObject(result); + if (jsonObject.containsKey("code")) { + if (jsonObject.getInteger("code") == 200) { + + } } - return OperateResult.success(); + } } - @GetMapping("/home") - public String home(Model model) { - log.info("home"); - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - ExtendUserDetails user = (ExtendUserDetails) authentication.getPrincipal(); - model.addAttribute("currentUser", user); - return "fragments/layout"; + request.getSession().removeAttribute("token"); + request.getSession().invalidate(); + return "redirect:/login"; + } + + //登录 + @PostMapping("/toAuth") + @ResponseBody + public OperateResult login(@RequestBody LoginForm loginForm, HttpServletRequest request) { + try { + log.info("username={}", loginForm.getUsername()); + authLoginForm(loginForm, request); + } catch (Exception e) { + log.error(e.getMessage()); + return OperateResult.error(null, e.getMessage(), GlobalExceptionHandler.SERVER_ERROR_CODE); + } - @Data - private static class LoginForm{ - String username; - String password; + return OperateResult.success(); + } + + private void authLoginForm(LoginForm loginForm, HttpServletRequest request) { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( + loginForm.getUsername(), loginForm.getPassword()); + authenticationManager.authenticate(token); + Authentication authentication = authenticationManager.authenticate(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + request.getSession().setAttribute("user", authentication.getPrincipal()); + request.getSession(true) + .setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, + SecurityContextHolder.getContext()); + } + + @GetMapping("/home") + public String home(Model model) { + log.info("home"); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + ExtendUserDetails user = (ExtendUserDetails) authentication.getPrincipal(); + model.addAttribute("currentUser", user); + return "fragments/layout"; + } + + @Data + public static class LoginForm { + + String username; + String password; + } + + private String token(String code) { + try { + String url = tokenUrl + "?client_id=" + clientId + "&client_secret=" + clientSecret + + "&grant_type=authorization_code&code=" + code; + log.info("tokenUrl: {}", url); + String result = webClient.get() + .uri(url) + .retrieve() + .bodyToMono(String.class) + .block(); + log.info("token: {}", result); + JSONObject resultObject = JSON.parseObject(result); + if (resultObject != null && resultObject.containsKey("code")) { + if (resultObject.getInteger("code") == 200) { + return resultObject.getJSONObject("data").getString("access_token"); + } + return resultObject.getString("access_token"); + } + } catch (Exception e) { + log.error(e.getMessage(), e); } + + return null; + } + + public LoginForm getThirdUserAndSaveUserIfNotExit(String token) { + String userUrl = getUserUrl + "?access_token=" + token; + log.info("getUserUrl: {}", userUrl); + try { + String result = webClient.get() + .uri(userUrl) + .retrieve() + .bodyToMono(String.class) + .block(); + log.info("getUserUrl result: {}", result); + JSONObject resultObject = JSON.parseObject(result); + if (resultObject != null && resultObject.containsKey("code")) { + if (resultObject.getInteger("code") == 200) { + + User user = getUser(resultObject.getJSONObject("data")); + User userInDb = userService.getUserByUserId(user.getUserId()); + if (userInDb == null) { + //插入到数据库 + User newUser = new User(); + newUser.setUserId(user.getUserId()); + newUser.setUserName(user.getUserName()); + newUser.setPassword(new BCryptPasswordEncoder().encode(user.getPassword())); + newUser.setNickName(user.getNickName()); + newUser.setSuperFlag(1); + userService.save(newUser); + } + LoginForm loginForm = new LoginForm(); + loginForm.setUsername(user.getUserName()); + loginForm.setPassword(user.getPassword()); + return loginForm; + } + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + return null; + } + + private User getUser(JSONObject userObject) { + User user = new User(); + user.setUserId(userObject.getString("userId")); + user.setUserName(userObject.getString("userName")); + user.setNickName(userObject.getString("nickName")); + + user.setPassword(userObject.getString("password")); + + return user; + } } diff --git a/src/main/java/com/hshh/nation/login/model/ExtendUserDetails.java b/src/main/java/com/hshh/nation/login/model/ExtendUserDetails.java index dbdf6df..593151e 100644 --- a/src/main/java/com/hshh/nation/login/model/ExtendUserDetails.java +++ b/src/main/java/com/hshh/nation/login/model/ExtendUserDetails.java @@ -1,6 +1,7 @@ package com.hshh.nation.login.model; import com.hshh.nation.menu.entity.Menu; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import lombok.Data; @@ -37,7 +38,7 @@ public class ExtendUserDetails implements UserDetails { @Override public Collection getAuthorities() { - return List.of(); + return new ArrayList<>(); } @Override diff --git a/src/main/java/com/hshh/nation/user/entity/User.java b/src/main/java/com/hshh/nation/user/entity/User.java index 8264a88..99e3247 100644 --- a/src/main/java/com/hshh/nation/user/entity/User.java +++ b/src/main/java/com/hshh/nation/user/entity/User.java @@ -1,6 +1,7 @@ package com.hshh.nation.user.entity; 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 java.io.Serializable; @@ -43,4 +44,6 @@ public class User implements Serializable { * 超级管理员标志. */ private int superFlag; + private String userId; + } diff --git a/src/main/java/com/hshh/nation/user/service/UserService.java b/src/main/java/com/hshh/nation/user/service/UserService.java index f44506c..87679c1 100644 --- a/src/main/java/com/hshh/nation/user/service/UserService.java +++ b/src/main/java/com/hshh/nation/user/service/UserService.java @@ -19,4 +19,5 @@ public interface UserService extends IService { * @return 用户对象. */ User getUserByUsername(String username); + User getUserByUserId(String userId); } diff --git a/src/main/java/com/hshh/nation/user/service/impl/UserServiceImpl.java b/src/main/java/com/hshh/nation/user/service/impl/UserServiceImpl.java index 4b35905..e86967f 100644 --- a/src/main/java/com/hshh/nation/user/service/impl/UserServiceImpl.java +++ b/src/main/java/com/hshh/nation/user/service/impl/UserServiceImpl.java @@ -28,4 +28,15 @@ public class UserServiceImpl extends ServiceImpl implements Us } return null; } + + @Override + public User getUserByUserId(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id", userId); + List list = this.list(queryWrapper); + if (!list.isEmpty()) { + return list.get(0); + } + return null; + } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 4ebe0c7..8737d8d 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -17,14 +17,14 @@ spring: max-wait: -1ms datasource: # mysql -# url: jdbc:mysql://localhost:3306/nation_defence?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC -# username: root -# password: 123456 -# driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:dm://192.168.0.52:5236 - username: NATION_DEFENCE - password: Lidy1234 - driver-class-name: dm.jdbc.driver.DmDriver + url: jdbc:mysql://localhost:3306/nation_defence?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:dm://127.0.0.1:5236 +# username: SYSDBA +# password: SYSDBA001 +# driver-class-name: dm.jdbc.driver.DmDriver hikari: minimum-idle: 5 maximum-pool-size: 20 @@ -63,4 +63,13 @@ logging: level: com.baomidou.mybatisplus: warn org.apache.ibatis: warn +third: + auth: + client_id: 233 + client_secret: 123 + token-url: http://32.15.80.150:99/oauth2Server/oauth2/token + userinfo-url: http://32.15.80.150:99/oauth2Server/oauth2/userinfo + jump_url: http://32.15.80.150:99/oauth2Server/oauth2/authorizeV2 + redirect_url: http://32.15.191.88:8888/redirect + logout_url: ttp://32.15.80.150:99/oauth2Server/oauth2/logout diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html index 7822c67..dbdf85f 100644 --- a/src/main/resources/templates/fragments/header.html +++ b/src/main/resources/templates/fragments/header.html @@ -10,7 +10,7 @@ \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 803e87c..a513db7 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -2,160 +2,172 @@ - - - - 登录 - - - - - - +
-
- -
-
-

-
-
- - -
-
-
-
- -
-
-
- - - -
+
+
+
+

+
+
+ +
+
+
+
+ +
- -
+ +
+ + + + +
+
+
+
- + \ No newline at end of file