diff --git a/pom.xml b/pom.xml index 47277a5..e8c7d92 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,13 @@ 2023.0.1.0 + + + org.springframework.cloud + spring-cloud-starter-bootstrap + 4.0.4 + + org.springdoc diff --git a/tacit-admin/pom.xml b/tacit-admin/pom.xml index 85708e7..7e1fd82 100644 --- a/tacit-admin/pom.xml +++ b/tacit-admin/pom.xml @@ -24,15 +24,17 @@ spring-boot-starter-security + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + org.springframework.cloud spring-cloud-starter-openfeign - - org.springframework.cloud - spring-cloud-starter-loadbalancer - @@ -41,10 +43,15 @@ - + + + com.mysql + mysql-connector-j + runtime @@ -82,6 +89,12 @@ resilience4j-spring-boot3 + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + diff --git a/tacit-admin/src/main/java/com/tacit/admin/config/SecurityConfig.java b/tacit-admin/src/main/java/com/tacit/admin/config/SecurityConfig.java index 1e37e59..a3ccec6 100644 --- a/tacit-admin/src/main/java/com/tacit/admin/config/SecurityConfig.java +++ b/tacit-admin/src/main/java/com/tacit/admin/config/SecurityConfig.java @@ -2,20 +2,15 @@ package com.tacit.admin.config; import org.springframework.context.annotation.Bean; 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.web.builders.HttpSecurity; 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.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; 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.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.filter.OncePerRequestFilter; import jakarta.servlet.FilterChain; @@ -33,82 +28,35 @@ public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http - // 禁用CSRF保护 - .csrf(csrf -> csrf.disable()) - // 允许跨域请求 - .cors(cors -> cors.disable()) - // 设置会话管理为无状态 + .csrf(AbstractHttpConfigurer::disable) + .cors(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - // 添加JWT认证过滤器 - .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) - // 设置请求授权规则 .authorizeHttpRequests(auth -> auth - // 允许访问的路径 - .requestMatchers("/test/**", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll() - // 其他请求需要认证 + .requestMatchers("/auth/**", "/test/**", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll() .anyRequest().authenticated() - ); + ) + .addFilterBefore(authenticationFilter(), org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.class); return http.build(); } @Bean - public OncePerRequestFilter jwtAuthenticationFilter() { + public OncePerRequestFilter authenticationFilter() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - // 从请求头中获取用户信息(由网关添加) String userId = request.getHeader("X-User-Id"); String username = request.getHeader("X-Username"); String role = request.getHeader("X-Role"); - // 如果有用户信息,则创建Authentication对象并设置到SecurityContext if (userId != null && username != null && role != null) { - // 创建用户对象 - org.springframework.security.core.userdetails.User user = new User( - username, - "", - 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); + User principal = new User(username, "", Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + role.toUpperCase()))); + var authentication = new org.springframework.security.authentication.UsernamePasswordAuthenticationToken(principal, null, principal.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); } - // 继续过滤链 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(); - } } diff --git a/tacit-admin/src/main/java/com/tacit/admin/controller/UserController.java b/tacit-admin/src/main/java/com/tacit/admin/controller/UserController.java index 9752e5b..c6ff8c1 100644 --- a/tacit-admin/src/main/java/com/tacit/admin/controller/UserController.java +++ b/tacit-admin/src/main/java/com/tacit/admin/controller/UserController.java @@ -1,8 +1,6 @@ package com.tacit.admin.controller; 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.common.entity.ResponseResult; import io.swagger.v3.oas.annotations.Operation; @@ -15,22 +13,14 @@ import java.util.List; @RestController @RequestMapping("/user") -@Tag(name = "用户管理", description = "用户相关接口") +@Tag(name = "用户管理", description = "用户管理相关接口") public class UserController { @Autowired private UserService userService; - @Operation(summary = "用户登录", description = "用户登录获取JWT令牌") - @PostMapping("/login") - public ResponseResult login(@RequestBody LoginRequest loginRequest) { - LoginResponse loginResponse = userService.login(loginRequest); - return ResponseResult.success(loginResponse); - } - @Operation(summary = "获取所有用户", description = "获取系统中所有用户列表") @GetMapping("/list") - @PreAuthorize("hasRole('ADMIN')") public ResponseResult> getAllUsers() { List users = userService.getAllUsers(); return ResponseResult.success(users); @@ -38,7 +28,6 @@ public class UserController { @Operation(summary = "根据ID获取用户", description = "根据用户ID获取用户详情") @GetMapping("/info/{id}") - @PreAuthorize("hasRole('ADMIN')") public ResponseResult getUserById(@PathVariable Long id) { User user = userService.getUserById(id); return ResponseResult.success(user); @@ -46,7 +35,6 @@ public class UserController { @Operation(summary = "创建用户", description = "创建新用户") @PostMapping("/create") - @PreAuthorize("hasRole('ADMIN')") public ResponseResult createUser(@RequestBody User user) { boolean result = userService.createUser(user); return ResponseResult.success(result); @@ -54,7 +42,6 @@ public class UserController { @Operation(summary = "更新用户", description = "更新用户信息") @PutMapping("/update") - @PreAuthorize("hasRole('ADMIN')") public ResponseResult updateUser(@RequestBody User user) { boolean result = userService.updateUser(user); return ResponseResult.success(result); @@ -62,7 +49,6 @@ public class UserController { @Operation(summary = "删除用户", description = "根据用户ID删除用户") @DeleteMapping("/delete/{id}") - @PreAuthorize("hasRole('ADMIN')") public ResponseResult deleteUser(@PathVariable Long id) { boolean result = userService.deleteUser(id); return ResponseResult.success(result); diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/UserService.java b/tacit-admin/src/main/java/com/tacit/admin/service/UserService.java index 81c1667..8583a6e 100644 --- a/tacit-admin/src/main/java/com/tacit/admin/service/UserService.java +++ b/tacit-admin/src/main/java/com/tacit/admin/service/UserService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.tacit.admin.entity.User; import com.tacit.admin.entity.dto.LoginRequest; import com.tacit.admin.entity.dto.LoginResponse; +import com.tacit.admin.entity.dto.RegisterRequest; import java.util.List; @@ -55,4 +56,10 @@ public interface UserService extends IService { * @return 登录响应结果 */ LoginResponse login(LoginRequest loginRequest); + + /** + * 用户注册 + * @param registerRequest 注册请求参数 + */ + void register(RegisterRequest registerRequest); } diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/impl/UserServiceImpl.java b/tacit-admin/src/main/java/com/tacit/admin/service/impl/UserServiceImpl.java index efa24f4..bce336b 100644 --- a/tacit-admin/src/main/java/com/tacit/admin/service/impl/UserServiceImpl.java +++ b/tacit-admin/src/main/java/com/tacit/admin/service/impl/UserServiceImpl.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.tacit.admin.entity.User; import com.tacit.admin.entity.dto.LoginRequest; import com.tacit.admin.entity.dto.LoginResponse; +import com.tacit.admin.entity.dto.RegisterRequest; import com.tacit.admin.mapper.UserMapper; import com.tacit.admin.service.UserService; import com.tacit.common.utils.JwtUtils; @@ -95,4 +96,23 @@ public class UserServiceImpl extends ServiceImpl implements Us 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); + } } diff --git a/tacit-app-api/pom.xml b/tacit-app-api/pom.xml index 6610ca3..9b985c0 100644 --- a/tacit-app-api/pom.xml +++ b/tacit-app-api/pom.xml @@ -41,10 +41,15 @@ - + + + com.mysql + mysql-connector-j + runtime diff --git a/tacit-app-api/src/main/java/com/tacit/app/controller/UserController.java b/tacit-app-api/src/main/java/com/tacit/app/controller/UserController.java index ece8936..532564b 100644 --- a/tacit-app-api/src/main/java/com/tacit/app/controller/UserController.java +++ b/tacit-app-api/src/main/java/com/tacit/app/controller/UserController.java @@ -19,7 +19,6 @@ public class UserController { @Operation(summary = "获取用户信息", description = "根据用户ID获取用户信息") @GetMapping("/info/{userId}") - @PreAuthorize("hasRole('USER')") public ResponseResult getUserInfo(@PathVariable Long userId) { User user = userService.getUserInfo(userId); return ResponseResult.success(user); @@ -27,7 +26,6 @@ public class UserController { @Operation(summary = "更新用户信息", description = "更新用户个人信息") @PutMapping("/update") - @PreAuthorize("hasRole('USER')") public ResponseResult updateUserInfo(@RequestBody User user) { boolean result = userService.updateUserInfo(user); return ResponseResult.success(result); diff --git a/tacit-gateway/pom.xml b/tacit-gateway/pom.xml index 11a7631..0903283 100644 --- a/tacit-gateway/pom.xml +++ b/tacit-gateway/pom.xml @@ -63,6 +63,12 @@ spring-cloud-starter-alibaba-nacos-discovery + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + diff --git a/tacit-gateway/src/main/java/com/tacit/gateway/filter/JwtAuthenticationFilter.java b/tacit-gateway/src/main/java/com/tacit/gateway/filter/JwtAuthenticationFilter.java index 0edcd92..2e17445 100644 --- a/tacit-gateway/src/main/java/com/tacit/gateway/filter/JwtAuthenticationFilter.java +++ b/tacit-gateway/src/main/java/com/tacit/gateway/filter/JwtAuthenticationFilter.java @@ -27,6 +27,8 @@ public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory WHITE_LIST = List.of( "/api/auth/login", "/api/auth/register", + "/admin/auth/login", + "/admin/auth/register", "/swagger-ui", "/v3/api-docs" );