无法使用Spring Social将UserDetailsS​​ervice配置到WebSecurityConfigurerAdapter中

时间:2015-10-20 01:38:16

标签: java spring spring-security spring-social

@Configuration
public class WebSecurityConfig  extends WebSecurityConfigurerAdapter {

private final Log log = LogFactory.getLog(WebSecurityConfig.class);

@Value("${spring.profiles.active}")
private String env;

@Value("${rememberMe.privateKey}")
private String rememberMeKey;

@Resource
private UserDetailsService userService;

@Bean
public RememberMeServices rememberMeServices() {

    TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices(rememberMeKey, userService);

    // See http://stackoverflow.com/questions/25565809/implementing-a-remember-me-for-spring-social
    rememberMeServices.setAlwaysRemember(true);

    return rememberMeServices;

}

@Bean
public PasswordEncoder passwordEncoder() {
  log.info("Creating password encoder bean");
  return new BCryptPasswordEncoder();
}


@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .authorizeRequests()
            .antMatchers("/",
                    "/signup",
                    "/public/**",
                    "/users/*",
                    "/auth/**").permitAll()
            .anyRequest().authenticated();

    http
        .formLogin()
            .loginPage("/signin")
            .permitAll().and()
        .rememberMe().key(rememberMeKey).rememberMeServices(rememberMeServices()).and()
        .logout()
            .deleteCookies("JSESSIONID")
            .permitAll()
        .and().apply(new SpringSocialConfigurer());

    if (!env.equals("dev"))
        http.requiresChannel().anyRequest().requiresSecure();

}

@Autowired
@Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
    authManagerBuilder.userDetailsService(userService).passwordEncoder(passwordEncoder());
}

}

作为UserDetailsS​​ervice我有以下内容:

@Service
@Transactional(propagation=Propagation.SUPPORTS, readOnly=true)
public class UserServiceImpl implements UserService, UserDetailsService,  SocialUserDetailsService {

private final Logger log = Logger.getLogger(this.getClass());

private UserRepository userRepository;
private PasswordEncoder passwordEncoder;

@Autowired
public UserServiceImpl(UserRepository userRepository,
        PasswordEncoder passwordEncoder) {

    this.userRepository = userRepository;
    this.passwordEncoder = passwordEncoder;

}

@Override
public SocialUserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    User user = userRepository.findByEmail(username);
    if (user == null)
        throw new UsernameNotFoundException(username);

    return new UserDetailsImpl(user);
}

@Override
public User findOne(long userId) {

    User user = userRepository.findOne(userId);
    return user;

}

@Override
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public User signup(SignupForm signupForm) {
    final User user = new User();
    user.setEmail(signupForm.getEmail());
    user.setName(signupForm.getName());
    user.setPassword(passwordEncoder.encode(signupForm.getPassword()));
    userRepository.save(user);
    MyUtil.logInUser(user);
    return user;        
}

@Override
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public void update(long userId, UserEditForm userEditForm) {

    User user = userRepository.findOne(userId);
    user.setName(userEditForm.getName());
    userRepository.save(user);

}

@Override
public SocialUserDetails loadUserByUserId(String userId)
        throws UsernameNotFoundException, DataAccessException {
    return loadUserByUsername(userId);
}

}

我收到以下错误:

org.springframework.beans.factory.BeanCreationException:使用名称' webSecurityConfig'创建bean时出错:资源依赖注入失败;嵌套异常是org.springframework.beans.factory.UnsatisfiedDependencyException:使用名称' userServiceImpl'创建bean时出错。在文件[/home/hardddisk/applications/tomcat8/webapps/ROOT/WEB-INF/classes/com/kefet/controller/UserServiceImpl.class]中定义:通过构造函数参数表示不满意的依赖关系,索引0的类型为[com.kefet。 controller.UserRepository] ​​::找不到类型[com.kefet.controller.UserRepository]的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者。依赖注释:{};嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为[com.kefet.controller.UserRepository]的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者。依赖注释:{}     在org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:311)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)     at org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:305)     在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)     在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)     在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)     在org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:835)     在org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)     在org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446)     在org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328)     在org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)     在org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727)     at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)     在org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)     在org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)     在org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)     在org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)     在org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:945)     在org.apache.catalina.startup.HostConfig $ DeployWar.run(HostConfig.java:1768)     at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)     at java.util.concurrent.FutureTask.run(FutureTask.java:266)     在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)     在java.lang.Thread.run(Thread.java:745)     由以下原因引起:org.springframework.beans.factory.UnsatisfiedDependencyException:使用名称' userServiceImpl'创建bean时出错在文件[/home/hardddisk/applications/tomcat8/webapps/ROOT/WEB-INF/classes/com/kefet/controller/UserServiceImpl.class]中定义:通过构造函数参数表示不满意的依赖关系,索引0的类型为[com.kefet。 controller.UserRepository] ​​::找不到类型[com.kefet.controller.UserRepository]的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者。依赖注释:{};嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为[com.kefet.controller.UserRepository]的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者。依赖注释:{}     在org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)     在org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)     at org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:305)     在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)     在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)     在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)     在org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192)     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)     在org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:508)     在org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:486)     at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor $ ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:615)     在org.springframework.beans.factory.annotation.InjectionMetadata $ InjectedElement.inject(InjectionMetadata.java:169)     在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)     at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:308)     ......还有26个     由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为[com.kefet.controller.UserRepository]的限定bean:期望至少有一个bean可以作为此依赖项的autowire候选者。依赖注释:{}     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)     在org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119)     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)     在org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)     在org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)     ... 44更多

谢谢。

1 个答案:

答案 0 :(得分:0)

错误消息声称它无法找到自动装入构造函数的UserRepository类。您必须使用@Component(或其某些子注释,如@Repository / @Service)来注释此类,以使其可用于自动装配。

//更新:

首先 - 如果你从头开始这个项目,我建议你考虑一下弹簧启动 - 这会为你简化很多配置。

你没有提到你试图在这里使用spring data jpa。 你必须以某种方式让spring知道你的接口在哪里。这是由@EnableJpaRepositories完成的。添加

@EnableJpaRepositories(basePackages = "com.kefet.controller")

高于DatabaseConfig。然后它会抱怨它需要entityManagerFactory。添加:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

    DataSource dataSource = dataSource();
    entityManagerFactoryBean.setDataSource(dataSource);
    entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

    entityManagerFactoryBean.setJpaProperties(jpaProperties());
    entityManagerFactoryBean.setPackagesToScan("com.kefet.controller");

    return entityManagerFactoryBean;
}

@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
    return new HibernateExceptionTranslator();
}

protected Properties jpaProperties() {
    Properties jpaProperties = new Properties();
    jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
    jpaProperties.put(org.hibernate.cfg.Environment.SHOW_SQL, false);
    return jpaProperties;
}

到同一DatabaseConfig班。

这将解决这篇文章的初始问题。您将获得更多错误(没有类型[org.springframework.social.facebook.api.Facebook]的限定bean),但您需要逐个修复它们。