用于Selenium测试的Spring Security @WithMockUser

时间:2015-05-04 16:12:26

标签: java selenium spring-security

我刚刚发现了新的Spring Security 4测试注释@WithMockUser,但我不能让它适用于我的Selenium测试。 问题是,这个注释创建了一个模拟SecurityContext,但HttpSessionSecurityContextRepository创建了一个新的注释,因为Selenium基于真实的浏览器运行测试。 我可以告诉Spring使用模拟SecurityContext作为下一个会话安全上下文吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

我找到了在测试类路径中使用新过滤器验证模拟用户的方法:

// MARK: Actions

extension ViewController {

    @IBAction func moveLabel(gesture:UIPanGestureRecognizer)  {

        if let labelBeingMoved = labelBeingMoved {
            labelBeingMoved.center = gesture.locationInView(labelContainer)
        }
    }

}


// MARK: UIGestureRecognizerDelegate

extension ViewController : UIGestureRecognizerDelegate {


    func gestureRecognizerShouldBegin(gesture: UIGestureRecognizer) -> Bool {

        let location = gesture.locationInView(labelContainer)



        //You'll have to change this to account for labels on top of one another
        for label in labels {
            if label.frame.contains(location) {
                labelBeingMoved = label
                labelContainer.bringSubviewToFront(labelBeingMoved!)
                return true
            }

        }
        return false
    }


}

它的灵感来自@Component public class MockUserFilter extends GenericFilterBean { @Autowired private UserDetailsService userDetailsService; private SecurityContext securityContext; @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; if (securityContext != null) { SecurityContextRepository securityContextRepository = WebTestUtils.getSecurityContextRepository(request); HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response); securityContextRepository.loadContext(requestResponseHolder); request = requestResponseHolder.getRequest(); response = requestResponseHolder.getResponse(); securityContextRepository.saveContext(securityContext, request, response); securityContext = null; } chain.doFilter(request, response); } public void authenticateNextRequestAs(String username) { UserDetails principal = userDetailsService.loadUserByUsername(username); Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities()); securityContext = SecurityContextHolder.createEmptyContext(); securityContext.setAuthentication(authentication); } } SecurityMockMvcRequestPostProcessors

我无法使用WithUserDetailsSecurityContextFactory注释,因为我运行了Cucumber测试,但是使用此过滤器,我可以在一行中模拟下一个请求的身份验证:@WithUserDetails

答案 1 :(得分:0)

我正在添加这个答案,因为虽然接受的答案帮助我形成了一个解决方案,但我不得不做出一些改变才能让它发挥作用。这个答案也帮助我实现了它:https://stackoverflow.com/a/8336233/2688076

这是我的MockUserFilter:

        @Component("MockUserFilter")
        public class MockUserFilter extends GenericFilterBean {
            @Autowired
            private UserDetailService userDetailService;

            private SecurityContext securityContext;

            @Autowired
            private AuthenticationProvider authenticationProvider;

            public void setUserDetailService(UserDetailService userDetailService) {
                this.userDetailService = userDetailService;
            }
            @Override
            public void doFilter(ServletRequest request, ServletResponse response,
                    FilterChain chain) throws IOException, ServletException {
                HttpServletRequest servletRequest = (HttpServletRequest) request;
                HttpServletResponse servletResponse = (HttpServletResponse) response;

                if (securityContext != null) {
                    SecurityContextRepository securityContextRepository = WebTestUtils.getSecurityContextRepository(servletRequest);
                    HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(servletRequest, servletResponse);
                    securityContextRepository.loadContext(requestResponseHolder);
                    servletRequest = requestResponseHolder.getRequest();
                    servletResponse = requestResponseHolder.getResponse();
                    securityContextRepository.saveContext(securityContext, servletRequest, servletResponse);
                    securityContext = null;
                }

                chain.doFilter(request, response);
            }

             public void authenticateNextRequestAs(String username, ServletRequest request) {
                 UserDetails principal = userDetailService.loadUserByUsername(username);
                 Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
                 securityContext = SecurityContextHolder.createEmptyContext();
                 securityContext.setAuthentication(authentication);
                 SecurityContextHolder.getContext().setAuthentication(authentication);

                 HttpSession session = ((HttpServletRequest) request).getSession(true);
                 session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
            }
        }

除此之外,我还必须从过滤器链中删除我的casAuthenticationFilter才能使其正常工作。我使用属性值来启用/禁用它。

我对Spring和Spring安全性相对较新,因此欢迎对此解决方案发表任何评论。我不确定这个解决方案是多么“好”或“坏”。

要记住的一件事是,这是在安全环境中进行本地测试或测试的解决方案,而不是您在开发环境中需要的解决方案。