修改网关调用问题

This commit is contained in:
panxuejie 2026-01-06 11:08:46 +08:00
parent fb8648a979
commit 9bf133fd6c
10 changed files with 79 additions and 87 deletions

View File

@ -100,6 +100,13 @@
<version>2023.0.1.0</version> <version>2023.0.1.0</version>
</dependency> </dependency>
<!-- Spring Cloud Bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>4.0.4</version>
</dependency>
<!-- SpringDoc --> <!-- SpringDoc -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>

View File

@ -24,15 +24,17 @@
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<!-- Spring Cloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Spring Cloud --> <!-- Spring Cloud -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- MyBatis Plus --> <!-- MyBatis Plus -->
<dependency> <dependency>
@ -41,10 +43,15 @@
</dependency> </dependency>
<!-- Database --> <!-- Database -->
<dependency> <!-- <dependency>
<groupId>com.oceanbase</groupId> <groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId> <artifactId>oceanbase-client</artifactId>
<version>2.4.0</version> <version>2.4.0</version>
</dependency> -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency> </dependency>
<!-- Swagger --> <!-- Swagger -->
@ -82,6 +89,12 @@
<artifactId>resilience4j-spring-boot3</artifactId> <artifactId>resilience4j-spring-boot3</artifactId>
</dependency> </dependency>
<!-- Spring Cloud Bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -2,20 +2,15 @@ package com.tacit.admin.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain; import jakarta.servlet.FilterChain;
@ -33,82 +28,35 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http http
// 禁用CSRF保护 .csrf(AbstractHttpConfigurer::disable)
.csrf(csrf -> csrf.disable()) .cors(AbstractHttpConfigurer::disable)
// 允许跨域请求
.cors(cors -> cors.disable())
// 设置会话管理为无状态
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 添加JWT认证过滤器
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
// 设置请求授权规则
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
// 允许访问的路径 .requestMatchers("/auth/**", "/test/**", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
.requestMatchers("/test/**", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
// 其他请求需要认证
.anyRequest().authenticated() .anyRequest().authenticated()
); )
.addFilterBefore(authenticationFilter(), org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.class);
return http.build(); return http.build();
} }
@Bean @Bean
public OncePerRequestFilter jwtAuthenticationFilter() { public OncePerRequestFilter authenticationFilter() {
return new OncePerRequestFilter() { return new OncePerRequestFilter() {
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 从请求头中获取用户信息由网关添加
String userId = request.getHeader("X-User-Id"); String userId = request.getHeader("X-User-Id");
String username = request.getHeader("X-Username"); String username = request.getHeader("X-Username");
String role = request.getHeader("X-Role"); String role = request.getHeader("X-Role");
// 如果有用户信息则创建Authentication对象并设置到SecurityContext
if (userId != null && username != null && role != null) { if (userId != null && username != null && role != null) {
// 创建用户对象 User principal = new User(username, "", Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + role.toUpperCase())));
org.springframework.security.core.userdetails.User user = new User( var authentication = new org.springframework.security.authentication.UsernamePasswordAuthenticationToken(principal, null, principal.getAuthorities());
username, SecurityContextHolder.getContext().setAuthentication(authentication);
"",
Collections.singletonList(() -> "ROLE_" + role.toUpperCase())
);
// 创建认证对象
org.springframework.security.authentication.UsernamePasswordAuthenticationToken authentication =
new org.springframework.security.authentication.UsernamePasswordAuthenticationToken(
user,
null,
user.getAuthorities()
);
// 设置认证信息到SecurityContext
org.springframework.security.core.context.SecurityContextHolder.getContext().setAuthentication(authentication);
} }
// 继续过滤链
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
} }
}; };
} }
@Bean
public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(passwordEncoder);
return new ProviderManager(Collections.singletonList(provider));
}
@Bean
public UserDetailsService userDetailsService() {
// 这里可以根据实际情况实现UserDetailsService从数据库中获取用户信息
return username -> {
// 由于我们使用网关进行认证这里可以返回一个空实现
// 实际项目中应该根据用户名从数据库中获取用户信息
throw new UsernameNotFoundException("User not found: " + username);
};
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
} }

View File

@ -1,8 +1,6 @@
package com.tacit.admin.controller; package com.tacit.admin.controller;
import com.tacit.admin.entity.User; import com.tacit.admin.entity.User;
import com.tacit.admin.entity.dto.LoginRequest;
import com.tacit.admin.entity.dto.LoginResponse;
import com.tacit.admin.service.UserService; import com.tacit.admin.service.UserService;
import com.tacit.common.entity.ResponseResult; import com.tacit.common.entity.ResponseResult;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -15,22 +13,14 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/user") @RequestMapping("/user")
@Tag(name = "用户管理", description = "用户相关接口") @Tag(name = "用户管理", description = "用户管理相关接口")
public class UserController { public class UserController {
@Autowired @Autowired
private UserService userService; private UserService userService;
@Operation(summary = "用户登录", description = "用户登录获取JWT令牌")
@PostMapping("/login")
public ResponseResult<LoginResponse> login(@RequestBody LoginRequest loginRequest) {
LoginResponse loginResponse = userService.login(loginRequest);
return ResponseResult.success(loginResponse);
}
@Operation(summary = "获取所有用户", description = "获取系统中所有用户列表") @Operation(summary = "获取所有用户", description = "获取系统中所有用户列表")
@GetMapping("/list") @GetMapping("/list")
@PreAuthorize("hasRole('ADMIN')")
public ResponseResult<List<User>> getAllUsers() { public ResponseResult<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers(); List<User> users = userService.getAllUsers();
return ResponseResult.success(users); return ResponseResult.success(users);
@ -38,7 +28,6 @@ public class UserController {
@Operation(summary = "根据ID获取用户", description = "根据用户ID获取用户详情") @Operation(summary = "根据ID获取用户", description = "根据用户ID获取用户详情")
@GetMapping("/info/{id}") @GetMapping("/info/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseResult<User> getUserById(@PathVariable Long id) { public ResponseResult<User> getUserById(@PathVariable Long id) {
User user = userService.getUserById(id); User user = userService.getUserById(id);
return ResponseResult.success(user); return ResponseResult.success(user);
@ -46,7 +35,6 @@ public class UserController {
@Operation(summary = "创建用户", description = "创建新用户") @Operation(summary = "创建用户", description = "创建新用户")
@PostMapping("/create") @PostMapping("/create")
@PreAuthorize("hasRole('ADMIN')")
public ResponseResult<Boolean> createUser(@RequestBody User user) { public ResponseResult<Boolean> createUser(@RequestBody User user) {
boolean result = userService.createUser(user); boolean result = userService.createUser(user);
return ResponseResult.success(result); return ResponseResult.success(result);
@ -54,7 +42,6 @@ public class UserController {
@Operation(summary = "更新用户", description = "更新用户信息") @Operation(summary = "更新用户", description = "更新用户信息")
@PutMapping("/update") @PutMapping("/update")
@PreAuthorize("hasRole('ADMIN')")
public ResponseResult<Boolean> updateUser(@RequestBody User user) { public ResponseResult<Boolean> updateUser(@RequestBody User user) {
boolean result = userService.updateUser(user); boolean result = userService.updateUser(user);
return ResponseResult.success(result); return ResponseResult.success(result);
@ -62,7 +49,6 @@ public class UserController {
@Operation(summary = "删除用户", description = "根据用户ID删除用户") @Operation(summary = "删除用户", description = "根据用户ID删除用户")
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseResult<Boolean> deleteUser(@PathVariable Long id) { public ResponseResult<Boolean> deleteUser(@PathVariable Long id) {
boolean result = userService.deleteUser(id); boolean result = userService.deleteUser(id);
return ResponseResult.success(result); return ResponseResult.success(result);

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.tacit.admin.entity.User; import com.tacit.admin.entity.User;
import com.tacit.admin.entity.dto.LoginRequest; import com.tacit.admin.entity.dto.LoginRequest;
import com.tacit.admin.entity.dto.LoginResponse; import com.tacit.admin.entity.dto.LoginResponse;
import com.tacit.admin.entity.dto.RegisterRequest;
import java.util.List; import java.util.List;
@ -55,4 +56,10 @@ public interface UserService extends IService<User> {
* @return 登录响应结果 * @return 登录响应结果
*/ */
LoginResponse login(LoginRequest loginRequest); LoginResponse login(LoginRequest loginRequest);
/**
* 用户注册
* @param registerRequest 注册请求参数
*/
void register(RegisterRequest registerRequest);
} }

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tacit.admin.entity.User; import com.tacit.admin.entity.User;
import com.tacit.admin.entity.dto.LoginRequest; import com.tacit.admin.entity.dto.LoginRequest;
import com.tacit.admin.entity.dto.LoginResponse; import com.tacit.admin.entity.dto.LoginResponse;
import com.tacit.admin.entity.dto.RegisterRequest;
import com.tacit.admin.mapper.UserMapper; import com.tacit.admin.mapper.UserMapper;
import com.tacit.admin.service.UserService; import com.tacit.admin.service.UserService;
import com.tacit.common.utils.JwtUtils; import com.tacit.common.utils.JwtUtils;
@ -95,4 +96,23 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
return loginResponse; return loginResponse;
} }
@Override
public void register(RegisterRequest registerRequest) {
User existUser = getUserByUsername(registerRequest.getUsername());
if (existUser != null) {
throw new RuntimeException("用户名已存在");
}
User user = new User();
user.setUsername(registerRequest.getUsername());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
user.setNickname(registerRequest.getNickname());
user.setEmail(registerRequest.getEmail());
user.setPhone(registerRequest.getPhone());
user.setRole("USER");
user.setDelFlag(0);
save(user);
}
} }

View File

@ -41,10 +41,15 @@
</dependency> </dependency>
<!-- Database --> <!-- Database -->
<dependency> <!-- <dependency>
<groupId>com.oceanbase</groupId> <groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId> <artifactId>oceanbase-client</artifactId>
<version>2.4.0</version> <version>2.4.0</version>
</dependency> -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency> </dependency>
<!-- Swagger --> <!-- Swagger -->

View File

@ -19,7 +19,6 @@ public class UserController {
@Operation(summary = "获取用户信息", description = "根据用户ID获取用户信息") @Operation(summary = "获取用户信息", description = "根据用户ID获取用户信息")
@GetMapping("/info/{userId}") @GetMapping("/info/{userId}")
@PreAuthorize("hasRole('USER')")
public ResponseResult<User> getUserInfo(@PathVariable Long userId) { public ResponseResult<User> getUserInfo(@PathVariable Long userId) {
User user = userService.getUserInfo(userId); User user = userService.getUserInfo(userId);
return ResponseResult.success(user); return ResponseResult.success(user);
@ -27,7 +26,6 @@ public class UserController {
@Operation(summary = "更新用户信息", description = "更新用户个人信息") @Operation(summary = "更新用户信息", description = "更新用户个人信息")
@PutMapping("/update") @PutMapping("/update")
@PreAuthorize("hasRole('USER')")
public ResponseResult<Boolean> updateUserInfo(@RequestBody User user) { public ResponseResult<Boolean> updateUserInfo(@RequestBody User user) {
boolean result = userService.updateUserInfo(user); boolean result = userService.updateUserInfo(user);
return ResponseResult.success(result); return ResponseResult.success(result);

View File

@ -63,6 +63,12 @@
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> </dependency>
<!-- Spring Cloud LoadBalancer - 用于 Gateway 的 lb:// 协议 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -27,6 +27,8 @@ public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory<JwtAut
private static final List<String> WHITE_LIST = List.of( private static final List<String> WHITE_LIST = List.of(
"/api/auth/login", "/api/auth/login",
"/api/auth/register", "/api/auth/register",
"/admin/auth/login",
"/admin/auth/register",
"/swagger-ui", "/swagger-ui",
"/v3/api-docs" "/v3/api-docs"
); );