具有自定义筛选器和多个身份验证提供程序的Spring REST安全性 - 成功身份验证时未调用目标方法

时间:2015-04-08 03:23:33

标签: rest spring-mvc authentication filter spring-security

我正在为REST服务实现Spring安全模块。它涉及2个自定义筛选器和2个自定义身份验证提该应用程序使用Spring 4.1.5.RELEASE和Spring security 4.0.0.RELEASE。没有XML。 验证成功后,我的自定义AuthenticationSuccessHandler将被调用。在onAuthenticationSuccess方法中,我只是重新构建原始URL并转发请求。但是请求永远不会进入REST服务。我没有收到任何错误,只是状态为200的空响应。我通过删除自定义过滤器进行检查,并且该服务被调用正常。在调用成功处理程序之后我甚至无法弄明白。为什么请求永远不会达到目标?请帮忙。

WebSecurityConfigurerAdapter实施:

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

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
    .anyRequest()
    .authenticated()
    .and()
    .exceptionHandling()
    .authenticationEntryPoint(restAuthenticationEntryPoint)
    .and()
    .sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and()
    .addFilterBefore(serviceRegistrationValidatingFilter,
    CustomUsernamePasswordAuthenticationFilter.class)
    .addFilter(authFilter);
}

AuthenticationEntryPoint实施:

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                authException.getMessage());
    }
}

AuthenticationSuccessHandler实施:

@Component
public class RestAuthenticationSuccessHandler extends
        SimpleUrlAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        String path = Joiner.on("/")
                .join(request.getServletPath(), request.getPathInfo())
                .replaceAll("//", "/");
        request.getRequestDispatcher(path).forward(request, response);
        clearAuthenticationAttributes(request);
    }
}

日志显示创建的过滤器链(为简洁起见,省略了包名和哈希码)。我的过滤器是我想要它们的地方。

INFO: Creating filter chain: AnyRequestMatcher, [WebAsyncManagerIntegrationFilter, SecurityContextPersistenceFilter, HeaderWriterFilter, CsrfFilter, LogoutFilter, ServiceRegistrationValidatingFilter, CustomUsernamePasswordAuthenticationFilter, RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, FilterSecurityInterceptor]

1 个答案:

答案 0 :(得分:0)

所以问题是使用Spring MockMvc。我需要使用forwardedUrl("forwardToUrl")进行验证。正如我在上面发布的那样,实际的前锋并没有发生。 content().string("expectedString")也没有工作,内容空白。

似乎MockMvc旨在测试行为,而不是数据。

 mockMvc.perform(get("/form"))
     .andExpect(status().isOk())
     .andExpect(content().string("expectedString"))
     .andExpect(forwardedUrl("forwardToUrl"));