当我使用 servletRequest.getReader().lines().collect(Collectors.joining()) 时请求更改正文
Posted
技术标签:
【中文标题】当我使用 servletRequest.getReader().lines().collect(Collectors.joining()) 时请求更改正文【英文标题】:Request body change when I Use servletRequest.getReader().lines().collect(Collectors.joining()) 【发布时间】:2022-01-16 02:35:49 【问题描述】:我在java、jwt、spring security中做一个私有api,第一次进来请求一个json对象。
user: xxx
password: yyy
API 在正文中返回一个jwt token
。
其他人称令牌进入正文 json 并验证它我使用这个:
sbody = servletRequest.getReader().lines().collect(Collectors.joining());
要获取字段令牌并正常,但随后过滤器会显示消息:
"Required request body is missing: public org.springframework.http.ResponseEntity"
这是我的 api:
@SpringBootApplication
public class JwtApplication
public static void main(String[] args)
SpringApplication.run(JwtApplication.class, args);
@EnableWebSecurity
@Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.addFilterAfter(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests().antMatchers(HttpMethod.POST, "/user").permitAll()
.antMatchers(HttpMethod.POST, "/Autenticacion").permitAll().anyRequest().authenticated();
这是过滤器:
public class JWTAuthorizationFilter extends OncePerRequestFilter
private final String HEADER = "Authorization";
private final String SESSION = "sesion";
private final String PREFIX = "Bearer ";
private final String SECRET = "mySecretKey";
public static final long EXPIRATION_TIME = 900_000; // 15 mins
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try
boolean resultado_checktoken = checkJWTToken(httpRequest, httpResponse);
if (resultado_checktoken)
Claims claims = validateToken(request);
if (claims.get("authorities") != null)
setUpSpringAuthentication(claims);
else
SecurityContextHolder.clearContext();
else
SecurityContextHolder.clearContext();
chain.doFilter(request, response);
catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException e)
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
return;
System.out.println("supuestamente no hubo problemas");
private Claims validateToken(HttpServletRequest request)
//String jwtToken = request.getHeader(HEADER).replace(PREFIX, "");
String jwtToken="";
try
jwtToken = this.getBodySession(request);
catch (IOException e)
e.printStackTrace();
;
return Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(jwtToken).getBody();
/**
* Authentication method in Spring flow
*
* @param claims
*/
private void setUpSpringAuthentication(Claims claims)
@SuppressWarnings("unchecked")
List<String> authorities = (List<String>) claims.get("authorities");
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(claims.getSubject(), null,
authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
SecurityContextHolder.getContext().setAuthentication(auth);
private boolean checkJWTToken(HttpServletRequest request, HttpServletResponse res) throws IOException
String authenticationHeader = "";
authenticationHeader = this.getBodySession(request);
if (authenticationHeader == null || !authenticationHeader.startsWith(PREFIX))
return false;
return true;
public String getBodySession(HttpServletRequest request) throws IOException
String sbody = "";
HttpServletRequest servletRequest = new ContentCachingRequestWrapper(request);
//servletRequest.getParameterMap();
sbody = servletRequest.getReader().lines().collect(Collectors.joining());
String Field = SESSION;
String scampo = "";
if (sbody.contains(Field))
scampo = sbody.substring(sbody.indexOf(Field), sbody.indexOf("\n", sbody.indexOf(Field)))
.replace(Field + "\": \"", "").replace("\"", "").replace(",", "");
System.out.println("sbody: " + sbody + " sesion: " + scampo);
return scampo;
【问题讨论】:
所有这些都是自定义安全性,这是不好的做法。当所有这些都已经存在于 Spring Security 中时,为什么要编写自定义 jwtfilter。 jwtfilter 中已经有一个可以自定义的构建。删除整个过滤器并阅读 spring 安全文档中关于 jwts 的章节。投反对票。 谢谢,我是 Spring Boot 新手,但我也需要生成安全令牌,而且我正在使用 JWT。 如果你是新手,那么你应该阅读官方的 spring 安全文档章节,了解如何实现 jwts 的处理,然后再发布堆栈溢出。 【参考方案1】:这需要明确地返回一个布尔值,你不能有两个返回语句。
private boolean checkJWTToken(HttpServletRequest request, HttpServletResponse res) throws IOException
String authenticationHeader = "";
authenticationHeader = this.getBodySession(request);
if (authenticationHeader == null || !authenticationHeader.startsWith(PREFIX))
**return false;**
**return true;**
【讨论】:
谢谢,我解决了以上是关于当我使用 servletRequest.getReader().lines().collect(Collectors.joining()) 时请求更改正文的主要内容,如果未能解决你的问题,请参考以下文章
为啥在我的 c 程序中,当我使用 double 时它只输出 0,但是当我使用 float 时它可以工作? [复制]
当我访问我的 iframe 时,当我使用 selenium 时,#document 不显示
当我在 ngOnInit() 中使用 router.getCurrentNavigation() 时,它会给我类型错误,但是当我在构造函数中使用它时,它工作正常,为啥?
当我不知道 data.frame 中的列名时,当我使用 dplyr mutate 函数时