[英]Java HttpParameters getInputStream method empty when sending the request from Angular, but works as expected when sending from Postman
My intention is to use JWT in order to generate auth token.我的意图是使用 JWT 来生成授权令牌。 Everything works as expected when I am sending email+password as json from postman, but when I am sending from Angular using HttpClient, I get the following exception:
当我从 postman 发送电子邮件+密码 json 时,一切都按预期工作,但是当我使用 HttpClient 从 Angular 发送时,出现以下异常:
Method threw 'com.fasterxml.jackson.databind.exc.MismatchedInputException' exception.方法抛出“com.fasterxml.jackson.databind.exc.MismatchedInputException”异常。 No content to map due to end-of-input
由于输入结束,map 没有内容
I also tried to replace line我也尝试更换线
creds = mapper.readValue(req.getInputStream(), UserBE.class); creds = mapper.readValue(req.getInputStream(), UserBE.class);
with:和:
String c = IOUtils.toString( req.getInputStream());字符串 c = IOUtils.toString( req.getInputStream());
This way I noticed that result is empty.这样我注意到结果是空的。 (PLEASE SEE SCREENSHOTS)
(请查看屏幕截图)
JwtAuthenticationFilter class : JwtAuthenticationFilter class :
FAILING LINE: creds = mapper.readValue(req.getInputStream(), UserBE.class);失败行: creds = mapper.readValue(req.getInputStream(), UserBE.class);
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
setFilterProcessesUrl("/user/login");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
ObjectMapper mapper = new ObjectMapper();
UserBE creds = null;
try {
creds = mapper.readValue(req.getInputStream(), UserBE.class); **THIS IS THE LINE WHERE CODE FAILS**
} catch (IOException e) {
e.printStackTrace();
}
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getEmail(),
creds.getPassword(),
new ArrayList<>())
);
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException {
String token = JWT.create()
.withSubject(((User) auth.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(Algorithm.HMAC512(SECRET.getBytes()));
String body = ((User) auth.getPrincipal()).getUsername() + " " + token;
res.getWriter().write(body);
res.getWriter().flush();
}
} }
WebSecurityConfig class:网络安全配置 class:
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().authorizeRequests()
.antMatchers("/user/create").permitAll()
.antMatchers("/user/confirm/**").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(userService).passwordEncoder(bCryptPasswordEncoder);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowCredentials(true);
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
source.registerCorsConfiguration("/**", config);
return source;
}
} }
ANGULAR HttpClient REQUEST: ANGULAR HttpClient 请求:
login(email: string, password: string): Observable<any> {
let options = {headers: new HttpHeaders().set('Content-Type', 'application/json')};
console.log({email, password});
return this.http.post<any>(this.baseUrl + "/user/login", {email, password}, options);
} }
AGAIN, this is working as expected when sending from POSTMAN, but not from Angular. Any thoughts?再一次,当从 POSTMAN 发送时,这是按预期工作的,但不是从 Angular 发送的。有什么想法吗?
SCREENSHOTS:截图:
Exception MESSAGE + EXCEPTION LINE (BLUE HIGHLIGHTED LINE)异常消息 + 异常行(蓝色高亮行)
Tried a different way .尝试了不同的方式。 Just to to convert req.getInputStream to String and see what is receiving from Angular Request.
只是为了将 req.getInputStream 转换为 String 并查看从 Angular 请求接收到的内容。 Looks Like result is empty.
看起来结果是空的。 Please also see next screenshot which is the Request from Postman (WHICH WORKES AS EXPECTED)
另请参阅下一个屏幕截图,它是来自 Postman 的请求(按预期工作)
Showing and proving that request from POSTMAN has a result显示并证明来自 POSTMAN 的请求有结果
Please note that I made researches and tried a lot of things I've found.请注意,我进行了研究并尝试了很多我发现的东西。 Nothing helped.
没有任何帮助。
Found the problem (FINALLY:), I had to add cors on HttpSecurity.发现问题(最终:),我不得不在 HttpSecurity 上添加 cors。 and change CORS configuration: So I changed followings:
并更改 CORS 配置:所以我更改了以下内容:
Added.cors() at the beginning of the expression.在表达式的开头添加了 .cors() 。 See code below:
请参阅下面的代码:
http.cors().and().csrf().disable().authorizeRequests().antMatchers("/user/create").permitAll().antMatchers("/user/confirm/**").permitAll().anyRequest().authenticated().and().addFilter(new JwtAuthenticationFilter(authenticationManager())).addFilter(new JwtAuthorizationFilter(authenticationManager())) // this disables session creation on Spring Security.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
Changed corsConfiguration Bean as following:更改 corsConfiguration Bean 如下:
CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues(); config.setAllowCredentials(true); config.setAllowedOriginPatterns(List.of("*")); source.registerCorsConfiguration("/**", config); return source;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.