【发布时间】:2021-04-23 00:50:32
【问题描述】:
完全错误: com.api.WebSecurityConfig 中的字段 myUserDetailsService 需要一个 bean,但找到了 2 个:
- user1:在文件中定义 [/tools/tomcat/instances/webapps/api/WEB-INF/classes/com/api/jwt/users/test1.class]
- user2:在文件中定义 [/tools/tomcat/instances/webapps/api/WEB-INF/classes/com/api/jwt/users/test2.class]
我有以下课程:
Test1.java
@Service
@Component("user1")
public class Test1 implements UserDetailsService {
@Value("${test1.username}")
private String test1Username;
@Value("${test1.password}")
private String test1Password;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username != null && username.equals(test1Username)) {
return new User(username, test1Password, new ArrayList<>());
} else {
throw new UsernameNotFoundException("Username not found: " + username);
}
}
}
Test2.java
@Service
@Component("user2")
public class Test2 implements UserDetailsService {
@Value("${test2.username}")
private String test2Username;
@Value("${test2.password}")
private String test2Password;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username != null && username.equals(test2Username)) {
return new User(username, test2Password, new ArrayList<>());
} else {
throw new UsernameNotFoundException("Username not found: " + username);
}
}
}
SpringMainApplication.java
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService myUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/**/access-token").permitAll().
anyRequest().authenticated().and().
exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
JwtRequestFilter.java
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
@Qualifier(value = "user1")
private Test1 test1;
@Autowired
@Qualifier(value = "user2")
private Test2 test2;
@Override
protected void doFilterInternal() throws ServletException, IOException {
// SOME CODE
}
我以为通过使用@Component和@Qualifier,我可以设置两个用户详细信息类,但似乎并非如此。
有什么我遗漏的或者在这个设计中是不可能的吗?
如果我创建另一个名为 MyUserDetailsService.java 的类,则编译工作正常,并且在各自的端点中访问正确的类。我只是不明白为什么MyUserDetailsService 必须存在并且我不能使用Test1 和Test2 作为用户类。
编辑:
Test1.java
@Service
@Component("myUserDetailsService")
public class Test1 implements UserDetailsService {
@Value("${test1.username}")
private String test1Username;
@Value("${test1.password}")
private String test1Password;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username != null && username.equals(test1Username)) {
return new User(username, test1Password, new ArrayList<>());
} else {
throw new UsernameNotFoundException("Username not found: " + username);
}
}
}
Test2.java
@Service
@Component("myUserDetailsService")
public class Test2 implements UserDetailsService {
@Value("${test2.username}")
private String test2Username;
@Value("${test2.password}")
private String test2Password;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username != null && username.equals(test2Username)) {
return new User(username, test2Password, new ArrayList<>());
} else {
throw new UsernameNotFoundException("Username not found: " + username);
}
}
}
SpringMainApplication.java
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier(value = "myUserDetailsService")
private UserDetailsService myUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/**/access-token").permitAll().
anyRequest().authenticated().and().
exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
JwtRequestFilter.java
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private Test1 test1;
@Autowired
private Test2 test2;
@Override
protected void doFilterInternal() throws ServletException, IOException {
// SOME CODE
}
这给了我以下错误:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.api.SpringMainApplication];
nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException:
Annotation-specified bean name 'myUserDetailsService' for bean class [com.api.jwt.users.Test2DetailsService] conflicts with existing, non-compatible bean definition of same name and class [com.api.jwt.users.Test1DetailsService]
【问题讨论】:
标签: java spring spring-boot jwt components