` 中。如果没有错误,它会显示默认的 "Error" 文本。
+
+## SpringSecurity
+
+### 密码转换器(Password Encoder)
+
+Spring Security 提供了多种密码转换器(Password Encoder),这些转换器用于对用户密码进行加密和验证。常见的密码转换器包括:
+
+1. **BCryptPasswordEncoder**:
+
+ - 使用 **BCrypt** 算法对密码进行加密。
+
+ - 是最常用的密码加密方案,具有强大的加密性,并且支持自动加盐(salt),防止暴力破解攻击。
+
+ - 示例:
+
+ ```java
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+ ```
+
+2. **NoOpPasswordEncoder**:
+
+ - 不对密码进行加密,直接返回明文密码。
+
+ - 主要用于开发和测试环境,**不推荐在生产环境中使用**。
+
+ - 示例:
+
+ ```java
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return NoOpPasswordEncoder.getInstance();
+ }
+ ```
+
+3. **Pbkdf2PasswordEncoder**:
+
+ - 使用 **PBKDF2** 算法进行密码加密。
+
+ - 提供较强的安全性,并且支持对密码进行哈希。
+
+ - 示例:
+
+ ```java
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new Pbkdf2PasswordEncoder();
+ }
+ ```
+
+4. **Argon2PasswordEncoder**:
+
+ - 使用 **Argon2** 算法对密码进行加密。
+
+ - Argon2 是目前被认为最强的密码哈希算法,支持内存密集型计算,从而防止硬件加速破解。
+
+ - 示例:
+
+ ```java
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new Argon2PasswordEncoder();
+ }
+ ```
+
+5. **SCryptPasswordEncoder**:
+
+ - 使用 **SCrypt** 算法进行密码加密。
+
+ - SCrypt 是另一种内存密集型的密码加密算法,与 Argon2 类似,旨在防止硬件加速破解。
+
+ - 示例:
+
+ ```java
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new SCryptPasswordEncoder();
+ }
+ ```
+
+6. **MessageDigestPasswordEncoder** (已废弃):
+
+ - 基于 **MessageDigest** 算法进行加密(如 SHA-1、SHA-256 等)。
+ - 由于缺乏盐和密钥加密机制,已被其他更强的加密方式所替代。
+
+> 选择密码转换器的建议:
+>
+> - 在现代应用中,推荐使用 **BCryptPasswordEncoder** 或 **Argon2PasswordEncoder**,这两种算法提供了强大的加密性。
+> - **Pbkdf2PasswordEncoder** 和 **SCryptPasswordEncoder** 也可以作为备选方案,尤其是当你希望加密算法能够承受更多资源密集型攻击时。
+> - **NoOpPasswordEncoder** 仅限于开发和测试环境。
+
+### 访问主页
+
+需要使用`http://localhost:8080/index`来访问主页,可以在配置中配置,访问根路径直接跳转
+
+```java
+@RequestMapping
+@Controller
+public class HomeController {
+
+ @Operation(summary = "主页内容")
+ @GetMapping("index")
+ public String index() {
+ return "index";
+ }
+
+ @Operation(summary = "订单内容")
+ @GetMapping("order")
+ public String order() {
+ return "order";
+ }
+
+ @Operation(summary = "login")
+ @GetMapping("login")
+ public String login() {
+ return "login";
+ }
+}
+```
+
+在配置中
+
+```java
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfiguration implements WebMvcConfigurer {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/")
+ // .setViewName("forward:/index") //两种方式写法
+ .setViewName("index");
+ registry.addViewController("/login");
+ }
+}
+```
+
+### 自定义登录
+
+```java
+package cn.bunny.springdemo.configuration;
+
+import cn.bunny.springdemo.dao.entity.AdminUser;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+
+import java.util.ArrayList;
+
+@Configuration
+public class SecurityConfiguration {
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new SCryptPasswordEncoder(4, 8, 1, 8, 32);
+ }
+
+ /**
+ * 使用内存方式
+ *
+ * @param encoder 密码加密器
+ * @return 基于内存的用户
+ */
+ @Bean
+ public UserDetailsService userDetailsService(PasswordEncoder encoder) {
+ ArrayList
userDetails = new ArrayList<>();
+ userDetails.add(new AdminUser("admin", encoder.encode("admin"), true));
+ userDetails.add(new AdminUser("bunny", encoder.encode("password"), true));
+
+ return new InMemoryUserDetailsManager(userDetails);
+ }
+
+ // /**
+ // * 使用数据库方式
+ // *
+ // * @param userService 获取用户数据(如数据库)
+ // * @return 基于数据库的用户
+ // */
+ // @Bean
+ // public UserDetailsService userDetailsService(UserService userService) {
+ // return username -> {
+ // AdminUser adminUser = userService.getOne(Wrappers.lambdaQuery().eq(AdminUser::getUsername, userService));
+ // if (adminUser != null) {
+ // return adminUser;
+ // }
+ // throw new UsernameNotFoundException("未找到 AdminUser");
+ // };
+ // }
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity security) throws Exception {
+ return security
+ .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
+ authorizationManagerRequestMatcherRegistry
+ .requestMatchers("/order").hasRole("USER")// 请求需要含有USER角色
+ .requestMatchers("/", "/index", "/login", "/images/**").permitAll()
+ )
+ /* 自定义登录页面 */
+ // .formLogin(AbstractAuthenticationFilterConfigurer::permitAll)// 默认的登录页会自动启用,无需额外配置
+ .formLogin(formLoginConfigurer -> formLoginConfigurer
+ .loginPage("/login")
+ // .loginProcessingUrl("/authenticate")
+ .usernameParameter("username")// 自定义用户名名称
+ .usernameParameter("password")// 自定义密码名称
+ .defaultSuccessUrl("/index")// 登录成功后默认跳转页面
+ // .defaultSuccessUrl("/index", true)// 登录成功后默认跳转页面,如果用户之前访问页面也需要强制跳转到 /index 可以传递第二个参数
+ )
+ .build();
+ }
+}
+```
\ No newline at end of file
diff --git a/mvc/pom.xml b/mvc/pom.xml
index 1358965..ebbf201 100644
--- a/mvc/pom.xml
+++ b/mvc/pom.xml
@@ -17,7 +17,7 @@
17
3.5.6
- 8.0.30
+ 8.0.33
5.1.0
@@ -43,7 +43,6 @@
runtime
true
-
org.projectlombok
diff --git a/spring-demo/logs/spring-demo/spring.log b/spring-demo/logs/spring-demo/spring.log
index f717428..9311799 100644
--- a/spring-demo/logs/spring-demo/spring.log
+++ b/spring-demo/logs/spring-demo/spring.log
@@ -30,3 +30,63 @@
11:13:44:041 INFO 12616 --- [spring-demo] [main] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
11:13:44:042 INFO 12616 --- [spring-demo] [main] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 1 ms
11:13:44:062 INFO 12616 --- [spring-demo] [main] c.b.s.controller.HomeControllerTest : Started HomeControllerTest in 0.888 seconds (process running for 1.466)
+12:56:08:799 INFO 10508 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 10508 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:56:08:802 INFO 10508 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:56:09:855 INFO 10508 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:56:09:868 INFO 10508 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:56:10:093 INFO 10508 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:56:10:240 INFO 10508 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.717 seconds (process running for 2.253)
+12:56:30:906 INFO 21060 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 21060 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:56:30:909 INFO 21060 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:56:31:936 INFO 21060 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:56:31:950 INFO 21060 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:56:32:175 INFO 21060 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:56:32:317 INFO 21060 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.675 seconds (process running for 2.201)
+12:56:49:178 INFO 19580 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 19580 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:56:49:181 INFO 19580 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:56:50:206 INFO 19580 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:56:50:220 INFO 19580 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:56:50:449 INFO 19580 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:56:50:598 INFO 19580 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.688 seconds (process running for 2.241)
+12:57:19:701 INFO 12696 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 12696 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:57:19:704 INFO 12696 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:57:20:735 INFO 12696 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:57:20:750 INFO 12696 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:57:20:979 INFO 12696 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:57:21:127 INFO 12696 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.708 seconds (process running for 2.258)
+12:57:45:076 INFO 9352 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 9352 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:57:45:079 INFO 9352 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:57:46:202 INFO 9352 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:57:46:219 INFO 9352 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:57:46:462 INFO 9352 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:57:46:630 INFO 9352 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.858 seconds (process running for 2.69)
+12:58:16:559 INFO 1652 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 1652 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:58:16:563 INFO 1652 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:58:17:571 INFO 1652 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:58:17:585 INFO 1652 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:58:17:813 INFO 1652 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:58:17:955 INFO 1652 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.689 seconds (process running for 2.236)
+12:58:31:856 INFO 4352 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 4352 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:58:31:860 INFO 4352 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:58:42:935 INFO 4352 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:58:42:951 INFO 4352 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:58:43:193 INFO 4352 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:58:43:364 INFO 4352 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 11.813 seconds (process running for 12.431)
+12:58:47:757 INFO 22540 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 22540 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:58:47:760 INFO 22540 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:58:53:578 INFO 22540 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:58:53:593 INFO 22540 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:58:53:835 INFO 22540 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:58:54:003 INFO 22540 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 6.548 seconds (process running for 7.169)
+12:59:00:364 INFO 21332 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 21332 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+12:59:00:367 INFO 21332 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+12:59:01:498 INFO 21332 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+12:59:01:514 INFO 21332 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+12:59:01:752 INFO 21332 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+12:59:01:920 INFO 21332 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.851 seconds (process running for 2.456)
+13:02:06:411 INFO 13172 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Starting SpringDemoApplicationTests using Java 17.0.9 with PID 13172 (started by 13199 in F:\学习\代码\Java\MultiThread\spring-demo)
+13:02:06:416 INFO 13172 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : The following 1 profile is active: "dev"
+13:02:07:458 INFO 13172 --- [spring-demo] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
+13:02:07:471 INFO 13172 --- [spring-demo] [main] o.s.v.b.OptionalValidatorFactoryBean : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
+13:02:07:695 INFO 13172 --- [spring-demo] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name userDetailsService
+13:02:07:837 INFO 13172 --- [spring-demo] [main] c.b.s.SpringDemoApplicationTests : Started SpringDemoApplicationTests in 1.696 seconds (process running for 2.265)
diff --git a/spring-demo/pom.xml b/spring-demo/pom.xml
index 302bfa8..accadbf 100644
--- a/spring-demo/pom.xml
+++ b/spring-demo/pom.xml
@@ -30,6 +30,9 @@
17
2.0.47
${junit.version}
+ 3.5.6
+ 8.0.33
+ 5.1.0
@@ -45,6 +48,17 @@
org.springframework.security
spring-security-test
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.70
+
+
+ org.bouncycastle
+ bcpg-jdk15on
+ 1.70
+
+
org.springframework.boot
@@ -92,7 +106,24 @@
hutool-all
5.8.27
-
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ ${mybatis-plus.version}
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+
+ com.zaxxer
+ HikariCP
+ ${HikariCP.version}
+
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/configuration/SecurityConfiguration.java b/spring-demo/src/main/java/cn/bunny/springdemo/configuration/SecurityConfiguration.java
new file mode 100644
index 0000000..c2aaa4a
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/configuration/SecurityConfiguration.java
@@ -0,0 +1,76 @@
+package cn.bunny.springdemo.configuration;
+
+import cn.bunny.springdemo.dao.entity.AdminUser;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+
+import java.util.ArrayList;
+
+@Configuration
+public class SecurityConfiguration {
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new SCryptPasswordEncoder(4, 8, 1, 8, 32);
+ }
+
+ /**
+ * 使用内存方式
+ *
+ * @param encoder 密码加密器
+ * @return 基于内存的用户
+ */
+ @Bean
+ public UserDetailsService userDetailsService(PasswordEncoder encoder) {
+ ArrayList userDetails = new ArrayList<>();
+ userDetails.add(new AdminUser("admin", encoder.encode("admin"), true));
+ userDetails.add(new AdminUser("bunny", encoder.encode("password"), true));
+
+ return new InMemoryUserDetailsManager(userDetails);
+ }
+
+ // /**
+ // * 使用数据库方式
+ // *
+ // * @param userService 获取用户数据(如数据库)
+ // * @return 基于数据库的用户
+ // */
+ // @Bean
+ // public UserDetailsService userDetailsService(UserService userService) {
+ // return username -> {
+ // AdminUser adminUser = userService.getOne(Wrappers.lambdaQuery().eq(AdminUser::getUsername, userService));
+ // if (adminUser != null) {
+ // return adminUser;
+ // }
+ // throw new UsernameNotFoundException("未找到 AdminUser");
+ // };
+ // }
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity security) throws Exception {
+ return security
+ .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
+ authorizationManagerRequestMatcherRegistry
+ .requestMatchers("/order").hasRole("USER")// 请求需要含有USER角色
+ .requestMatchers("/", "/index", "/login", "/images/**").permitAll()
+ )
+ /* 自定义登录页面 */
+ // .formLogin(AbstractAuthenticationFilterConfigurer::permitAll)// 默认的登录页会自动启用,无需额外配置
+ .formLogin(formLoginConfigurer -> formLoginConfigurer
+ .loginPage("/login")
+ // .loginProcessingUrl("/authenticate")
+ .usernameParameter("username")// 自定义用户名名称
+ .usernameParameter("password")// 自定义密码名称
+ .defaultSuccessUrl("/index")// 登录成功后默认跳转页面
+ // .defaultSuccessUrl("/index", true)// 登录成功后默认跳转页面,如果用户之前访问页面也需要强制跳转到 /index 可以传递第二个参数
+ )
+ .build();
+ }
+}
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/configuration/WebConfiguration.java b/spring-demo/src/main/java/cn/bunny/springdemo/configuration/WebConfiguration.java
new file mode 100644
index 0000000..70ffea1
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/configuration/WebConfiguration.java
@@ -0,0 +1,16 @@
+package cn.bunny.springdemo.configuration;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfiguration implements WebMvcConfigurer {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/")
+ // .setViewName("forward:/index") //两种方式写法
+ .setViewName("index");
+ }
+}
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/controller/HomeController.java b/spring-demo/src/main/java/cn/bunny/springdemo/controller/HomeController.java
index 97ca87d..08f103f 100644
--- a/spring-demo/src/main/java/cn/bunny/springdemo/controller/HomeController.java
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/controller/HomeController.java
@@ -14,4 +14,16 @@ public class HomeController {
public String index() {
return "index";
}
+
+ @Operation(summary = "订单内容")
+ @GetMapping("order")
+ public String order() {
+ return "order";
+ }
+
+ @Operation(summary = "login")
+ @GetMapping("login")
+ public String login() {
+ return "login";
+ }
}
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/dao/BaseEntity.java b/spring-demo/src/main/java/cn/bunny/springdemo/dao/BaseEntity.java
new file mode 100644
index 0000000..bf2a1e7
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/dao/BaseEntity.java
@@ -0,0 +1,48 @@
+package cn.bunny.springdemo.dao;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@Schema(name = "BaseEntity", title = "基础信息字段", description = "基础信息字段")
+public class BaseEntity implements Serializable {
+
+ @Schema(name = "id", title = "唯一标识")
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long id;
+
+ @Schema(name = "createTime", title = "创建时间")
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ @Schema(name = "updateTime", title = "更新时间")
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private LocalDateTime updateTime;
+
+ @Schema(name = "createUser", title = "创建用户")
+ @TableField(fill = FieldFill.INSERT)
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long createUser;
+
+ @Schema(name = "updateUser", title = "操作用户")
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long updateUser;
+
+ @Schema(name = "isDeleted", title = "是否被删除")
+ @TableLogic
+ private Boolean isDeleted;
+
+}
+
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/dao/BaseUserEntity.java b/spring-demo/src/main/java/cn/bunny/springdemo/dao/BaseUserEntity.java
new file mode 100644
index 0000000..3f38b2d
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/dao/BaseUserEntity.java
@@ -0,0 +1,18 @@
+package cn.bunny.springdemo.dao;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Schema(name = "BaseUserEntity", title = "基础信息字段包含用户信息", description = "基础信息字段包含用户信息")
+public class BaseUserEntity extends BaseEntity {
+
+ @Schema(name = "username", title = "用户名")
+ private String createUsername;
+
+ @Schema(name = "nickname", title = "昵称")
+ private String updateUsername;
+
+}
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/dao/dto/BillDto.java b/spring-demo/src/main/java/cn/bunny/springdemo/dao/dto/BillDto.java
new file mode 100644
index 0000000..a998486
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/dao/dto/BillDto.java
@@ -0,0 +1,44 @@
+package cn.bunny.springdemo.dao.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Schema(name = "BillDto对象", title = "账单信息查询内容", description = "账单信息查询内容")
+public class BillDto {
+
+ @Schema(name = "userId", title = "绑定的用户id")
+ private Long userId;
+
+ @Schema(name = "amount", title = "金额")
+ private BigDecimal amount;
+
+ @Schema(name = "categoryIds", title = "类别分类")
+ private List categoryIds;
+
+ @Schema(name = "username", title = "类型:1 - 收入,-1 - 支出")
+ private Byte type;
+
+ @Schema(name = "description", title = "描述")
+ private String description;
+
+ @Schema(name = "startDate", title = "开始交易日期")
+ @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
+ private LocalDate startDate;
+
+ @Schema(name = "endDate", title = "结束交易日期")
+ @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
+ private LocalDate endDate;
+
+}
\ No newline at end of file
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/dao/entity/AdminUser.java b/spring-demo/src/main/java/cn/bunny/springdemo/dao/entity/AdminUser.java
new file mode 100644
index 0000000..f45046d
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/dao/entity/AdminUser.java
@@ -0,0 +1,49 @@
+package cn.bunny.springdemo.dao.entity;
+
+import cn.bunny.springdemo.dao.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ *
+ * 管理员用户信息
+ *
+ *
+ * @author Bunny
+ * @since 2024-06-26
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("sys_user")
+@Schema(name = "AdminUser对象", title = "用户信息", description = "用户信息")
+public class AdminUser extends BaseEntity implements UserDetails {
+
+ @Schema(name = "username", title = "用户名")
+ private String username;
+
+ @Schema(name = "password", title = "密码")
+ private String password;
+
+ @Schema(name = "status", title = "状态", description = "1:禁用 0:正常")
+ private Boolean status;
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return List.of(new SimpleGrantedAuthority("ROLE_USER"));
+ }
+}
+
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/dao/entity/Bill.java b/spring-demo/src/main/java/cn/bunny/springdemo/dao/entity/Bill.java
new file mode 100644
index 0000000..4324ac6
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/dao/entity/Bill.java
@@ -0,0 +1,49 @@
+package cn.bunny.springdemo.dao.entity;
+
+import cn.bunny.springdemo.dao.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ *
+ * 账单信息
+ *
+ *
+ * @author Bunny
+ * @since 2024-11-07
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+@TableName("t_bill")
+@Schema(name = "Bill对象", title = "账单信息", description = "账单信息")
+public class Bill extends BaseEntity {
+
+ @Schema(name = "username", title = "类型:1 - 收入,-1 - 支出")
+ private Byte type;
+
+ @Schema(name = "userId", title = "绑定的用户id")
+ private Long userId;
+
+ @Schema(name = "amount", title = "金额")
+ private BigDecimal amount;
+
+ @Schema(name = "description", title = "描述")
+ private String description;
+
+ @Schema(name = "transactionDate", title = "交易日期")
+ private LocalDateTime transactionDate;
+
+ @Schema(name = "categoryId", title = "类别id")
+ private Long categoryId;
+
+}
+
+
+
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/mapper/UserMapper.java b/spring-demo/src/main/java/cn/bunny/springdemo/mapper/UserMapper.java
new file mode 100644
index 0000000..fbeb752
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/mapper/UserMapper.java
@@ -0,0 +1,19 @@
+package cn.bunny.springdemo.mapper;
+
+import cn.bunny.springdemo.dao.entity.AdminUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ *
+ * 用户信息 Mapper 接口
+ *
+ *
+ * @author Bunny
+ * @since 2024-09-26
+ */
+@Mapper
+public interface UserMapper extends BaseMapper {
+
+
+}
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/services/UserService.java b/spring-demo/src/main/java/cn/bunny/springdemo/services/UserService.java
new file mode 100644
index 0000000..22d29a8
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/services/UserService.java
@@ -0,0 +1,16 @@
+package cn.bunny.springdemo.services;
+
+import cn.bunny.springdemo.dao.entity.AdminUser;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 用户信息 服务类
+ *
+ *
+ * @author Bunny
+ * @since 2024-09-26
+ */
+public interface UserService extends IService {
+
+}
diff --git a/spring-demo/src/main/java/cn/bunny/springdemo/services/impl/UserServiceImpl.java b/spring-demo/src/main/java/cn/bunny/springdemo/services/impl/UserServiceImpl.java
new file mode 100644
index 0000000..a30090c
--- /dev/null
+++ b/spring-demo/src/main/java/cn/bunny/springdemo/services/impl/UserServiceImpl.java
@@ -0,0 +1,21 @@
+package cn.bunny.springdemo.services.impl;
+
+import cn.bunny.springdemo.dao.entity.AdminUser;
+import cn.bunny.springdemo.mapper.UserMapper;
+import cn.bunny.springdemo.services.UserService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+
+/**
+ * 用户信息 服务实现类
+ *
+ * @author Bunny
+ * @since 2024-09-26
+ */
+@Service
+@Transactional
+public class UserServiceImpl extends ServiceImpl implements UserService {
+
+}
diff --git a/spring-demo/src/main/resources/application.yml b/spring-demo/src/main/resources/application.yml
index c071ef9..51f6cb6 100644
--- a/spring-demo/src/main/resources/application.yml
+++ b/spring-demo/src/main/resources/application.yml
@@ -8,12 +8,12 @@ spring:
multipart:
max-file-size: 6MB
- # datasource:
- # type: com.zaxxer.hikari.HikariDataSource
- # driver-class-name: com.mysql.cj.jdbc.Driver
- # url: jdbc:mysql://${bunny.master.host}:${bunny.master.port}/${bunny.master.database}?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
- # username: ${bunny.master.username}
- # password: ${bunny.master.password}
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://${bunny.master.host}:${bunny.master.port}/${bunny.master.database}?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
+ username: ${bunny.master.username}
+ password: ${bunny.master.password}
jackson:
date-format: yyyy-MM-dd HH:mm:ss
diff --git a/spring-demo/src/main/resources/templates/login.html b/spring-demo/src/main/resources/templates/login.html
new file mode 100644
index 0000000..02d9cd9
--- /dev/null
+++ b/spring-demo/src/main/resources/templates/login.html
@@ -0,0 +1,255 @@
+
+
+
+
+ 边框流动效果的login页面 www.bootstrapmb.com
+
+
+
+
+
+
+
+
+
diff --git a/spring-demo/src/main/resources/templates/order.html b/spring-demo/src/main/resources/templates/order.html
new file mode 100644
index 0000000..0f8b193
--- /dev/null
+++ b/spring-demo/src/main/resources/templates/order.html
@@ -0,0 +1,10 @@
+
+
+
+
+ 订单内容
+
+
+ 订单内容
+
+
\ No newline at end of file
diff --git a/spring-demo/src/test/java/cn/bunny/springdemo/SpringDemoApplicationTests.java b/spring-demo/src/test/java/cn/bunny/springdemo/SpringDemoApplicationTests.java
index ffc51dd..ae1f6e4 100644
--- a/spring-demo/src/test/java/cn/bunny/springdemo/SpringDemoApplicationTests.java
+++ b/spring-demo/src/test/java/cn/bunny/springdemo/SpringDemoApplicationTests.java
@@ -1,13 +1,20 @@
package cn.bunny.springdemo;
import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootTest
class SpringDemoApplicationTests {
+ @Autowired
+ PasswordEncoder passwordEncoder;
+
@Test
void contextLoads() {
+ String s = passwordEncoder.encode("admin123");
+ System.out.println(s);
}
}