英文:
@WebMvcTest Error creating bean with name 'securityConfiguration'
问题
这里是您提供的翻译内容:
我有一个使用Spring Boot的REST应用程序,我在其中使用JWT进行身份验证,当我只启动应用程序时,它能正常运行。
我只是想添加一些测试案例,但我无法解决这个问题(我使用 mvn test
运行测试案例):
错误表明Spring无法创建userDetailsService bean,但这似乎是不正确的,因为我的应用程序可以毫无问题地运行。
注意:我尝试通过 @MockBean 添加 userdetailservice 的模拟。但这次Spring对于 MyAuthenticationEntryPoint 显示相同的错误。我认为应该有一个解决方案可以自动添加所有配置,或者避免对此端点进行全部配置。
[ERROR] verifyRegisterUserHttpRequest Time elapsed: 0.008 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed
through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.myProjects.sample.security.MyUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
- 这是测试类:
package com.myProjects.sample.controller;
@WebMvcTest(controllers = RegisterController.class)
public class RegisterControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private RegisterService registerService;
@MockBean
private ValidationService validationService;
// 1. 验证 Http 请求匹配
@Test
public void verifyRegisterUserHttpRequest() throws Exception {
NewCustomerRequest requestBody = new NewCustomerRequest();
requestBody.setEmailAddress("sample@sample.com");
requestBody.setPhoneNumber("01112223344");
requestBody.setPassword("password");
requestBody.setPasswordVerify("password");
mockMvc.perform(post(MyWebUrls.API.API + MyWebUrls.Register.REGISTER_USER)
.content(objectMapper.writeValueAsString(requestBody))
.contentType("application/json"))
.andExpect(status().isOk());
}
}
- RegisterController 和 SecurityConfiguration
package com.myProjects.sample.controller;
@RestController
@RequestMapping(MyWebUrls.API.API)
public class RegisterController {
@Autowired
private RegisterService registerService;
@Autowired
private ValidationService validationService;
@PostMapping(MyWebUrls.Register.REGISTER_USER)
public ResponseEntity<?> registerUser(@Valid @RequestBody NewCustomerRequest newCustomerRequest, BindingResult bindingResult){
String validationResultMessage = validationService.getFirstValidationErrorMessage(bindingResult);
// ...
}
}
package com.myProjects.sample.security;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private MyAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
@Bean
public AuthTokenFilter authJwtTokenFilter(){
return new AuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
// ....
- 还要查看我的自定义详情服务类
package com.myProjects.sample.security;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Override
@Transactional
public UserDetails loadUserByUsername(String emailOrMobilePhone) throws UsernameNotFoundException {
// ...
}
}
英文:
I have a spring boot rest application where I use JWT for authentication and it works fine when I just start the application.
I just wanted to add some test cases but I could not solve this problem (I run the test cases with mvn test
:
> Error states that Spring can not create userDetailsService bean but this seems incorrect, because my application can run without any issue.
Not: I have tried to add userdetailservice mock via @MockBean. But this time spring shows the same error for MyAuthenticationEntryPoint. I think there should be a solution to add all configuration automatically, or avoid them all for this endpoint.
[ERROR] verifyRegisterUserHttpRequest Time elapsed: 0.008 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed
through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.myProjects.sample.security.MyUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
- Here is the test class:
package com.myProjects.sample.controller;
@WebMvcTest(controllers = RegisterController.class)
public class RegisterControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private RegisterService registerService;
@MockBean
private ValidationService validationService;
// 1. Verifying Http Request Matching
@Test
public void verifyRegisterUserHttpRequest() throws Exception {
NewCustomerRequest requestBody = new NewCustomerRequest();
requestBody.setEmailAddress("sample@sample.com");
requestBody.setPhoneNumber("01112223344");
requestBody.setPassword("password");
requestBody.setPasswordVerify("password");
mockMvc.perform(post(MyWebUrls.API.API + MyWebUrls.Register.REGISTER_USER)
.content(objectMapper.writeValueAsString(requestBody))
.contentType("application/json"))
.andExpect(status().isOk());
}
}
- RegisterController and SecurityConfiguration
package com.myProjects.sample.controller;
@RestController
@RequestMapping(MyWebUrls.API.API)
public class RegisterController {
@Autowired
private RegisterService registerService;
@Autowired
private ValidationService validationService;
@PostMapping(MyWebUrls.Register.REGISTER_USER)
public ResponseEntity<?> registerUser(@Valid @RequestBody NewCustomerRequest newCustomerRequest, BindingResult bindingResult){
String validationResultMessage = validationService.getFirstValidationErrorMessage(bindingResult);
// ...
}
}
}
package com.myProjects.sample.security;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private MyAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
@Bean
public AuthTokenFilter authJwtTokenFilter(){
return new AuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
// ....
- And also see my custom details service class
package com.myProjects.sample.security;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Override
@Transactional
public UserDetails loadUserByUsername(String emailOrMobilePhone) throws UsernameNotFoundException {
// ...
}
}
答案1
得分: 1
以下是翻译好的内容:
你能将以下依赖项添加到你的项目中吗?
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
这样应该可以确保为你的 @WebMvcTest
配置也填充了安全性配置。
然后,你可以使用多种技术来模拟在使用 MockMvc
访问你的应用程序时的凭据/用户:
@Test
@WithMockUser("duke")
或者
@Test
public void testWithSecurityMockMvcRequestPostProcessors() throws Exception {
this.mockMvc
.perform(
post("/your/endpoint")
.with(jwt())
.with(csrf())
)
.andExpect(status().isOk());
}
有关 MockMvc
和 Spring Security 集成的更多信息可以在 这里 找到。
英文:
Can you add the following dependency to your project?
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
This should then ensure to also populate your security configuration for your @WebMvcTest
.
You can then use several techniques to mock credentials/user when accessing your application with MockMvc
:
@Test
@WithMockUser("duke")
or
@Test
public void testWithSecurityMockMvcRequestPostProcessors() throws Exception {
this.mockMvc
.perform(
post("/your/endpoint")
.with(jwt())
.with(csrf())
)
.andExpect(status().isOk());
}
More information for the MockMvc
and Spring Security integration can be found here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论