本文介绍了如何在Spring MVC中模拟安全上下文以进行测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要测试一些受保护的url,因此需要在测试(junit)中设置一个模拟安全上下文.
特别是,我需要使用经过身份验证的用户执行一些获取操作并将其发布到我的Web应用程序中.在下面的代码中,我能够创建这样的安全上下文,但是需要将其注入"MockMvc"对象中.
我在安全上下文中设置了身份验证对象,并且可以正常工作,"SecurityContextHolder.getContext().getAuthentication().getPrincipal()"的输出结果为[email protected],但是当我在/profile上调用GET时,出现断言错误,因为我被重定向到我的登录页面,而不是/profile.

I need to test some protected urls, therefore I need to set up a mock security context in my tests (junit).
In particular I need perform some gets and post against my web application, using an authenticated user.Below there is my code, I am able to create a such security context but I need to inject it in the 'MockMvc' object.
I set the authentication object in the security context and it works, the output result of 'SecurityContextHolder.getContext().getAuthentication().getPrincipal()' is [email protected] but when I call the GET on /profile I have an assertion error because I am redirected to my login page, and not to /profile.

@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:spring/security.xml", "classpath:spring/view.xml"})
@ActiveProfiles("default")
@RunWith(SpringJUnit4ClassRunner.class)
public class AuthenticationTest {

@Autowired
WebApplicationContext ctx;

private MockMvc mockMvc;

@Autowired
private FilterChainProxy springSecurityFilterChain;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
}

@Before
public void setUp() throws Exception {
    mockMvc = MockMvcBuilders.webAppContextSetup(ctx).addFilters(springSecurityFilterChain).build();

    //@formatter:off

    UserDetailsLogic userDetailsLogic = null;
    userDetailsLogic = ctx.getBean(UserDetailsLogic.class);
    final UserDetailsImp userDetailsImp = new UserDetailsImp();
    userDetailsImp.setAccountId(1001);
    userDetailsImp.setUserId(8001);
    userDetailsImp.setPassword("a378c92df7531df6fdf351f7ae1713f91f2dd2d45b9c6e1a8b02736ee3afec6595ff60465e9cb8da");
    userDetailsImp.setUsername("[email protected]");
    userDetailsImp.setEmail("[email protected]");

    final Collection<GrantedAuthorityImplementation> authorities= new ArrayList<GrantedAuthorityImplementation>();
    authorities.add(new GrantedAuthorityImplementation("ROLE_USER"));

    userDetailsImp.setAuthorities(authorities);

    userDetailsImp.setAccountNonExpired(true);
    userDetailsImp.setAccountNonLocked(true);
    userDetailsImp.setCredentialsNonExpired(true);
    userDetailsImp.setEnabled(true);

    final Authentication authToken = new UsernamePasswordAuthenticationToken (userDetailsImp.getUsername(), userDetailsImp.getPassword(), userDetailsImp.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authToken);

    System.out.println("principal:"+SecurityContextHolder.getContext().getAuthentication().getPrincipal());
    mockMvc.perform(get("/profile").principal(authToken)

            .contentType(MediaType.TEXT_HTML)

            .accept(MediaType.TEXT_HTML))

            .andDo(print())

            .andExpect(status().isOk())
            .andExpect(redirectedUrl(null))
            .andExpect(forwardedUrl(null));
    //@formatter:on
}

我想我应该将身份验证对象放在MockMvc对象中,但是我不知道如何
有人知道吗?

I guess that I should put my authentication object inside the MockMvc object, but I do not know how
Does anyone have any idea?

推荐答案

这是我几天前写的.我认为这可能会有所帮助(我针对登录表单测试了相同的内容,使用第二个请求的会话)请参见loginUser1Ok(..))

This is something I wrote few days ago. I think that could be helpful (I tested the same thing against the login form, using the session for the second request) see loginUser1Ok(..))

请参见

See MvcTest.java in

m4nuv/easy-bank .

这篇关于如何在Spring MVC中模拟安全上下文以进行测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-14 14:42