Java 在Spring应用程序中将MockitoMVC与Junit一起使用时发生Stackoverflow错误

Java 在Spring应用程序中将MockitoMVC与Junit一起使用时发生Stackoverflow错误,java,spring-boot,junit,mockmvc,Java,Spring Boot,Junit,Mockmvc,我正在尝试测试我的Spring应用程序,它由JWT auth和Junit和Mockmvc组成。注册测试按预期进行。但当尝试测试登录时,会显示StackOverflowerError。在JWTAuthenticationFilter.java中,正在成功接收数据。但在该错误显示之后。请帮帮我。谢谢 错误: java.lang.StackOverflowError at org.mockito.internal.invocation.MatchersBinder.bindMatchers(

我正在尝试测试我的Spring应用程序,它由JWT auth和Junit和Mockmvc组成。注册测试按预期进行。但当尝试测试登录时,会显示StackOverflowerError。在JWTAuthenticationFilter.java中,正在成功接收数据。但在该错误显示之后。请帮帮我。谢谢

错误:


java.lang.StackOverflowError
    at org.mockito.internal.invocation.MatchersBinder.bindMatchers(MatchersBinder.java:25)
    at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:59)
    at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
    at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:35)
    at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:63)
    at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:49)
    at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptSuperCallable(MockMethodInterceptor.java:110)
    at org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder$MockitoMock$310380589.encode(Unknown Source)
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.prepareTimingAttackProtection(DaoAuthenticationProvider.java:142)
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:106)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200)
    at org.springframework.security.con
WebSecurity.java


@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    private UserDetailsServiceImpl userDetailsService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;


    public WebSecurity(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()))
                // this disables session creation on Spring Security
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.parentAuthenticationManager(authenticationManagerBean())
                .userDetailsService(userDetailsService)
                .passwordEncoder(bCryptPasswordEncoder);
    }

}
UserControllerTest.java


@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureJsonTesters
public class UserControllerTest {
    @Autowired
    private MockMvc mvc;

    @Autowired
    private JacksonTester<User> json;

    @Autowired
    private JacksonTester<CreateUserRequest> jsonN;

    @MockBean
    private UserRepository userRepository;

    @MockBean
    private BCryptPasswordEncoder encoder;

    private  CreateUserRequest r;

    @Before
    public void setup(){
        r = new CreateUserRequest();
        r.setUsername("ujjwal2102");
        r.setPassword("ujjwal21");
        r.setConfirmPassword("ujjwal21");


    }

    @Test
    public void createUserTest() throws Exception{
        signup();
    }

    @Test
    public void loginUserTest() throws Exception{
        signup();
        login();
    }

    public void signup() throws Exception{
        when(encoder.encode("ujjwal21")).thenReturn("ujjwal21");

        mvc.perform(
                post(new URI("/api/user/create"))
                        .content(jsonN.write(r).getJson())
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .accept(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id",is(0)))
                .andExpect(jsonPath("$.username",is("ujjwal2102")));
    }

    public void login() throws Exception{

        User user = new User();
        user.setUsername("ujjwal2102");
        user.setPassword("ujjwal21");

        when(encoder.encode("ujjwal21")).thenReturn("ujjwal21");
        mvc.perform(
                    post(new URI("/login"))
                        .content(json.write(user).getJson())
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .accept(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk());



    }


}

JWTAuthenticationFilter.java


public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private AuthenticationManager authenticationManager;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest req,
                                                HttpServletResponse res) throws AuthenticationException {
        try {
            User creds = new ObjectMapper()
                    .readValue(req.getInputStream(), User.class);
            System.out.println("USERNAME-----" + creds.getUsername());
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            creds.getUsername(),
                            creds.getPassword(),
                            new ArrayList<>())
            );
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest req,
                                            HttpServletResponse res,
                                            FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {

        String token = JWT.create()
                .withSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername())
                .withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
                .sign(HMAC512(SecurityConstants.SECRET.getBytes()));
        System.out.println("TOKEN----" + token);
        res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
    }
}

公共类JWTAuthenticationFilter扩展了UsernamePasswordAuthenticationFilter{
私人AuthenticationManager AuthenticationManager;
公共JWTAuthenticationFilter(AuthenticationManager AuthenticationManager){
this.authenticationManager=authenticationManager;
}
@凌驾
公共身份验证尝试身份验证(HttpServletRequest-req,
HttpServletResponse(res)引发AuthenticationException{
试一试{
User creds=new ObjectMapper()
.readValue(req.getInputStream(),User.class);
System.out.println(“用户名------”+creds.getUsername());
返回authenticationManager.authenticate(
新用户名PasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
新建ArrayList())
);
}捕获(IOE异常){
抛出新的运行时异常(e);
}
}
@凌驾
受保护的无效成功身份验证(HttpServletRequest-req,
HttpServletRes,
过滤链,
身份验证(auth)引发IOException、ServletException{
字符串标记=JWT.create()
.withSubject(((org.springframework.security.core.userdetails.User)auth.getPrincipal()).getUsername())
.withExpiresAt(新日期(System.currentTimeMillis()+SecurityConstants.Expirement\u TIME))
.sign(HMAC512(SecurityConstants.SECRET.getBytes());
System.out.println(“令牌----”+令牌);
res.addHeader(SecurityConstants.HEADER\u字符串,SecurityConstants.TOKEN\u前缀+令牌);
}
}

我注意到一个错误,它可能会解决您的问题,也可能不会解决您的问题,但可能会影响您的身份验证过程

new UsernamePasswordAuthenticationToken(
    creds.getUsername(), 
    creds.getPassword(), 
    new ArrayList<>()) // with autorities, the user is authenticated

new UsernamePasswordAuthenticationToken(
    creds.getUsername(), 
    creds.getPassword()) // without autorities, the user is not authenticated
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
new ArrayList())//使用autorities对用户进行身份验证
新用户名PasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword())//如果没有自动权限,则用户未经身份验证
AuthentificationManager通常在身份验证成功后使用具有autorities的构造函数。筛选器使用不带的构造函数传递给AuthentificationManager


查看日志,问题似乎出现在您没有提供的Spring安全配置中。您可能在身份验证提供程序内进行了递归调用。

有东西在递归调用自身。顺便说一句,你发布的日志不完整,你介意发布完整的日志吗log@mangusta我已经更新了日志。谢谢回复!感谢您的回复,但这并没有解决错误。我添加了WebSecurity.java。
new UsernamePasswordAuthenticationToken(
    creds.getUsername(), 
    creds.getPassword(), 
    new ArrayList<>()) // with autorities, the user is authenticated

new UsernamePasswordAuthenticationToken(
    creds.getUsername(), 
    creds.getPassword()) // without autorities, the user is not authenticated