模拟@AuthenticationPrincipal参数

时间:2018-09-05 08:27:36

标签: java spring spring-boot spring-security spring-security-oauth2

我有一个Spring-security-oauth2应用程序,它是一个ResourceServer。我们有一个自定义PrincipalExtractor类,用于构建自定义Principal对象。此自定义Principal对象不会扩展PrincipalUserDetails

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 个答案:

答案 0 :(得分:0)

我必须实施一些变通办法才能完成这项工作。

创建了一个模拟筛选器,该筛选器在SecurityContext中设置了Authentication对象。以下是代码

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))...
  }