当前位置: 首页 > 知识库问答 >
问题:

MockMvc使用不调用DispatcherServlet的自定义过滤器执行基本Authentificaton Point

邵华皓
2023-03-14

我使用@AutoConfigureMockMvc,所有无身份验证请求和请求都需要完美地进行身份验证(使用调用DispatcherServlet)

但当我试图执行auth point(用户名、密码)来全面测试身份验证时:

var resp = mockMvc.perform(post("/api/auth")
    .content(objectMapper.writeValueAsString(requestDto))
    .andExpect(status().isOk())
    .andReturn().getResponse().getContentAsString();

处理完所有自定义身份验证过滤器后,在auth上下文中创建UserDetails,但变量resp为空。

我尝试调试(CustomUsernamePasswordAuthenticationFilter=CustomFilter):

CustomFilter.attemptAuthentication
CustomFilter.doFilter
CustomFilter.successfulAuthentication
this.successHandler.onAuthenticationSuccess
ForwardAuthenticationSuccessHandler.onAuthenticationSuccess
request.getRequestDispatcher(this.forwardUrl).forward(request, response)
MockRequestDispatcher.forward

MockRequest estDispatcher.forward-此模拟请求调度程序返回空响应

当我通过邮递员而不是MockRequest estDispatcher调用/api/auth时,它从apache调用Application ationDispatcher,它的前向方法调用realDispatcherServlet

而不是自动配置mockMvc,我尝试使用这个,没有效果:

mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
            .addFilters(filters)
            .build();

当我删除addFilters时,DispatcherServlet可以工作,但身份验证未处理(过滤器不调用)

有人知道如何将MockRequestDispatcher重写为ApplicationDispatcher以调用真正的DispatcherServlet和controller吗?

共有1个答案

曹波鸿
2023-03-14

我通过覆盖身份验证过滤器中的ForwardAuthentiation成功处理程序解决了这个问题:

@Bean
public MockMvc mockMvcWithAuthSupport(
        @Qualifier("springSecurityFilterChain") Filter springSecurityFilterChain,
        WebApplicationContext webApplicationContext
) {
    FilterChainProxy filterChain = (FilterChainProxy) springSecurityFilterChain;
    UsernamePasswordAuthenticationFilter[] filters = filterChain.getFilterChains().stream()
            .flatMap(chain -> chain.getFilters().stream())
            .filter(this::isUsernamePasswordFilter)
            .map(f -> (UsernamePasswordAuthenticationFilter) f)
            .peek(filter -> filter.setAuthenticationSuccessHandler(new MockMvcSuccessHandler()))
            .toArray(UsernamePasswordAuthenticationFilter[]::new);

    return MockMvcBuilders.webAppContextSetup(webApplicationContext)
            .addFilters(filters)
            .build();
}

自定义成功处理程序:

private class MockMvcSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        MockFilterChain filterChain = new MockFilterChain(mockMvc.getDispatcherServlet(), new Filter[0]);
        filterChain.doFilter(request, response);
    }
}
 类似资料:
  • 问题内容: 我已经如下设置了web.xml。我还有一个基于注释的控制器,该控制器可以采用任何URL模式,然后转到相应的jsp(我已在-servlet.xml中进行了设置)。但是,如果转到以.html结尾的页面(并且其jsp不存在),则看不到自定义404页面(并且在日志中看到以下错误)。任何不以.html结尾的页面,我都可以看到自定义404页面。 如何为通过DispatcherServlet的任何页

  • 本文向大家介绍详解AngularJS中$filter过滤器使用(自定义过滤器),包括了详解AngularJS中$filter过滤器使用(自定义过滤器)的使用技巧和注意事项,需要的朋友参考一下 1.内置过滤器 2.自定义过滤器     套用上面的格式定义两个简单的自定义过滤器一个带条件的,一个不带条件的。 (1)【不带条件】,功能:固定转换(有时候项目中会遇到角色代号,门店编码什么的,但是显示的时候

  • 我正在尝试为resty gwt编写我的自定义调度程序。 我的dispatcher将包含两个过滤器: 基本CauthHeaderDispatcherFilter(将添加到每个请求安全令牌), 我有一个问题,我的过滤器是由gwt/restygwt注册的,不幸的是它们不工作。 以下是代码: gin客户端模块 RestyGwtConfig RestyDispatcher 禁止调度过滤器 禁止调度员回调 B

  • 演示在网关追加一个header public class CustomFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 演示在网关追加heade

  • SOFARPC 提供了一套良好的可扩展性机制,为各个模块提供 SPI 的能力。 SOFARPC 对请求与响应的过滤链处理方式是通过多个过滤器 Filter 来进行具体的拦截处理,该部分可由用户自定义 Filter 扩展,自定义 Filter 的执行顺序在内置 Filter 之后。具体方式如下: Bolt Filter 新建自定义 Filter 。 public class CustomFilter

  • 问题内容: 我正在尝试为resty gwt编写我的自定义调度程序。 我的调度程序将包含两个过滤器: (将添加到每个请求安全令牌中), (将包含回调)-如果用户未登录,他的工作是重定向到登录页面。 我有问题,我的过滤器是由gwt / restygwt注册的,不幸的是它们不起作用。 这是代码: 杜松子酒客户端模块 RestyGwtConfig RestyDispatcher ForbiddenDisp