Junit没有在UsernameNotFoundException上调用@ControllerAdvice

时间:2014-09-21 17:13:41

标签: json spring exception junit spring-security

我正在为我的Rest应用程序编写集成测试。我写了一个测试来检查accesDenied,它引发了一个UsernameNotFoundException,它应该,但它不会跟随返回JSON的@ControllerAdvice类的异常。

代码在执行时正常工作,返回Json,在其他测试用例中,例如AuthenticationFailed - whcih也由异常处理 - ,Json返回运行测试。在这种情况下json不返回,可能是因为我有一个自定义UserDetailsS​​ervice?

我已经在互联网上看过,其他人只是测试是否有异常,并致电当天。然而,我喜欢测试返回与执行相同的行为--Json。可能吗?我错过了什么?

我尝试过类似的问题'答案,但他们没有工作,返回相同的行为。

非常感谢任何帮助。 Thx提前, 阿方索

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
@WebAppConfiguration
public class SecurityIntegrationTest {

    private final String SECURED_URI = "/users/1";
    private final String LOGIN_URI = "/login";

    @Autowired
    private WebApplicationContext wac;

    @Autowired
    private FilterChainProxy springSecurityFilter;

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    UserController userController;

    private MockMvc mockMvc;

    @Before
    public void setup() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
        .addFilters(springSecurityFilter).alwaysDo(print()).build();
    }

    @Test
    public void requiresAuthentication() throws Exception {
    mockMvc.perform(
        get(SECURED_URI).contentType(
            MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(status().isUnauthorized())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(Jsons.AUTHENTICATION_REQUIRED));
    }

    @Test
    public void authenticationFailed() throws Exception {
    mockMvc.perform(formLogin())
        .andExpect(status().isUnauthorized())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(Jsons.AUTHENTICATION_FAILED));
    }

    @Test
    public void authenticationSuccess() throws Exception {
    mockMvc.perform(formLogin().user("Ikos").password("Ikos"))
        .andExpect(status().isOk())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(
            content().string(
                String.format(Jsons.LOGIN, "Ikos", "Ikos")));
    }

    @Test
    public void accessGranted() throws Exception {
    UserDetails user = customUserDetailsService.loadUserByUsername("Ikos");

    mockMvc.perform(
        get(SECURED_URI).with(user(user)).contentType(
            MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(status().isOk())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(RestDataFixture.defaultUserJSON()));
    }

    @Test
    public void accessDenied() throws Exception {
    UserDetails user = customUserDetailsService.loadUserByUsername("Pedro");

    mockMvc.perform(
        get(SECURED_URI).with(user(user)).contentType(
            MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(status().isUnauthorized())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(Jsons.AUTHENTICATION_REQUIRED));
    }
}

@Configuration
@ComponentScan(basePackages = { "es.aekia.rest" })
@EnableWebMvc
public class TestConfig {
}

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    User user;
    try {
        user = userDao.findByAlias(username);
        if (user == null)
        throw new UsernameNotFoundException("user name not found");

    } catch (DataAccessException e) {
        throw new UsernameNotFoundException("database error");
    }

    return buildUserFromUserEntity(user);
    }

    private UserDetails buildUserFromUserEntity(User userEntity) {
    // convert model user to spring security user
    String username = userEntity.getAlias();
    String password = userEntity.getPassword();

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"
        + userEntity.getRole());
    authorities.add(authority);

    UserDetails springUser = new org.springframework.security.core.userdetails.User(
        username, password, authorities);
    return springUser;
    }
}

@ControllerAdvice
public class ExceptionController {

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler({ MissingServletRequestParameterException.class,
        UnsatisfiedServletRequestParameterException.class,
        HttpRequestMethodNotSupportedException.class,
        ServletRequestBindingException.class,
        MethodArgumentNotValidException.class })
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public @ResponseBody Map<String, Object> handleRequestException(Exception ex) {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.REQUEST_ERROR);
    map.put(Constants.CAUSE, ex.getMessage());
    return map;
    }

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    @ResponseStatus(value = HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public @ResponseBody Map<String, Object> handleUnsupportedMediaTypeException(
        HttpMediaTypeNotSupportedException ex) throws IOException {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.UNSUPPORTED_MEDIA_TYPE);
    map.put(Constants.CAUSE, ex.getLocalizedMessage());
    map.put(Constants.SUPPORTED, ex.getSupportedMediaTypes());
    return map;
    }

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler({ AccessDeniedException.class,
        UsernameNotFoundException.class })
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    public @ResponseBody Map<String, Object> handleAccesDeniedException(
        Exception ex) {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.ACCESS_DENIED);
    map.put(Constants.CAUSE, ex.getMessage());
    return map;
    }

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler(Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public @ResponseBody Map<String, Object> handleUncaughtException(
        Exception ex) throws IOException {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.UNKNOWN_ERROR);
    if (ex.getCause() != null) {
        map.put(Constants.CAUSE, ex.getCause().getMessage());
    } else {
        map.put(Constants.CAUSE, ex.getMessage());
    }
    return map;
    }

}

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
    @Autowired
    private RestAccessDeniedHandler restAccessDeniedHandler;

    @Autowired
    private RestAuthSuccessHandler restAuthSuccessHandler;
    @Autowired
    private RestAuthFailureHandler restAuthFailureHandler;
    @Autowired
    private RestLogoutSuccessHandler restLogoutSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.csrf()
        .disable()
        /*
         * .authenticationProvider(authenticationProvider())
         */
        .exceptionHandling()
        .authenticationEntryPoint(restAuthenticationEntryPoint)
        .accessDeniedHandler(restAccessDeniedHandler)
        .and()
        .formLogin()
        .permitAll()
        .loginProcessingUrl("/login")
        // .usernameParameter(USERNAME)
        // .passwordParameter(PASSWORD)
        .successHandler(restAuthSuccessHandler)
        .failureHandler(restAuthFailureHandler).and()
        .logout()
        .permitAll()
        // .logoutRequestMatcher(new AntPathRequestMatcher(LOGIN_PATH,
        // "DELETE"))
        .logoutSuccessHandler(restLogoutSuccessHandler).and()
        .sessionManagement().maximumSessions(1);

    // .logoutSuccessUrl("/logout").and()
    /*
     * .sessionManagement() .sessionCreationPolicy (SessionCreationPolicy
     * .STATELESS).and()
     */

    //
    http.authorizeRequests().antMatchers(HttpMethod.POST, "/login")
        .permitAll().antMatchers(HttpMethod.POST, "/logout")
        .authenticated().antMatchers(HttpMethod.GET, "/users")
        .permitAll().antMatchers(HttpMethod.GET, "/users/**")
        .hasAnyRole("USER", "ADMIN")
        .antMatchers(HttpMethod.POST, "/**").hasRole("ADMIN")
        .antMatchers(HttpMethod.PUT, "/**").hasRole("ADMIN")
        .antMatchers(HttpMethod.PATCH, "/**").hasRole("ADMIN")
        .antMatchers(HttpMethod.DELETE, "/**").hasRole("ADMIN");
    // .anyRequest().anonymous();
    }
}

0 个答案:

没有答案