Spring5中Md5PasswordEncoder()方法失效问题求助
Md5PasswordEncoder Failure in Spring 5 Hey there, let's figure out why your Md5PasswordEncoder isn't working in Spring 5 — I've dealt with this exact issue a few times, so here's the breakdown:
Why This Is Happening
Md5PasswordEncoderis deprecated in Spring 5
Spring Security moved away from direct use of single-algorithm encoders likeMd5PasswordEncoderin favor ofDelegatingPasswordEncoder, which supports multiple encoding algorithms and is more secure. If you're using the old encoder without explicitly configuring it, Spring might be falling back to the defaultDelegatingPasswordEncoder, which doesn't recognize raw MD5 hashes without a prefix.Missing password prefix (if using default encoder)
The defaultDelegatingPasswordEncoderexpects stored passwords to have a prefix like{md5}to identify which algorithm was used. If your database passwords don't have this prefix, Spring won't process them as MD5 hashes, leading to authentication failures.No explicit password encoder configured
Looking at your code snippet, you haven't added a.passwordEncoder()call to yourjdbcAuthentication()setup. Without this, Spring uses the default encoder, which doesn't play nice with raw MD5 hashes.
Fixes You Can Try
Option 1: Explicitly Use Md5PasswordEncoder (Temporary Fix)
Even though it's deprecated, you can still force Spring to use Md5PasswordEncoder by adding it to your configuration. Just make sure your database stores raw MD5 hashes (no prefix):
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private DataSource datasource; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { Md5PasswordEncoder passwordEncoder = new Md5PasswordEncoder(); auth.jdbcAuthentication() .dataSource(datasource) .usersByUsernameQuery("select username as principal, password as credentials, active from users where username = ?") .authoritiesByUsernameQuery("select username as principal, role as role from users_roles where username = ?") .passwordEncoder(passwordEncoder) // Add this line to specify the encoder .rolePrefix("ROLE_"); // Include this if your roles don't start with ROLE_ already } }
Option 2: Migrate to DelegatingPasswordEncoder (Recommended)
This is the long-term, secure solution. First, update your stored passwords to include the {md5} prefix. For example, if your current password hash is 5f4dcc3b5aa765d61d8327deb882cf99 (MD5 of "password"), store it as {md5}5f4dcc3b5aa765d61d8327deb882cf99.
Then update your configuration to use the default delegating encoder:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private DataSource datasource; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth.jdbcAuthentication() .dataSource(datasource) .usersByUsernameQuery("select username as principal, password as credentials, active from users where username = ?") .authoritiesByUsernameQuery("select username as principal, role as role from users_roles where username = ?") .passwordEncoder(passwordEncoder) .rolePrefix("ROLE_"); } }
Additional Checks
- Verify that your
userstable'sactivecolumn returns a boolean value (eithertrue/falseor1/0) — Spring uses this to determine if an account is enabled. - Double-check that your
users_rolesquery returns valid role names. If your roles don't start withROLE_, therolePrefix("ROLE_")line will add it automatically (required for Spring's role-based access control).
内容的提问来源于stack exchange,提问作者Badr MOUMOUD

