代码之家  ›  专栏  ›  技术社区  ›  sidgate

Mock@AuthenticationPrincipal参数

  •  1
  • sidgate  · 技术社区  · 6 年前

    PrincipalExtractor 类生成自定义主体对象。此自定义主体对象不扩展 Principal UserDetails

    class CustomUser{
    //some custom fields
    }
    
    class CustomPrincipalExtractor implements PrincipalExtractor{
      @Override 
      public CustomUser extractPrincipal(Map<String, Object> map){
        return new CustomUser(map);
      }
    }
    
    
    class SomeController{
      @GetMapping
      public ResponseEntity(@AuthenticationPrincipal CustomUser user){
         //able to get user object 
      }
    }
    

    上面的代码工作正常。现在我想测试控制器,但不能通过CustomUser实例。

    @SpringBootTest
    @AutoConfigureMockMvc
    public class SomeControllerTest{
       @Autowired
       private MockMvc mockMvc;
    
      @Test
      public void test(){
        mockMvc.perform(get(...).principal(CANNOT pass CustomUser as it does not implement Principal))
      }
    }
    

    我看了一些其他的解决方案,要求有自定义 HandlerMethodArgumentResolver 但不确定如何配置自动配置的MockMvc

    1 回复  |  直到 6 年前
        1
  •  3
  •   sidgate    6 年前

    public class MockSpringSecurityFilter implements Filter {
      @Override
      public void init(FilterConfig filterConfig) {}
    
      @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        SecurityContextHolder.getContext()
          .setAuthentication((Authentication) ((HttpServletRequest) req).getUserPrincipal());
        chain.doFilter(req, res);
      }
    
      @Override
      public void destroy() {
        SecurityContextHolder.clearContext();
      }
    }
    

    在测试范围内

    @Before
    public void setup() {
      mockMvc = MockMvcBuilders.webAppContextSetup(context)
        .apply(springSecurity(new MockSpringSecurityFilter()))
        .build();
    }
    
    @Test
      public void test(){
        mockMvc.perform(get(...)
         .principal(new UsernamePasswordAuthenticationToken(new CustomUser(), null))...
      }