2016-09-10 1 views
2

Я хочу написать простой тест, но мой SecurityConfig дает мне всегда доступ запрещен. Вот мой конфиг:Откупоривание пользователя весной

@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); 

    } 

Проблема заключается в том, что я всегда получаю 403 -> Access Denied. Это из-за TokenAuthenticationFilter. Если я устанавливаю заголовок с именем «Авторизация» с правильной подпиской (правильно означает, что это используется фактическим пользователем), тогда он работает. Но я думаю, это не то, как это должно быть для модульных тестов. Так что делать? Как установить роль и передать SecurityFilter?

ответ

1

Вы должны отключить весеннюю безопасность для целей испытаний, если вы не проводите интеграционные тесты, которые должны включать его.