春季启动身份验证中的无限循环



我们最近已将Java转换为Spring应用程序为Spring Boot,并且旧应用程序正常运行,但是在将其转换为Spring Boot Project之后,我们在JWT确保的端点中遇到了严重的问题令牌所有这些都在创建一个无尽的循环,最后抛出StackOverflow例外。

下面是没有实际代码的整个JWT令牌归档器的非常抽象的示例,因为原始代码非常漫长,我觉得这足以适合在春天擅长的人。

public class TokenAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

  public TokenAuthenticationFilter() {
    setAuthenticationManager(new AuthenticationManager() {
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            return null; // no different in the original code 
        }
    });
    setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler() {
        @Override
        protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
            String context = request.getContextPath();
            String fullURL = request.getRequestURI();
            String url = fullURL.substring(fullURL.indexOf(context) + context.length());
            return url;
        }
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) throws IOException, ServletException {
            String url = determineTargetUrl(request, response);
            request.getRequestDispatcher(url).forward(request, response);
        }
    });
    setRequiresAuthenticationRequestMatcher(new RequestMatcher() {
        public boolean matches(HttpServletRequest request) {
            return getTokenRequest(request);
        }
    });
}

private boolean getTokenRequest(HttpServletRequest request) {
    String userAuthToken = request.getHeader("X-Auth-Token");
    return userAuthToken != null;
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>(1);
    roles.add(new SimpleGrantedAuthority("USER_ROLE"));
    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("imaa95@gmail.com", "", roles);
    return authRequest;
 }
}

基本上在实际的代码令牌中,在attemptAuthentication方法中验证了Spring呼叫onAuthenticationSuccess方法,在该方法中,基于逻辑,我们将请求转发给控制器

request.getRequestDispatcher(url).forward(request, response);

我认为这是无限循环的原因如果有人可以发现问题并为我们提供一种解决最小代码更改的方法

,这真的很高兴

按照此处的要求是安全配置

@Override
protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authenticationProvider(daoAuthenticationProvider())
            .authorizeRequests()
            .antMatchers("/", "/allData").permitAll()
            .anyRequest().authenticated()
            .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .formLogin().usernameParameter("email").passwordParameter("password")
                .successHandler(getLoginSuccessHandler())
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request,
                                                        HttpServletResponse response,
                                                        AuthenticationException e) throws IOException,
                            ServletException {
                        response.getWriter().write("Login Failed :(");
                    }
                })
            .and()
                .logout()
                    .logoutRequestMatcher( new AntPathRequestMatcher( "/logout" ) )
                    .logoutSuccessHandler( getLogoutSuccessHandler() )
                    .deleteCookies( "uc" )
                    .invalidateHttpSession( true )
                    .and()
            .exceptionHandling()
            .authenticationEntryPoint(getEntryPoint());
    http.addFilterBefore(new TokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

我怀疑随着登录页面的身份验证,请求会陷入无尽的循环中。在您的配置中,尝试在登录页后立即放置许可证((。

.formLogin().loginPage("/login").permitAll()

随后是其他配置。

编辑:由于上述修复程序无效,因此我怀疑身份验证在2个身份验证提供商之间可能会引起问题。您可以尝试将DaoAuthProvider注入令牌过滤器吗?这样做的方法是:删除配置:

authenticationProvider(daoAuthenticationProvider())

来自

http.authenticationProvider(daoAuthenticationProvider())
            .authorizeRequests()

修改以下配置:

http.addFilterBefore(new TokenAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);

可以像以下方式配置DaoAuthProvider:

@Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(daoAuthProvider);
        }

,在您的TokenAuthenticationFilter中,您可以执行此操作:

public TokenAuthenticationFilter(AuthenticationManager authManager) {       
        setAuthenticationManager(authManager);
    }

我根据我过去对问题的经验建议解决方案。我不确定是否适用于您的案件。

最新更新