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

Spring Security测试和MockMvc向REST控制器提供空的自定义UserDetails参数

琴英华
2023-03-14

我正在尝试编写一个联调器,它会到达RESTendpoint并获取特定经过身份验证的用户(我在测试中设置的用户)的数据。我最初尝试使用mockMvc=webAppContextSetup(wac). Application(springSecurity()). build()进行设置,但使用BeanInstantiationException时总是失败。在使用自定义用户详细信息实现测试Spring Security和MvcMock的帮助下,我能够通过切换我的设置来克服这个问题。现在我已经将我的设置切换到使用Standard aloneSetup,我可以调用我的控制器。但是,无论我做什么,我都无法将我在测试中创建的自定义User细节对象获取到我的控制器中调用MockMvc的方法中。

我使用的是Spring 4.2.2和Spring Security 4.0.1。

我的测试代码如下所示:

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { RestControllerITConfig.class })
@WebAppConfiguration
public class ControllerIT {

  private MockMvc mockMvc;

  @Before
  public void setUp() {
    mockMvc = standaloneSetup(new Controller())
                .setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver())
                .build();
  }

  @Test
  public void testGetEndpoint() throws Exception {
    CustomUserDetails userDetails = new CustomUserDetails("John","Smith", "abc123");
    assertNotNull(userDetails);
    MvcResult result = mockMvc.perform(
      get("/somepath").with(user(userDetails)))    
      .andExpect(status().isOk())
      .andExpect(content().contentType("text/json")));
  }
}

@Configuration
@ComponentScan(basePackageClasses = { AuthenticationConfig.class })
public class RestControllerITConfig {
}

@Configuration
@EnableWebSecurity
@ComponentScan("com.my.authentication.package")
public class AuthenticationConfig extends WebSecurityConfigurerAdapter {
  // snip
}

@Target({ ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal
public @interface MyUser {
}

@RestController
@RequestMapping("/somepath")
public class Controller {

  @RequestMapping(value = "", method = RequestMethod.GET)
  public ResponseEntity<Object> getSomePath(@MyUser CustomUserDetails customUser) {
    customUser.getName(); // <== Causes NPE
  }
}

为了简洁起见,还省略了其他一些不相关的配置。我真的不明白为什么我在测试中显式创建的自定义UserDetails对象没有传递到我的REST控制器中,而是传递了一个null对象。我做错了什么?有人有类似案例的工作实例吗?非常感谢。

共有2个答案

巴洲
2023-03-14

如果将Spring 5与自定义用户详细信息实现一起使用,则可以轻松使用@WithUserDetails注释

例如

@Test
@WithUserDetails
void createInstitution

您可以在Spring Security文档Spring Security文档中找到详细信息

裴金鑫
2023-03-14

通过将AuthenticationConfig的过滤器显式添加StandaloneMockMvcBuilder,我终于能够实现这一点。所以我的设置现在看起来像:

private MockMvc mockMvc;
@Autowired
private MyController controller;
@Autowired
private AuthenticationConfig authConfig;

@Before
public void setUp() {
  mockMvc = standaloneSetup(controller)
              .setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver())
              .addFilters(authConfig.getCustomFilter())
              .build();
}
 类似资料:
  • 我试图测试我的一个控制器,它返回给我一个get方法上的对象列表,以填充我页面上的下拉列表。 我试图使用MockMvc和Hamcrest编写一个JUnit测试来测试相同的内容。 我想比较对象列表,并测试它是否失败。 这就是我获取模型属性的方式: 提前谢了。

  • 我试图使用mockmvcbuilders.standalonesetup方法为一个spring mvc rest控制器创建一个非常基本的单元测试。我一直收到一个404错误。下面列出了测试应用程序上下文、测试类、控制器和整个堆栈跟踪。欢迎任何指导。 java.lang.AssertionError:状态应为:<200>但实际为:<404>在org.springframework.test.util.

  • 我试图向RepositoryRestResource中自动生成的endpoint添加一些额外的业务逻辑。请参见下面的代码: 资源: 控制器: 我看过下面两篇stackoverflow的文章: 我可以让自定义控制器镜像Spring-Data-Rest / Spring-Hateoas生成的类的格式吗? 在自定义控制器方法的 Spring Boot 中启用 HAL 序列化 我觉得我很接近了,但我面临的

  • 我有一个POJO类患者,具有以下特征: 现在从我的Rest控制器中,我只需要在json中发送患者的姓名、电话号码、电子邮件和地址。我希望json输出为 此处仅将检查成功/失败添加为标志。

  • 问题内容: 我正在使用spring 3.2.0和junit 4 这是我需要测试的控制器方法 spring-servlet config is: This is my test class : 如何使用MockMvc测试此方法? 问题答案: 你可以使用以下注释来使用应用程序调度程序servlet xml。以下示例使用路径/ mysessiontest设置了一些会话属性并期望返回某个视图来命中控制器:

  • 我有一个运行简单REST服务Spring Boot应用程序。我想测试一下这项服务。因为我喜欢Spock框架,所以我很愿意在这里使用它,但是我不能通过Spring配置的问题。 日志 例外情况