Spring-Security的Password Encoding

本文介绍了Spring Security的PasswordEncoder接口,用于密码的安全编码,避免明文存储。文章讲解了其核心方法encode和matches的用途,并探讨了不同实现,如BCryptPasswordEncoder、Pbkdf2PasswordEncoder和DelegatingPasswordEncoder。DelegatingPasswordEncoder的引入是为了处理不同版本间的兼容性问题。最后,指出了PasswordEncoder在 DaoAuthenticationProvider 中的角色,用于验证用户密码的正确性。

 

详细文档参考官方说明https://docs.spring.io/spring-security/site/docs/5.0.9.RELEASE/reference/htmlsingle/#core-services-password-encoding

    PasswordEncoder是spring-security的一个接口,主要用于对密码进行编码或加密,它有什么用途呢?说白了就是俩字“安全”,它的作用就是为了让密码不要以明文形式保存在数据库或其他文件中,我们先看一下这个接口的源码,如下:

public interface PasswordEncoder {

	/**
	 * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or
	 * greater hash combined with an 8-byte or greater randomly generated salt.
	 */
	String encode(CharSequence rawPassword);

	/**
	 * Verify the encoded password obtained from storage matches the submitted raw
	 * password after it too is encoded. Returns true if the passwords match, false if
	 * they do not. The stored password itself is never decoded.
	 *
	 * @param rawPassword the raw password to encode and match
	 * @param encodedPassword the encoded password from storage to compare with
	 * @return true if the raw password, after encoding, matches the encoded password from
	 * storage
	 */
	boolean matches(CharSequence rawPassword, String encodedPassword);

}

       很简单,只有两个方法:encode和matches,顾名思义,encode是对明文密码进行编码,生成一段不明所以的字符串,encode方法主要用于保存密码至数据库或其他文件前将密码进行编码。matches方法用于将原始密码与编码过的密码进行匹配,matches方法主要用于验证密码的正确性。

       默认情况下,spring-security自带了常用的PasswordEncoder实现,比如默认的BCryptPasswordEncoder, Pbkdf2PasswordEncoder,SCryptPasswordEncoder,NoOpPasswordEncoder等。

    那么,我们在spring-security中是如何使用PasswordEncoder的呢?

  // 实例化一个PasswordEncoder的bean
  @Bean
  public PasswordEncoder passwordEncoder() {
    DelegatingPasswordEncoder passwordEncoder = (DelegatingPasswordEncoder) PasswordEncoderFactories
        .createDelegatingPasswordEncoder();
    passwordEncoder.setDefaultPasswordEncoderForMatches(new BCryptPasswordEncoder());
    return passwordEncoder;
    //还有一种更简单的方法
    // return new BCryptPasswordEncoder();
  }

  @Bean
  public AuthenticationProvider daoAuthenticationProvider(Us
E:\XXHJ\JAVA\JDK\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-Dmanagement.endpoints.jmx.exposure.include=*" "-javaagent:D:\XXRJ\IntelliJ IDEA 2024.3.7\lib\idea_rt.jar=63104" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath D:\XXWJ\jcglxt\textbook\target\classes;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-data-jdbc\4.0.1\spring-boot-starter-data-jdbc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter\4.0.1\spring-boot-starter-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-logging\4.0.1\spring-boot-starter-logging-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\ch\qos\logback\logback-classic\1.5.22\logback-classic-1.5.22.jar;C:\Users\BHTSQ\.m2\repository\ch\qos\logback\logback-core\1.5.22\logback-core-1.5.22.jar;C:\Users\BHTSQ\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.25.3\log4j-to-slf4j-2.25.3.jar;C:\Users\BHTSQ\.m2\repository\org\apache\logging\log4j\log4j-api\2.25.3\log4j-api-2.25.3.jar;C:\Users\BHTSQ\.m2\repository\org\slf4j\jul-to-slf4j\2.0.17\jul-to-slf4j-2.0.17.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\4.0.1\spring-boot-autoconfigure-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\jakarta\annotation\jakarta.annotation-api\3.0.0\jakarta.annotation-api-3.0.0.jar;C:\Users\BHTSQ\.m2\repository\org\yaml\snakeyaml\2.5\snakeyaml-2.5.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-jdbc\4.0.1\spring-boot-starter-jdbc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\com\zaxxer\HikariCP\7.0.2\HikariCP-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\slf4j\slf4j-api\2.0.17\slf4j-api-2.0.17.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-data-jdbc\4.0.1\spring-boot-data-jdbc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-data-commons\4.0.1\spring-boot-data-commons-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-persistence\4.0.1\spring-boot-persistence-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\data\spring-data-commons\4.0.1\spring-data-commons-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\data\spring-data-jdbc\4.0.1\spring-data-jdbc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\data\spring-data-relational\4.0.1\spring-data-relational-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-context\7.0.2\spring-context-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-jdbc\4.0.1\spring-boot-jdbc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot\4.0.1\spring-boot-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-sql\4.0.1\spring-boot-sql-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-transaction\4.0.1\spring-boot-transaction-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-jdbc\7.0.2\spring-jdbc-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-security\4.0.1\spring-boot-starter-security-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-security\4.0.1\spring-boot-security-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\security\spring-security-config\7.0.2\spring-security-config-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\security\spring-security-core\7.0.2\spring-security-core-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\security\spring-security-crypto\7.0.2\spring-security-crypto-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\security\spring-security-web\7.0.2\spring-security-web-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-expression\7.0.2\spring-expression-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-aop\7.0.2\spring-aop-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-beans\7.0.2\spring-beans-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-core\7.0.2\spring-core-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\commons-logging\commons-logging\1.3.5\commons-logging-1.3.5.jar;C:\Users\BHTSQ\.m2\repository\org\jspecify\jspecify\1.0.0\jspecify-1.0.0.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-webmvc\4.0.1\spring-boot-starter-webmvc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-jackson\4.0.1\spring-boot-starter-jackson-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-jackson\4.0.1\spring-boot-jackson-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\tools\jackson\core\jackson-databind\3.0.3\jackson-databind-3.0.3.jar;C:\Users\BHTSQ\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.20\jackson-annotations-2.20.jar;C:\Users\BHTSQ\.m2\repository\tools\jackson\core\jackson-core\3.0.3\jackson-core-3.0.3.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\4.0.1\spring-boot-starter-tomcat-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat-runtime\4.0.1\spring-boot-starter-tomcat-runtime-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\11.0.15\tomcat-embed-core-11.0.15.jar;C:\Users\BHTSQ\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\11.0.15\tomcat-embed-el-11.0.15.jar;C:\Users\BHTSQ\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\11.0.15\tomcat-embed-websocket-11.0.15.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-tomcat\4.0.1\spring-boot-tomcat-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-http-converter\4.0.1\spring-boot-http-converter-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-web\7.0.2\spring-web-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\io\micrometer\micrometer-observation\1.16.1\micrometer-observation-1.16.1.jar;C:\Users\BHTSQ\.m2\repository\io\micrometer\micrometer-commons\1.16.1\micrometer-commons-1.16.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-webmvc\4.0.1\spring-boot-webmvc-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-servlet\4.0.1\spring-boot-servlet-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-webmvc\7.0.2\spring-webmvc-7.0.2.jar;C:\Users\BHTSQ\.m2\repository\org\mybatis\spring\boot\mybatis-spring-boot-starter\4.0.0\mybatis-spring-boot-starter-4.0.0.jar;C:\Users\BHTSQ\.m2\repository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\4.0.0\mybatis-spring-boot-autoconfigure-4.0.0.jar;C:\Users\BHTSQ\.m2\repository\org\mybatis\mybatis\3.5.19\mybatis-3.5.19.jar;C:\Users\BHTSQ\.m2\repository\org\mybatis\mybatis-spring\4.0.0\mybatis-spring-4.0.0.jar;C:\Users\BHTSQ\.m2\repository\com\microsoft\sqlserver\mssql-jdbc\13.2.1.jre11\mssql-jdbc-13.2.1.jre11.jar;C:\Users\BHTSQ\.m2\repository\org\projectlombok\lombok\1.18.42\lombok-1.18.42.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\boot\spring-boot-web-server\4.0.1\spring-boot-web-server-4.0.1.jar;C:\Users\BHTSQ\.m2\repository\org\springframework\spring-tx\7.0.2\spring-tx-7.0.2.jar com.example.textbook.TextbookApplication . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v4.0.1) 2025-12-24T14:50:16.854+08:00 INFO 31260 --- [ main] c.example.textbook.TextbookApplication : Starting TextbookApplication using Java 21.0.8 with PID 31260 (D:\XXWJ\jcglxt\textbook\target\classes started by BHTSQ in D:\XXWJ\jcglxt\textbook) 2025-12-24T14:50:16.858+08:00 INFO 31260 --- [ main] c.example.textbook.TextbookApplication : No active profile set, falling back to 1 default profile: "default" 2025-12-24T14:50:17.383+08:00 INFO 31260 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode. 2025-12-24T14:50:17.402+08:00 INFO 31260 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 13 ms. Found 0 JDBC repository interfaces. 2025-12-24T14:50:17.759+08:00 INFO 31260 --- [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) 2025-12-24T14:50:17.771+08:00 INFO 31260 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2025-12-24T14:50:17.771+08:00 INFO 31260 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.15] 2025-12-24T14:50:17.829+08:00 INFO 31260 --- [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 926 ms 2025-12-24T14:50:18.429+08:00 INFO 31260 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2025-12-24T14:50:18.669+08:00 INFO 31260 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection ConnectionID:1 ClientConnectionId: 8eb90616-1936-4f1f-a148-9ceaf72b5dce 2025-12-24T14:50:18.671+08:00 INFO 31260 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2025-12-24T14:50:18.785+08:00 WARN 31260 --- [ main] .s.a.UserDetailsServiceAutoConfiguration : Using generated security password: 11aa82c8-25d3-472e-a585-b87a0c57463a This generated password is for development use only. Your security configuration must be updated before running your application in production. 2025-12-24T14:50:18.824+08:00 INFO 31260 --- [ main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager 2025-12-24T14:50:19.000+08:00 INFO 31260 --- [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' 2025-12-24T14:50:19.004+08:00 INFO 31260 --- [ main] c.example.textbook.TextbookApplication : Started TextbookApplication in 2.593 seconds (process running for 3.2)
最新发布
12-25
```markdown ### 普通文本型回答 您提供的日志非常关键,我们来逐行分析: --- ## ✅ 当前状态:后端已成功启动 | 项目 | 状态 | |------|------| | Spring Boot | ✅ 已启动 | | 端口 | `8080` | | 数据库连接 | ✅ 成功(`HikariPool-1 - Start completed`) | | 应用名称 | `TextbookApplication` | > 🎉 **后端服务本身没有问题,能够正常运行。** --- ## ⚠️ 但存在一个致命问题: ### 🔥 日志中这行暴露了根源: ``` Using generated security password: 11aa82c8-25d3-472e-a585-b87a0c57463a ``` 👉 这说明:**Spring Security 被自动启用了!** 它会: - 拦截所有请求 - 强制跳转到 `/login` - 使用默认登录页 - 忽略您自定义的 `/api/login` 接口 这就是您“登录不了”的根本原因! --- ## ✅ 解决方案:立即关闭 Spring Security ### 第一步:在 `application.yml` 中添加禁用配置 > 文件路径:`D:\XXWJ\jcglxt\textbook\src\main\resources\application.yml` ```yaml spring: security: enabled: false # 👈 关键!必须加在最前面 ``` 完整示例如下: ```yaml spring: security: enabled: false # <<<--- 必须加这一行 server: port: 8080 spring: datasource: url: jdbc:sqlserver://localhost:1433;databaseName=TextbooksDB;encrypt=false username: sa password: your_password_here driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver jackson: default-property-inclusion: non_null mybatis: type-aliases-package: com.example.textbook.entity configuration: mapUnderscoreToCamelCase: true mapper-locations: classpath:mybatis-mapper/*.xml ``` 📌 注意:`spring.security.enabled=false` 必须写在 `spring:` 下,且优先级最高。 --- ### 第二步:确认 `pom.xml` 没有引入 Security 打开: ``` D:\XXWJ\jcglxt\textbook\pom.xml ``` 搜索并**删除**以下依赖(如果您没主动添加,就删掉): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` > 💡 提示:从您的日志看,确实引入了 Security(因为生成了密码),必须排除。 --- ### 第三步:重启后端项目 ```bash cd D:\XXWJ\jcglxt\textbook mvn clean compile spring-boot:run ``` ✅ 重启后,如果日志中 **不再出现 `Using generated security password`**,说明关闭成功! --- ## ✅ 验证是否修复 ### 方法一:直接测试接口 访问: ``` http://localhost:8080/api/users ``` ✅ 正常应返回 JSON 用户列表 ❌ 如果跳转到 `/login` → 说明 Security 仍在生效 → 回头检查 `application.yml` --- ### 方法二:使用 Postman 测试登录 ```http POST http://localhost:8080/api/login Content-Type: application/json { "userId": 1000100, "password": "123456" } ``` ✅ 正常返回 200 和用户信息 ✅ 前端就能正常登录了 --- ## ✅ 补充建议:前端请求头一致性 确保前端发送的是标准 JSON 请求: ```js // src/utils/request.js import axios from 'axios' export default axios.create({ baseURL: '/api', headers: { 'Content-Type': 'application/json' } }) ``` --- ### 知识点 - **Security 自动装配**:只要存在 `spring-boot-starter-security` 就会自动启用。 - **关闭开关**:`spring.security.enabled=false` 是最高优先级配置。 - **日志线索**:“Using generated security password” 是判断是否启用的黄金标志。 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值