spring错误“名为'x'的bean应该是'y'类型,但实际上是[com.sun.proxy.$proxy]类型”

qvtsj1bj  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(135)

我尝试在使用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 类可以工作,但它可能会影响性能。)

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题