From 44dee07956cffbd8336a6df34d57567adfedd9f2 Mon Sep 17 00:00:00 2001 From: Bunny <1319900154@qq.com> Date: Thu, 10 Jul 2025 17:14:32 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring-security/pom.xml | 2 +- .../spring/config/DefaultSecurityConfig.java | 12 +++---- .../java/com/spring/config/Knife4jConfig.java | 10 ++++++ .../spring/config/SecurityConfiguration.java | 30 ++++++++++++++-- .../handler/SecurityAccessDeniedHandler.java | 28 +++++++++++++++ .../SecurityAuthenticationEntryPoint.java | 29 +++++++++++++++ .../controller/security/LoginController.java | 35 +++++++++++++++++++ .../system/MessageReceivedController.java | 8 ++--- .../domain/dto/security/LoginRequest.java | 22 ++++++++++++ .../spring/service/security/LoginService.java | 4 +++ .../src/main/resources/templates/index.html | 2 +- 11 files changed, 167 insertions(+), 15 deletions(-) create mode 100644 spring-security/src/main/java/com/spring/config/handler/SecurityAccessDeniedHandler.java create mode 100644 spring-security/src/main/java/com/spring/config/handler/SecurityAuthenticationEntryPoint.java create mode 100644 spring-security/src/main/java/com/spring/controller/security/LoginController.java create mode 100644 spring-security/src/main/java/com/spring/domain/dto/security/LoginRequest.java create mode 100644 spring-security/src/main/java/com/spring/service/security/LoginService.java diff --git a/spring-security/pom.xml b/spring-security/pom.xml index ea23d4a..09fafb9 100644 --- a/spring-security/pom.xml +++ b/spring-security/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.3 + 3.3.13 com.mall diff --git a/spring-security/src/main/java/com/spring/config/DefaultSecurityConfig.java b/spring-security/src/main/java/com/spring/config/DefaultSecurityConfig.java index 4178ad4..60aaa02 100644 --- a/spring-security/src/main/java/com/spring/config/DefaultSecurityConfig.java +++ b/spring-security/src/main/java/com/spring/config/DefaultSecurityConfig.java @@ -12,7 +12,6 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @@ -26,10 +25,10 @@ public class DefaultSecurityConfig { */ @Bean @ConditionalOnMissingBean(UserDetailsService.class) - InMemoryUserDetailsManager inMemoryUserDetailsManager() { - String generatedPassword = PasswordEncoderFactories.createDelegatingPasswordEncoder() - .encode("123456"); - return new InMemoryUserDetailsManager(User.withUsername("user") + InMemoryUserDetailsManager inMemoryUserDetailsManager(PasswordEncoder passwordEncoder) { + + String generatedPassword = passwordEncoder.encode("123456"); + return new InMemoryUserDetailsManager(User.withUsername("bunny") .password(generatedPassword).roles("USER").build()); } @@ -46,7 +45,8 @@ public class DefaultSecurityConfig { @Bean public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { - DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userDetailsService); + DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); + authenticationProvider.setUserDetailsService(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(authenticationProvider); diff --git a/spring-security/src/main/java/com/spring/config/Knife4jConfig.java b/spring-security/src/main/java/com/spring/config/Knife4jConfig.java index 24e8e45..e41e07e 100644 --- a/spring-security/src/main/java/com/spring/config/Knife4jConfig.java +++ b/spring-security/src/main/java/com/spring/config/Knife4jConfig.java @@ -41,4 +41,14 @@ public class Knife4jConfig { public GroupedOpenApi all() { return GroupedOpenApi.builder().group("全部请求接口").pathsToMatch("/api/**").build(); } + + @Bean + public GroupedOpenApi system() { + return GroupedOpenApi.builder().group("系统请求接口").pathsToMatch("/api/system/**").build(); + } + + @Bean + public GroupedOpenApi security() { + return GroupedOpenApi.builder().group("security接口").pathsToMatch("/api/security/**").build(); + } } diff --git a/spring-security/src/main/java/com/spring/config/SecurityConfiguration.java b/spring-security/src/main/java/com/spring/config/SecurityConfiguration.java index 506c937..0fdfc3c 100644 --- a/spring-security/src/main/java/com/spring/config/SecurityConfiguration.java +++ b/spring-security/src/main/java/com/spring/config/SecurityConfiguration.java @@ -1,13 +1,19 @@ package com.spring.config; +import com.spring.config.handler.SecurityAccessDeniedHandler; +import com.spring.config.handler.SecurityAuthenticationEntryPoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.Customizer; 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.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import javax.sql.DataSource; + @EnableWebSecurity @Configuration public class SecurityConfiguration { @@ -15,11 +21,29 @@ public class SecurityConfiguration { SecurityFilterChain filterChain(HttpSecurity http) throws Exception { HttpSessionRequestCache requestCache = new HttpSessionRequestCache(); http - .httpBasic(Customizer.withDefaults()) .requestCache(cache -> cache.requestCache(requestCache)) + // 如果禁用登录页会有弹窗形式的登录 + .formLogin(AbstractHttpConfigurer::disable) + // 开启打开默认页会让登录 + // .formLogin(Customizer.withDefaults()) + .formLogin(AbstractHttpConfigurer::disable) + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/", "/*/*/login").permitAll() + .anyRequest().authenticated() + ) + .exceptionHandling(configurer -> { + // 访问拒绝处理器 + configurer.accessDeniedHandler(new SecurityAccessDeniedHandler()); + // 认证入口点 + configurer.authenticationEntryPoint(new SecurityAuthenticationEntryPoint()); + }) ; - return http.build(); } + @Bean + public UserDetailsService userDetailsService(DataSource dataSource) { + return new JdbcUserDetailsManager(dataSource); + } + } diff --git a/spring-security/src/main/java/com/spring/config/handler/SecurityAccessDeniedHandler.java b/spring-security/src/main/java/com/spring/config/handler/SecurityAccessDeniedHandler.java new file mode 100644 index 0000000..dfbf1a6 --- /dev/null +++ b/spring-security/src/main/java/com/spring/config/handler/SecurityAccessDeniedHandler.java @@ -0,0 +1,28 @@ +package com.spring.config.handler; + +import com.alibaba.fastjson2.JSON; +import com.spring.domain.vo.result.Result; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +import java.io.IOException; + +@Slf4j +public class SecurityAccessDeniedHandler implements AccessDeniedHandler { + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { + log.error("CustomerAccessDeniedHandler:{}", accessDeniedException.getLocalizedMessage()); + + Result result = Result.error(accessDeniedException.getMessage()); + + Object json = JSON.toJSON(result); + + // 返回响应 + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().println(json); + } +} diff --git a/spring-security/src/main/java/com/spring/config/handler/SecurityAuthenticationEntryPoint.java b/spring-security/src/main/java/com/spring/config/handler/SecurityAuthenticationEntryPoint.java new file mode 100644 index 0000000..c10becd --- /dev/null +++ b/spring-security/src/main/java/com/spring/config/handler/SecurityAuthenticationEntryPoint.java @@ -0,0 +1,29 @@ +package com.spring.config.handler; + +import com.alibaba.fastjson2.JSON; +import com.spring.domain.vo.result.Result; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; + +import java.io.IOException; + +@Slf4j +public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { + log.error("CustomerAccessDeniedHandler:{}", authException.getLocalizedMessage()); + + Result result = Result.error(authException.getMessage()); + + Object json = JSON.toJSON(result); + + // 返回响应 + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().println(json); + } +} diff --git a/spring-security/src/main/java/com/spring/controller/security/LoginController.java b/spring-security/src/main/java/com/spring/controller/security/LoginController.java new file mode 100644 index 0000000..8bbd819 --- /dev/null +++ b/spring-security/src/main/java/com/spring/controller/security/LoginController.java @@ -0,0 +1,35 @@ +package com.spring.controller.security; + +import com.spring.domain.dto.security.LoginRequest; +import com.spring.domain.vo.result.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +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.RestController; + +@Tag(name = "Login接口", description = "登录接口") +@RestController +@RequestMapping("/api/security") +@RequiredArgsConstructor +public class LoginController { + + private final AuthenticationManager authenticationManager; + + @Operation(summary = "登录接口", description = "系统登录接口") + @PostMapping("login") + public Result login(@RequestBody LoginRequest loginRequest) { + String username = loginRequest.getUsername(); + String password = loginRequest.getPassword(); + + Authentication authenticationRequest = UsernamePasswordAuthenticationToken.unauthenticated(username, password); + + Authentication authenticationResponse = authenticationManager.authenticate(authenticationRequest); + return Result.success(authenticationResponse); + } +} \ No newline at end of file diff --git a/spring-security/src/main/java/com/spring/controller/system/MessageReceivedController.java b/spring-security/src/main/java/com/spring/controller/system/MessageReceivedController.java index d9d1f31..644f3ca 100644 --- a/spring-security/src/main/java/com/spring/controller/system/MessageReceivedController.java +++ b/spring-security/src/main/java/com/spring/controller/system/MessageReceivedController.java @@ -33,7 +33,7 @@ public class MessageReceivedController { private final MessageReceivedService messageReceivedService; - @Operation(summary = "分页查询", description = "分页") + @Operation(summary = "消息接受分页查询", description = "消息接受分页") @GetMapping("{page}/{limit}") public Result> getMessageReceivedPage( @Parameter(name = "page", description = "当前页", required = true) @@ -46,21 +46,21 @@ public class MessageReceivedController { return Result.success(pageResult); } - @Operation(summary = "添加", description = "添加") + @Operation(summary = "添加", description = "添加消息接受") @PostMapping() public Result addMessageReceived(@Valid @RequestBody MessageReceivedDto dto) { messageReceivedService.addMessageReceived(dto); return Result.success(ResultCodeEnum.ADD_SUCCESS); } - @Operation(summary = "更新", description = "更新") + @Operation(summary = "更新", description = "更新消息接受") @PutMapping() public Result updateMessageReceived(@Valid @RequestBody MessageReceivedDto dto) { messageReceivedService.updateMessageReceived(dto); return Result.success(ResultCodeEnum.UPDATE_SUCCESS); } - @Operation(summary = "删除", description = "删除") + @Operation(summary = "删除", description = "删除消息接受") @DeleteMapping() public Result deleteMessageReceived(@RequestBody List ids) { messageReceivedService.deleteMessageReceived(ids); diff --git a/spring-security/src/main/java/com/spring/domain/dto/security/LoginRequest.java b/spring-security/src/main/java/com/spring/domain/dto/security/LoginRequest.java new file mode 100644 index 0000000..b40b7e0 --- /dev/null +++ b/spring-security/src/main/java/com/spring/domain/dto/security/LoginRequest.java @@ -0,0 +1,22 @@ +package com.spring.domain.dto.security; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Schema(name = "LoginRequest", title = "LoginRequest登录参数", description = "登录请求参数") +public class LoginRequest { + + @Schema(name = "username", title = "用户名") + private String username; + + @Schema(name = "password", description = "密码") + private String password; + +} diff --git a/spring-security/src/main/java/com/spring/service/security/LoginService.java b/spring-security/src/main/java/com/spring/service/security/LoginService.java new file mode 100644 index 0000000..e01b9dc --- /dev/null +++ b/spring-security/src/main/java/com/spring/service/security/LoginService.java @@ -0,0 +1,4 @@ +package com.spring.service.security; + +public interface LoginService { +} diff --git a/spring-security/src/main/resources/templates/index.html b/spring-security/src/main/resources/templates/index.html index 0919378..7edf047 100644 --- a/spring-security/src/main/resources/templates/index.html +++ b/spring-security/src/main/resources/templates/index.html @@ -395,7 +395,7 @@

学习最强大的Java安全框架,保护您的应用程序免受现代安全威胁。Spring Security 6提供了全面的身份验证和授权功能,让您的应用安全无忧。