diff --git a/README/SpringMVC笔记.md b/README/SpringMVC笔记.md index 6de9bfb..5fbbe14 100644 --- a/README/SpringMVC笔记.md +++ b/README/SpringMVC笔记.md @@ -1521,4 +1521,226 @@ Thymeleaf 是一种现代化的 Java 模板引擎,广泛用于生成 HTML、XM
Error
``` -如果验证失败,错误消息将显示在 `
` 中。如果没有错误,它会显示默认的 "Error" 文本。 \ No newline at end of file +如果验证失败,错误消息将显示在 `
` 中。如果没有错误,它会显示默认的 "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 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); } }