说明
我创建了一个包含三个表的数据库
users (user_id, name, password),
带有列的角色表
role_id, role and the third column Role_user with user_id,role_id.
运行程序时出错,
为了安全起见,我已经使用SHA2进行哈希存储了用户名和密码。
运行程序时,它如上所述抛出了错误。我应该如何解决此错误?
package com.techprimers.security.securitydbexample.model;
import javax.persistence.*;
import java.util.Set;
@Entity
@Table(name = "user")
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private int id;
@Column(name = "password")
private String password;
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
public Users() {
}
public Users(Users users) {
this.roles = users.getRoles();
this.name = users.getName();
this.id = users.getId();
this.password = users.getPassword();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
角色
package com.MonitoringDashboardNew.Model;
import javax.persistence.*;
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "role_id")
private int roleId;
@Column(name = "role")
private String role;
public Role() {
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
CustomUserDetails
package com.MonitoringDashboardNew.Model;
import org.springframework.security.core.GrantedAuthority;
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.stream.Collectors;
public class CustomUserDetails extends Users implements UserDetails {
public CustomUserDetails(final Users users) {
super(users);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles()
.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getRole()))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return super.getPassword();
}
@Override
public String getUsername() {
return super.getName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
存储库
package com.MonitoringDashboardNew.Repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.MonitoringDashboardNew.Model.Users;
@Repository
public interface UsersRepository extends JpaRepository<Users, Integer> {
Optional<Users> findByName(String username);
}
服务
package com.MonitoringDashboardNew.Services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.MonitoringDashboardNew.Model.CustomUserDetails;
import com.MonitoringDashboardNew.Model.Users;
import com.MonitoringDashboardNew.Repository.UsersRepository;
import java.util.Optional;
@Service
public abstract class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UsersRepository usersRepository;
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Optional<Users> optionalUsers = usersRepository.findByName(name);
// Optional<Users> optionalUsers = usersRepository.findById(id);
optionalUsers
.orElseThrow(() -> new UsernameNotFoundException("Username not found"));
return optionalUsers
.map(CustomUserDetails::new).get();
}
}
安全配置
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import com.MonitoringDashboardNew.Services.CustomUserDetailsService;
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@EnableJpaRepositories()
@Configuration
@Component
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(getPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("**/monitoring/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return true;
}
};
}
}
错误
说明:
com.example.demo.SecurityConfiguration中的字段userDetailsService需要一个类型为'com.MonitoringDashboardNew.Services.CustomUserDetailsService'的bean。
注入点具有以下注释:
@org.springframework.beans.factory.annotation.Autowired(required=true)
动作:
考虑在您的配置中定义类型为'com.MonitoringDashboardNew.Services.CustomUserDetailsService'的bean。
您的CustomUserDetailsService是抽象的,无法创建。
@Service
public abstract class CustomUserDetailsService implements UserDetailsService {
使其不抽象:
@Service
public class CustomUserDetailsService implements UserDetailsService {