我一直在努力将 SecurityConfig 文件映射到较新的 Spring 版本。 具体来说,问题(我认为)是由 UserDetailsService() 或与之相关的东西引起的。 我尝试通过将原始密码传递到登录页面来登录,同时将加密密码硬编码到数据库中(我刚刚粘贴了encode() 方法返回的字符串)。 在尝试这样做时,我收到以下消息:
Hibernate: select u1_0.id,u1_0.name,u1_0.password,u1_0.username from users u1_0 where u1_0.username=?
Hibernate: select a1_0.user_id,a1_0.id,a1_0.authority from authority a1_0 where a1_0.user_id=?
看起来 id 没有在某个地方正确传递,但我不知道如何看待它。我就是无法正常登录。
下面我将向您展示我来自哪里,我有什么 atm,以及其他一些文件,但是它们应该没问题,因为它们在 Spring Boot 3 中的编码方式没有太多变化无论如何,因为我不确定它们是否会有所帮助,所以它们在这里:
旧文件:
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(getPasswordEncoder());
// auth.inMemoryAuthentication()
// .passwordEncoder(getPasswordEncoder())
// .withUser("[email protected]")
// .password(getPasswordEncoder().encode("asdfasdf"))
// .roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().hasRole("USER").and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.permitAll();
}
}
新文件:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig
{
@Autowired
private UserDetailsService userDetailsService;
@Bean
public UserDetailsService userDetailsService()
{
return new UserDetailsServiceImpl();
}
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception
{
return
http.authorizeHttpRequests()
.requestMatchers("/").permitAll()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.permitAll()
.and()
.logout()
.logoutUrl("/logout").permitAll()
.and().build();
}
@Bean
public AuthenticationProvider authenticationProvider()
{
DaoAuthenticationProvider authenticationProvider=new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
}
用户详细信息服务Impl:
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
@Autowired
private UserRepository userRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
User user = userRepo.findByUsername(username);
if(user == null)
{
throw new UsernameNotFoundException("Invalid username and password");
}
return new CustomSecurityUser(user);
}
}
自定义安全用户:
public class CustomSecurityUser extends User implements UserDetails
{
private static final long serialVersionUID = 464958176L;
public CustomSecurityUser()
{}
public CustomSecurityUser(User user)
{
this.setAuthorities(user.getAuthorities());
this.setId(user.getId());
this.setName(user.getName());
this.setPassword(user.getPassword());
this.setUsername(user.getUsername());
}
@Override
public Set<Authority> getAuthorities()
{
return super.getAuthorities();
}
@Override
public String getPassword()
{
return super.getPassword();
}
@Override
public String getUsername()
{
return super.getUsername();
}
@Override
public boolean isAccountNonExpired()
{
return true;
}
@Override
public boolean isAccountNonLocked()
{
return true;
}
@Override
public boolean isCredentialsNonExpired()
{
return true;
}
@Override
public boolean isEnabled()
{
return true;
}
}
用户存储库:
public interface UserRepository extends JpaRepository<User, Long>
{
User findByUsername(String username);
}
权威机构:
package com.freshvotes.security;
import org.springframework.security.core.GrantedAuthority;
import com.freshvotes.domain.User;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
@Entity
public class Authority implements GrantedAuthority
{
private static final long serialVersionUID = -6420181486L;
private Long id;
private String authority;
private User user;
@Override
public String getAuthority()
{
return this.authority;
}
public void setAuthority(String authority)
{
this.authority = authority;
}
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId()
{
return this.id;
}
public void setId(Long id)
{
this.id = id;
}
@ManyToOne()
public User getUser()
{
return this.user;
}
public void setUser(User user)
{
this.user = user;
}
}
用户实体:
@Entity
@Table(name = "users")
public class User
{
private Long id;
private String username;
private String password;
private String name;
private Set<Authority> authorities = new HashSet<>();
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="user")
public Set<Authority> getAuthorities()
{
return this.authorities;
}
public void setAuthorities(Set<Authority> authorities)
{
this.authorities = authorities;
}
}
我希望能够从中做出一些东西。我删除了导入,因为否则我无法发布我的问题。
您的数据库中的数据似乎可能存在问题。我克隆了您的存储库并通过添加数据进行了测试,它似乎在我这边运行正常。
要进行故障排除,请尝试在登录页面上使用以下凭据:用户名 -
user
和密码 - password
。
此外,这是我插入数据库的数据的详细信息:
用户表:
INSERT INTO users(id, name, password, username) values (1, 'kc', '$2a$10$C6454pQIMqMNW76.M8NjYOzvniTgqdl8unnjnWNnMXmkGqE1M9CSC', 'user');
权限表:
INSERT INTO authority(id, authority, user_id) VALUES (1, 'ROLE_USER', 1);