Jackson MismatchedInputException: нет содержимого для сопоставления из-за конца ввода

Я пытаюсь реализовать JWTAuthentication в своем проекте. Я настроил свою сущность следующим образом:

@Entity
public class ApplicationUser {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;
    String username,password;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Затем я настроил AuthenticationFilter следующим образом:

    public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
        private AuthenticationManager authenticationManager;

        public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
            this.authenticationManager = authenticationManager;
        }

        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
            try {
                System.out.println("request "+request.getPathInfo());
                ApplicationUser user = new ObjectMapper().readValue(request.getInputStream(),ApplicationUser.class);
//this is where the exception is    
                return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),new ArrayList<>()));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
            String token = Jwts.builder()
                    .setSubject(((ApplicationUser) authResult.getPrincipal()).getUsername())
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET.getBytes())
                    .compact();
            response.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
        }
    }

И это моя конфигурация SecurityConfiguration как:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private BCryptPasswordEncoder bCryptPasswordEncoder;
    private UserDetailsService userDetailsService;

    public SecurityConfig(AppUserDetailService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder){
        this.bCryptPasswordEncoder=bCryptPasswordEncoder;
        this.userDetailsService=userDetailsService;
    }



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
//                .antMatchers(HttpMethod.POST,LOGIN_URL).permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()))
                // this disables session creation on Spring Security
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
        return source;
    }
}

Регистрация работает нормально, но когда я пытаюсь войти в систему с теми же учетными данными, я получаю следующее исключение:

Вызвано: com.fasterxml.jackson.databind.exc.MismatchedInputException: нет содержимого для сопоставления из-за окончания ввода в [Источник: (org.apache.catalina.connector.CoyoteInputStream); строка: 1, столбец: 0] в com.fasterxml.jackson.databind.exc.MismatchedInputException.from (MismatchedInputException.java:59) ~ [jackson-databind-2.9.6.jar: 2.9.6] в com.fasterxml. jackson.databind.ObjectMapper._initForReading (ObjectMapper.java:4145) ~ [jackson-databind-2.9.6.jar: 2.9.6] в com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose (ObjectMapper.java:4000) ~ [jackson-databind-2.9.6.jar: 2.9.6] в com.fasterxml.jackson.databind.ObjectMapper.readValue (ObjectMapper.java:3070) ~ [jackson-databind-2.9.6.jar: 2.9.6] at com.project.pq.security.JWTAuthenticationFilter.attemptAuthentication (JWTAuthenticationFilter.java:35) ~ [классы /: na] ... 53 общих кадра опущены

Я использую Postman для доступа к API, и там я установил application / json в качестве типа содержимого и отправил имя пользователя и пароль в качестве параметров публикации. Я следую этому руководству. Что я делаю неправильно? Любая помощь будет оценена по достоинству.

Спасибо


person theanilpaudel    schedule 15.07.2018    source источник
comment
Не используйте содержимое POST в фильтре, особенно в фильтре, который применяется ко всем URL-адресам. Если для входа в систему требуется POST для указанного URL-адреса с содержимым JSON, тогда он должен обрабатываться сервлетом, а не фильтром. Фильтры аутентификации предназначены для обработки значений заголовков (например, Authentication), поэтому аутентификация может происходить "на лету" во время обработки любого произвольного запроса.   -  person Andreas    schedule 15.07.2018


Ответы (1)


У меня была такая же ошибка, пришлось удалить ApplicationUser user = new ObjectMapper (). ReadValue (request.getInputStream (), ApplicationUser.class);

и напрямую используйте request.getParameter:

                new UsernamePasswordAuthenticationToken(
                    request.getParameter("username"),
                    request.getParameter("password"),
                    Collections.emptyList()
            )
person Mervyn Zhang    schedule 10.10.2018
comment
Вы узнали причину такого поведения? У меня такая же проблема. - person Katharina; 01.10.2019
comment
замена строки objectMapper на request.getParameter () работала как шарм - person sanjeevRm; 23.03.2021