必须将Spring Security UserDetailsS​​ervice设置为Error

时间:2017-06-27 06:10:23

标签: java spring spring-mvc

我不明白,为什么customUserDetailsS​​ervice不会自动装配 我使用了两个类

@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger log = 
LoggerFactory.getLogger(CustomUserDetailsService.class);
private UserService userService;


@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String ssoId) throws 
UsernameNotFoundException {
    User user = userService.getUserBySSO(ssoId);
    log.info("User : {}", user);
    if (user == null) {
        log.info("User not found");
        throw new UsernameNotFoundException("User not found");
    }
    return new 
org.springframework.security.core.userdetails.User(user.getSsoId(), 
user.getPassword(),
            true, true, true, true, getGrantedAuthorities(user));
}

private List<GrantedAuthority> getGrantedAuthorities(User user) {
    List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
    for (Role role : user.getRoles()) {
        log.info("UserProfile : {}", role);
        grantedAuthorities.add(new 
SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
    }
    log.info("authorities : {}", grantedAuthorities);
    return grantedAuthorities;
}

@Autowired
public void setUserService(UserService userService) {
    this.userService = userService;
}

=================

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = "ru.mightynoobs.springhibernate.security")
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;

private PersistentTokenRepository tokenRepository;

@Autowired
@Qualifier("customUserDetailsService")
public void setUserDetailsService(UserDetailsService userDetailsService) {
    this.userDetailsService = userDetailsService;
}

@Autowired
@Qualifier("tokenRepositoryDao")
public void setTokenRepository(PersistentTokenRepository tokenRepository) {
    this.tokenRepository = tokenRepository;
}

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder authentication) throws Exception {
    authentication.userDetailsService(userDetailsService);
    authentication.authenticationProvider(authenticationProvider());
}

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.authorizeRequests()
            .antMatchers("/", "/list")
                .access("hasRole('USER') or hasRole('ADMIN') or hasRole('DBA')")
            .and()
                .formLogin().loginPage("/login")
                .loginProcessingUrl("/login").usernameParameter("ssoId").passwordParameter("pass
word")
            .and()
                .rememberMe().rememberMeParameter("remember-
me").tokenRepository(tokenRepository)
                .tokenValiditySeconds(86400)
            .and()
                .csrf()
            .and()
                .exceptionHandling().accessDeniedPage("/access_denied");
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Bean
public PersistentTokenBasedRememberMeServices 
persistentTokenBasedRememberMeServices() {
    return new PersistentTokenBasedRememberMeServices("remember-me", 
userDetailsService, tokenRepository);
}

@Bean
public AuthenticationTrustResolver getAuthenticationTrustResolver() {
    return new AuthenticationTrustResolverImpl();
}

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider daoAuthenticationProvider = new 
DaoAuthenticationProvider();
    daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
    daoAuthenticationProvider.setUserDetailsService(userDetailsService);
    return daoAuthenticationProvider;
}
}

还有stackTrace

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springSecurityConfig': Unsatisfied dependency expressed through method 'setUserDetailsService' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customUserDetailsService': Unsatisfied dependency expressed through method 'setUserService' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ru.mightynoobs.springhibernate.service.user.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:667)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4743)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1702)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:482)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:431)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customUserDetailsService': Unsatisfied dependency expressed through method 'setUserService' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ru.mightynoobs.springhibernate.service.user.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}    

请解释一下,怎么可能。这些类具有相同的包,我包含了这个包@ComponentScan注释。春天仍然抱怨他找不到@Service Component。有一些简单的东西,但我无法得到它。请帮忙。

3 个答案:

答案 0 :(得分:3)

我认为您不必使用customUserDetailService注释标记@Service。此外,db操作和事务应在userService中完成,以区分每层的任务。像这样重构CustomUserDetailsService

public class CustomUserDetailsService implements UserDetailsService {
    // ...

    @Override
    public UserDetails loadUserByUsername(String ssoId) throws UsernameNotFoundException {
        // the implementation
    }
}

根据Spring Security的反抗意见:

  

5.6.5 UserDetailsS​​ervice

     

您可以通过公开自定义来定义自定义身份验证   UserDetailsS​​ervice作为bean。例如,以下将   假设SpringDataUserDetailsS​​ervice自定义身份验证   实现UserDetailsS​​ervice:

     

[注意]仅在AuthenticationManagerBuilder没有时使用   已填充,未定义AuthenticationProviderBean。

所以删除DaoAuthenticationProvider中的bean SpringSecurityConfig

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder authentication) throws Exception {
    authentication.userDetailsService(userDetailsServiceBean());
    //authentication.authenticationProvider(authenticationProvider());
}

@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
    return new CustomUserDetailsService();
}

答案 1 :(得分:1)

设置字段后,不保证执行configureGlobalSecurity定义。因此userDetailsServicenull

@Autowired
@Qualifier("customUserDetailsService")
public void configureGlobalSecurity(AuthenticationManagerBuilder authentication, UserDetailsService userDetailsService) throws Exception {
    authentication.userDetailsService(userDetailsService);
    authentication.authenticationProvider(authenticationProvider());
}

答案 2 :(得分:0)

使用XML配置:

<security:authentication-manager id="clientAuthenticationManager">
        <security:authentication-provider ref="stratusDaoAuthenticationProvider"></security:authentication-provider>
        <security:authentication-provider user-service-ref="stratusClientUserDetailsService" >
            <security:password-encoder ref="delegatePasswordEncoder" />
        </security:authentication-provider>
        <!-- <security:authentication-provider user-service-ref="uriEncodedClientUserDetailsService"/>-->
</security:authentication-manager>