完全错误:com.api.websecurityconfig中的字段myuserdetailsservice需要一个bean,但找到2个:
user1:在文件[/tools/tomcat/instances/webapps/api/webinf/classes/com/api/jwt/users/test1.class]中定义
user2:在文件[/tools/tomcat/instances/webapps/api/webinf/classes/com/api/jwt/users/test2.class]中定义
我有以下课程:
测试1.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);
}
}
}
测试2.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);
}
}
}
SpringMain应用程序.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
作为用户类。
编辑:
测试1.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);
}
}
}
测试2.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);
}
}
}
SpringMain应用程序.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]
1条答案
按热度按时间w8f9ii691#
这些声明不需要限定符。spring可以按类型注入这些bean,因为每个类型都有一个匹配的bean(test1和test2)。
但是,您确实需要为这个声明提供一个限定符,因为您有两个
UserDetailsService
spring不知道要注入哪一个,导致了错误。编辑
在更新的示例中,您定义了两个具有相同bean id的bean
这将导致您看到的新错误(查看spring文档可能会有所帮助):
为bean类[com.api.jwt.users.test2detailsservice]指定的注解bean名称“myuserdetailsservice”与相同名称和类[com.api.jwt.users.test1detailsservice]的现有不兼容bean定义冲突
在你的例子中,有两个是没有意义的
UserDetailsService
实现。您可以通过将它们组合到一个类中来重构。