当前位置: 首页 > 面试题库 >

Spring MockMVC,Spring安全性和Mockito

金飞
2023-03-14
问题内容

我想测试一个Spring BootRest控制器,该控制器使用进行保护Spring security,并在其中使用模拟程序。我已经尝试过Mockito,但我认为任何模拟工具都可以解决问题。

为了在测试中启用Spring安全性,我首先做了如下工作:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{

    protected MockMvc mockMvc;

    @Autowired
    private WebApplicationContext wac;

    @Before
    public void setUp(){
        mockMvc = MockMvcBuilders
                .webAppContextSetup(wac)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();
    }

    @Test
    public void doTheTest(){
        mockMvc.perform(post("/user/register")
            .with(SecurityMockMvcRequestPostProcessors.csrf())
            .content(someContent()));
    }
}

到那为止,它运作良好。

完成此步骤后,我希望添加模拟以隔离测试我的安全控制器。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{

    protected MockMvc mockMvc;

    @Mock
    private Myservice serviceInjectedInController;

    @InjectMocks
    private MyController myController;

    @Autowired
    private WebApplicationContext wac;

    @Before
    public void setUp(){
        mockMvc = MockMvcBuilders
                .webAppContextSetup(wac)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();
    }

    @Test
    public void doTheTest(){
        mockMvc.perform(post("/user/register")
            .with(SecurityMockMvcRequestPostProcessors.csrf())
            .content(someContent()));
    }
}

不幸的是,模拟服务没有注入到控制器中,因为MockMVC和Mocks没有任何关系,因此模拟没有注入到控制器中。

因此,我尝试如下更改MockMVC的配置:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{

    protected MockMvc mockMvc;

    @Mock
    private Myservice serviceInjectedInController;

    @InjectMocks
    private MyController myController;


    @Before
    public void setUp(){
        mockMvc = MockMvcBuilders
                .standAloneSetup(myController)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();
    }

    @Test
    public void doTheTest(){
        mockMvc.perform(post("/user/register")
            .with(SecurityMockMvcRequestPostProcessors.csrf())
            .content(someContent()));
    }
}

但是在这种情况下,我还有另一个问题。Spring Security抱怨配置:

java.lang.IllegalStateException: springSecurityFilterChain cannot be null. Ensure a Bean with the name springSecurityFilterChain implementing Filter is present or inject the Filter to be used.

我没有其他想法可以进行安全性和嘲弄。任何的想法?还是我应该采取其他方式?

谢谢。


问题答案:

默认情况下,集成会查找名称为“
springSecurityFilterChain”的bean。在提供的示例中,使用的是独立安装程序,这意味着MockMvc将不会WebApplicationContext在测试中知道所提供的内容,因此将无法查找“
springSecurityFilterChain” bean。

解决此问题的最简单方法是使用如下代码

    MockMvc mockMvc = MockMvcBuilders
            // replace standaloneSetup with line below
            .webAppContextSetup(wac)
            .alwaysDo(print())
            .apply(SecurityMockMvcConfigurers.springSecurity())
            .build();

如果您真的想使用standaloneSetup(因为已经有了WebApplicationContext并没有什么意义),则可以使用以下命令显式提供springSecurityFilterChain:

@Autowired
FilterChainProxy springSecurityFilterChain;

@Before
public void startMocks(){
    controller = wac.getBean(RecipesController.class);

    MockMvc mockMvc = MockMvcBuilders
            .standaloneSetup(controller)
            .alwaysDo(print())
            .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
            .build();

    MockitoAnnotations.initMocks(this);
}


 类似资料:
  • 当我使用security.basic.enabled=false在具有以下依赖项的Spring Boot项目上禁用安全性时: 为了修复此异常,我必须添加属性-management.security.enabled=false。我的理解是,当执行器在类路径中时,应该将security.basic.enabled=false和management.security.enabled=false设置为禁用

  • 你好,我是Spring和Spring保安新来的。目前我正在Spring开发rest api。根据spring提供rest API。rest api是无状态的,所以我们不能创建到rest api的会话。因为它是一个无状态的,如果我们这样做,那么它是违反rest设计的。所以我的问题是,在REST中,我们是不是可以永远保持服务器端用户的状态?我们可以维护它的客户端吗??怎么做??在spring basi

  • 问题内容: 我正在使用ResponseEntityExceptionHandler全局处理错误,并且几乎可以正常工作,只是我想用spring处理错误的请求。通过任何逻辑,handleNoSuchRequestHandlingMethod都应处理此问题,但是总是要进行处理 HTTP Status 404 - type Status report message description The req

  • 我得到了一个Spring Boot2Reactive Web应用程序,它目前有一个基于JWT的身份验证系统。现在,我想添加一个LDAP后端用于身份验证,并通过Kerberos允许单点登录(SSO)。 似乎Kerberos和LDAP支持目前仅限于webmvc,没有专用的反应版本可用。 由于关于将所有3个组件(WebFlux,LDAP+Kerberos)集成到一个应用程序中的文档非常少,我想问一下是否

  • 我有一个auth-cas库,它为我的spring boot项目提供身份验证。在这个auth-cas库中,有一个类扩展并使用以下配置函数 由于这应该是黑框,所以我添加了自己的,如下所示: 我的自定义AuthenticationProvider实现了“AuthenticationProvider”,并在页面中工作,将我重定向到/login页面,我可以使用用户库中的凭据登录。唯一的问题是,当我已经登录到

  • 问题内容: 如果我有一个下面定义的Java类,则通过依赖项注入将其插入我的Web应用程序中: 我担心线程安全。Spring框架是否不能处理一个请求正在从列表中读取而当前正在被另一个请求更新的情况?我以前在其他应用程序中使用过读/写锁,但是我之前从未考虑过这种情况。 我打算将bean作为单例使用,以便减少数据库负载。 顺便说一下,这是以下问题的跟进: Java内存存储以减少数据库负载-安全吗? 编辑

  • 我正在用Spring-boot(在http://localhost:8080上)和angular(在http://localhost:80上)构建一个应用程序。 如果我输入了正确的密码,http响应代码(我可以在Chrome控制台中看到)是,但我仍然到达块(带有error.status=-1),并且我可以在控制台中看到以下错误消息: XMLHttpRequest无法加载http://localho

  • 1.远程执行命令 1.1 危险命令检测. gossh将危险的命令放到黑名单中,一旦远程执行危险命令,会自动退出,通过指定-f参数强制执行。危险命令目前收录如下: "mount", "umount", "rm", "mkfs", "mkfs.ext3", "make.ext2", "make.ext4", "make2fs", "shutdown", "reboot", "init", "dd"