下面我有一个customUserDetailsService
属性和一个tokenAuthenticationService
属性。我需要将customUserDetailsService
传递给tokenAuthenticationService
,但tokenAuthenticationService
是@Bean
文件而customUserDetailsService
是@Service
,这意味着tokenAuthenticationService
首先调用UserDetailsService
的参数作为null
参数的UserDetailsService
。我需要延迟启动tokenAuthenticationService
作为Bean或将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 :(得分:1)
您可以将userDetailsService定义为TokenAuthenticationService的直接依赖关系,如下所示:
@Bean
public TokenAuthenticationService tokenAuthenticationService(UserDetailsService userDetailsService) {
tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", userDetailsService);
return tokenAuthenticationService;
}
这样,Spring将确保在创建TokenAuthenticationService时实例化并注入UserDetailsService。
答案 1 :(得分:0)
您可以尝试使用@Lazy注释tokenAuthenticationService()。虽然这有点不可预测,但未来对这个或相关bean的修改可能让你想知道为什么它停止工作。
最好将TokenAuthenticationService
声明为@Service
&注入UserDetailsService
。
作为旁注,最好不要将@Configuration与应用程序代码混合以避免这些问题。
更新 - 我认为@Lazy不会在这里工作。因为你依赖@Bean是在正在处理的@Autowired bean的中间调用的。
为了使代码正常工作,应首先设置@Autowired
customUserDetailsService,然后调用@Bean
方法,然后设置@Autowired
tokenAuthenticationService。