我尝试在使用Spring Security 的应用程序中实现基于dao的身份验证。
当我试图用一个用户登录到应用程序时,出现了以下错误:
failed to lazily initialize a collection of role: com.intellivest.app.dao.User.groups, could not initialize proxy - no Session
看着@jcmwright80对这个问题的回答,我明白我应该理想地进行注解 UserDetailsServiceImpl
分类为 @Transactional
. 完成此操作后,我在登录时出错:
Bean named 'userDetailsService' is expected to be of type 'com.intellivest.app.service.UserDetailsServiceImpl' but was actually of type 'com.sun.proxy.$Proxy238'"}}
这似乎是一个与在userdetailsserviceimpl上创建的代理对象相关的问题-我如何才能优雅地解决这个问题?
代码
安全配置的相关部分:
@Configuration
@ComponentScan("com.intellivest.app.service")
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
}
userdetailsserviceimpl.java
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.intellivest.app.dao.User;
import com.intellivest.app.dao.UserDao;
import com.intellivest.app.dao.UserDetailsImpl;
@Service("userDetailsService")
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService{
public UserDetailsServiceImpl () {};
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.getUser(username);
if (user == null) {
throw new UsernameNotFoundException ("User not found.");
}
return new UserDetailsImpl(user);
}
}
用户dao.java
@Repository
@Transactional
public class UserDao extends BaseDao {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public UserDao() {
System.out.println("successfully loaded users DAO");
}
public User getUser(String username) {
CriteriaBuilder cb = getSession().getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
Predicate predicate = cb.equal(root.get(User_.USERNAME), username);
cq.where(predicate);
TypedQuery<User> query = getSession().createQuery(cq);
return query.getSingleResult();
}
// Other methods ....
}
用户.java
@Entity
@Table(name="users",schema="sec")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="userGen")
@SequenceGenerator(name="userGen", sequenceName="user_id_seq", schema="sec")
private long id;
// Validation constraints on the fields ...
private String username;
private String password;
private boolean enabled;
@ManyToMany
@JoinTable(name="group_members", schema="sec", joinColumns= { @JoinColumn(name="user_id") }, inverseJoinColumns = { @JoinColumn(name="group_id") } )
private Set<Group> groups;
// Getters, Setters etc. ...
}
userdetailsimpl.java文件
public class UserDetailsImpl implements UserDetails {
private User user;
public UserDetailsImpl(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<Authority> authorities = user.getAuthorities();
return authorities.stream().map(authority -> new SimpleGrantedAuthority(authority.getAuthorityName())).collect(Collectors.toList());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return user.isEnabled();
}
}
(使用 @ManyToMany(fetch = FetchType.EAGER)
中的集合类型字段 User
以及 Group
类可以工作,但它可能会影响性能。)
暂无答案!
目前还没有任何答案,快来回答吧!