Java 在Spring中模拟用户
我想写一个简单的测试,但我的SecurityConfig让我总是拒绝访问。这是我的配置:Java 在Spring中模拟用户,java,spring,unit-testing,mockmvc,Java,Spring,Unit Testing,Mockmvc,我想写一个简单的测试,但我的SecurityConfig让我总是拒绝访问。这是我的配置: @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Override protected void configure(HttpSec
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new TokenAuthenticationFilter(userService), AnonymousAuthenticationFilter.class);
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
//Options preflight
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();
//ACL
http.authorizeRequests().antMatchers(HttpMethod.POST, "/auth/password").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers("/auth/**").anonymous();
//Tags
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags/recommendation").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.POST, "/tags").hasAnyRole("ADMIN", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags/recommendation/random").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.PUT, "/tags").hasAnyRole("ADMIN");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags/notapproved").hasAnyRole("ADMIN");
http.authorizeRequests().antMatchers(HttpMethod.PUT, "/tags/approve/{id}").hasAnyRole("ADMIN");
}
和AuthenticationFilter:
public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private UserService userService;
public TokenAuthenticationFilter(UserService userService) {
super("/");
this.userService = userService;
}
private final String HEADER_SECURITY_TOKEN = "Authorization";
private final String PARAMETER_SECURITY_TOKEN = "access_token";
private String token = "";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
this.token = request.getHeader(HEADER_SECURITY_TOKEN);
if ("".equals(this.token) || this.token == null) {
this.token = request.getParameter(PARAMETER_SECURITY_TOKEN);
}
//Attempt to authenticate
Authentication authResult;
authResult = attemptAuthentication(request, response);
if (authResult == null) {
chain.doFilter(request, response);
} else {
successfulAuthentication(request, response, chain, authResult);
}
}
/**
* Attempt to authenticate request - basically just pass over to another
* method to authenticate request headers
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
Authentication userAuthenticationToken = authUserByToken();
if (userAuthenticationToken == null) {
//throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
}
return userAuthenticationToken;
}
/**
* authenticate the user based on token, mobile app secret & user agent
*
* @return
*/
private Authentication authUserByToken() {
Authentication securityToken = null;
try {
User user = userService.findUserByAccessToken(this.token);
securityToken = new PreAuthenticatedAuthenticationToken(
user, null, user.getAuthorities());
} catch (Exception e) {
logger.error("Authenticate user by token error: ", e);
}
return securityToken;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(authResult);
chain.doFilter(request, response);
}
简单的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/test/test-servlet.xml"})
@WebAppConfiguration
public class TagControllerTest {
private MockMvc mockMvc;
private TagService tagServiceMock;
@Autowired
private FilterChainProxy springSecurityFilterChain;
@Resource
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
tagServiceMock = mock(TagService.class);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext)
.addFilters(this.springSecurityFilterChain)
.build();
}
public TagControllerTest() {
}
/**
* Test of getAllTags method, of class TagController.
*/
@Test
public void testGetAllTags() throws Exception {
List<Tags> tagsList = new ArrayList<>();
tagsList.add(new Tags((long) 1, "test", 2, 1));
tagsList.add(new Tags((long) 2, "test2", 4, 0));
User user = TestUtil.EMPTY_USER;
String query = "";
String notIncluded = "";
Integer limit = 8;
Integer start = 0;
Language language = new Language(0);
Boolean approved = false;
when(tagServiceMock.findTagsByQuery(user, query, limit, start, language, approved)).thenReturn(tagsList);
when(tagServiceMock.findTags(user, limit, start, language)).thenReturn(tagsList);
SecurityContextHolder.getContext().setAuthentication(TestUtil.getPrincipal("ROLE_ADMIN"));
mockMvc.perform(get("/tags").with(securityContext(SecurityContextHolder.getContext())).header("host", "localhost:80"))
.andExpect(status().isOk())
.andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[1].id", is(2)))
.andExpect(jsonPath("$[0].label", is("test")))
.andExpect(jsonPath("$[1].label", is("test2")))
.andExpect(jsonPath("$[0].count", is(2)))
.andExpect(jsonPath("$[1].count", is(4)))
.andExpect(jsonPath("$[0].approved", is(1)))
.andExpect(jsonPath("$[1].approved", is(0)));
verify(tagServiceMock, times(1)).findTagsByQuery(user, query, limit, start, language, approved);
verifyNoMoreInteractions(tagServiceMock);
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“classpath*:spring/test/testservlet.xml”})
@WebAppConfiguration
公共类TagControllerTest{
私有MockMvc-MockMvc;
私有标记服务标记服务模拟;
@自动连线
私有过滤链Proxy springSecurityFilterChain;
@资源
私有WebApplicationContext WebApplicationContext;
@以前
公共作废设置(){
tagServiceMock=mock(TagService.class);
this.mockMvc=MockMvcBuilders.webAppContextSetup(this.webApplicationContext)
.addFilters(此.springSecurityFilterChain)
.build();
}
公共标记控制器测试(){
}
/**
*测试TagController类的getAllTags方法。
*/
@试验
public void testGetAllTags()引发异常{
List tagsList=new ArrayList();
添加(新标签((长)1,“测试”,2,1));
添加(新标签((长)2,“test2”,4,0));
User User=TestUtil.EMPTY\u User;
字符串查询=”;
字符串notinclude=“”;
整数极限=8;
整数起始=0;
语言=新语言(0);
布尔批准=假;
当(tagServiceMock.findTagsByQuery(用户、查询、限制、开始、语言、批准)),然后返回(tagsList);
当(tagServiceMock.findTags(用户、限制、开始、语言)),然后返回(tagsList);
SecurityContextHolder.getContext().setAuthentication(TestUtil.getPrincipal(“角色\管理”));
mockMvc.perform(get(“/tags”).with(securityContext(SecurityContextHolder.getContext()).header(“主机”,“本地主机:80”))
.andExpect(状态().isOk())
.andExpect(content().contentType(TestUtil.APPLICATION\u JSON\u UTF8))
.andExpect(jsonPath(“$”,hasSize(2)))
.andExpect(jsonPath(“$[0].id”,是(1)))
.andExpect(jsonPath(“$[1].id”,是(2)))
.andExpect(jsonPath(“$[0].label”),是(“测试”))
.andExpect(jsonPath(“$[1].label”)是(“test2”))
.andExpect(jsonPath(“$[0].count”)是(2)))
.andExpect(jsonPath(“$[1].count”)是(4)))
.andExpect(jsonPath(“$[0].approved”)是(1)))
.andExpect(jsonPath(“$[1].approved”)是(0));
验证(tagServiceMock,次(1))。findTagsByQuery(用户、查询、限制、开始、语言、已批准);
验证Nomore交互(tagServiceMock);
}
问题是,我总是得到403->拒绝访问。这是因为TokenAuthenticationFilter。如果我使用正确的accesstoken设置了名为“Authorization”的头(正确的意思是实际用户使用的)然后它就可以工作了。但是我想这不是单元测试应该做的。那么该怎么做呢?如何设置角色并通过SecurityFilter?如果您没有进行集成测试,那么您应该关闭Spring安全性以进行测试,而集成测试应该包括它