2015-11-19 2 views
0

Ниже у меня есть собственность customUserDetailsService и собственность tokenAuthenticationService. Мне нужно передать customUserDetailsService в tokenAuthenticationService но tokenAuthenticationService является @Bean файлом и customUserDetailsService является @Service, что означает, что tokenAuthenticationService вызывается первым параметром для UserDetailsService в null для параметра UserDetailsService. Мне нужно либо задержать начало tokenAuthenticationService в качестве Bean, либо Turn tokenAuthenticationService, а также как передать эти параметры в качестве конструктора. Как мне это сделать?Весенняя обувь. Бобы зависят от услуги

package app.config; 

    import app.repo.User.CustomUserDetailsService; 
    import app.security.*; 
    import app.security.filters.StatelessAuthenticationFilter; 
    import org.springframework.beans.factory.annotation.Autowired; 
    import org.springframework.context.annotation.Bean; 
    import org.springframework.context.annotation.Configuration; 
    import org.springframework.context.annotation.DependsOn; 
    import org.springframework.core.annotation.Order; 
    import org.springframework.security.authentication.AuthenticationManager; 
    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.core.userdetails.UserDetailsService; 
    import org.springframework.security.crypto.password.PasswordEncoder; 
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 

    import javax.sql.DataSource; 

    @Configuration 
    @EnableWebSecurity 
    @EnableGlobalMethodSecurity(securedEnabled = true) 
    @Order(2) 
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

     private static PasswordEncoder encoder; 

     @Autowired 
     private TokenAuthenticationService tokenAuthenticationService; 

     @Autowired 
     private UserDetailsService customUserDetailsService; 

     @Autowired 
     private RESTAuthenticationEntryPoint authenticationEntryPoint; 
     @Autowired 
     private RESTAuthenticationFailureHandler authenticationFailureHandler; 
     @Autowired 
     private RESTAuthenticationSuccessHandler authenticationSuccessHandler; 

     public WebSecurityConfig() { 
      super(true); 
     } 

     @Autowired 
     public void configureAuth(AuthenticationManagerBuilder auth,DataSource dataSource) throws Exception { 
      auth.jdbcAuthentication().dataSource(dataSource); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeRequests().antMatchers("/**").authenticated(); 
      http.csrf().disable(); 
      http.httpBasic(); 
      http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); 
      http.formLogin().defaultSuccessUrl("/").successHandler(authenticationSuccessHandler); 
      http.formLogin().failureHandler(authenticationFailureHandler); 
      http.addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), 
        UsernamePasswordAuthenticationFilter.class); 

     } 

     @Override 
     protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
      auth.userDetailsService(customUserDetailsService); 
     } 

     @Bean 
     public TokenAuthenticationService tokenAuthenticationService() { 
      tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", customUserDetailsService); 
      return tokenAuthenticationService; 
     } 
    } 
+0

Почему вы не отправляете стек? Обычно Spring закончил автосоздание класса конфигурации перед вызовом его заводских методов, но циклические зависимости (или зависимости от Bean (Factory) PostProcessors) могут помешать этому. – meriton

+0

Откуда «TokenAuthenticationService»? Можете ли вы добавить конструктор, который принимает только один аргумент и Autwire userDetailService? – jny

ответ

0

Вы можете попробовать аннотирования tokenAuthenticationService() с @Lazy. Хотя даже если это сработало немного непредсказуемо, и будущие модификации этого или связанных с ним бобин могут оставить вас задуматься о том, почему он перестает работать.

Лучше всего объявить TokenAuthenticationService как @Service & ввести UserDetailsService в него.

В качестве примечания стороны лучше не смешивать @ Конфигурация с кодом приложения, чтобы избежать таких проблем.

Обновление - Я не думаю, что @Lazy будет работать здесь. Поскольку вы полагаетесь на @Bean, который вызывается в середине @Autowired beans, обрабатывается.

Для того, чтобы ваш код для работы в @Autowired customUserDetailsService должен быть установлен первым, а затем @Bean метод, названный затем @Autowired tokenAuthenticationService должен быть установлен.

1

Вы можете определить UserDetailsService в прямой зависимости от TokenAuthenticationService, как это:

@Bean 
public TokenAuthenticationService tokenAuthenticationService(UserDetailsService userDetailsService) { 
    tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", userDetailsService); 
    return tokenAuthenticationService; 
} 

Таким образом, весна будет убедиться, что UserDetailsService конкретизируется и вводят, когда TokenAuthenticationService создается.

Смежные вопросы