我刚刚发现了新的Spring Security 4测试注释@WithMockUser
,但我不能让它适用于我的Selenium测试。
问题是,这个注释创建了一个模拟SecurityContext
,但HttpSessionSecurityContextRepository
创建了一个新的注释,因为Selenium基于真实的浏览器运行测试。
我可以告诉Spring使用模拟SecurityContext
作为下一个会话安全上下文吗?
谢谢!
答案 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安全性相对较新,因此欢迎对此解决方案发表任何评论。我不确定这个解决方案是多么“好”或“坏”。
要记住的一件事是,这是在安全环境中进行本地测试或测试的解决方案,而不是您在开发环境中需要的解决方案。