Jackson MismatchedInputException: No content to map due to end-of-input
I had the same error, had to remove ApplicationUser user = new ObjectMapper().readValue(request.getInputStream(),ApplicationUser.class);
and use request.getParameter directly:
new UsernamePasswordAuthenticationToken(
request.getParameter("username"),
request.getParameter("password"),
Collections.emptyList()
)
Comments
-
theanilpaudel over 1 year
I am trying to implement JWTAuthentication in my project. I have set up my entity like this:
@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; } }
Then I have setup the AuthenticationFilter like this:
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); } }
And this is my SecurityConfiguration as:
@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; } }
Sign up is working fine, but when I try to login using the same credentials I get the following exception:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 1, column: 0] at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59) ~[jackson-databind-2.9.6.jar:2.9.6] at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4145) ~[jackson-databind-2.9.6.jar:2.9.6] at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4000) ~[jackson-databind-2.9.6.jar:2.9.6] at 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) ~[classes/:na] ... 53 common frames omitted
I am using Postman to hit the API and there I have set application/json as the content-type and sent the username and password as post parameters. I am following this tutorial. What am I doing wrong? Any help would be appreciated.
Thanks
-
Andreas over 5 yearsDo not consume the POST content in a filter, especially not a filter that applies to all URLs. If logging in requires a POST to a specify URL with JSON content, then it should be handled by a Servlet, not a Filter. Authentication filters are for processing header values (e.g.
Authentication
), so authentication can happen on-the-fly, during the processing of any arbitrary request.
-
-
Katharina about 4 yearsHave you found out the reason for this behaviour? I'm having the same issue.
-
sanjeevRm over 2 yearsreplacing objectMapper line with request.getParameter("") worked like charm