自定义了一个过滤器过滤restapi的数据,但是在重新request 时报错!,错误信息:18:30:08.122 WARN o.s.s.o.p.endpoint.TokenEndpoint - Handling error: InvalidRequestException, Missing grant type
麻烦贴一下错误堆栈?
场景是这样,我定义了一个过滤器组件,代码如下:
利用postman 进行测试时,出现18:30:08.122 WARN o.s.s.o.p.endpoint.TokenEndpoint - Handling error: InvalidRequestException, Missing grant type的错误!
我猜可能是RequestWrapper时丢失了RestAPI需要的header信息。 检查一下wrapper前和wrapper后的header 信息是否一致
好的,我检查一下,我在修改request时,只是使用request.getInputStream()进行参数修改,应该不会涉及到header信息!
错误提示比较明显 ,确认一下header中是否传递了 grant_type
如果不重写requset.getInputStream,是没问题的!
哦, grant_type
应该是在 body 中,可能是wrapper有问题,导致取不到body或body内容变化。能贴出完整的 wrapper定义吗。
protected static class RestSecurityRequestWrapper extends HttpServletRequestWrapper {
private byte[] body; // 报文
private final Logger log = LoggerFactory.getLogger(RestSecurityRequestWrapper.class);
public RestSecurityRequestWrapper(HttpServletRequest request) throws Exception {
super(request);
//替换报文内容
body = InputStreamToByte(request.getInputStream());
String bodyStr = new String(body);
body = bodyStr.getBytes();
}
/**
* 流转 字节数组
*
* @param is
* @return
* @throws IOException
*/
private byte[] InputStreamToByte(InputStream is) throws IOException {
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int ch;
while ((ch = is.read(buffer)) != -1) {
bytestream.write(buffer, 0, ch);
}
byte data[] = bytestream.toByteArray();
bytestream.close();
return data;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return bais.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
}
Spring security 获取grant_type时是通过 request.getParameter 来获取的,你目前的wrapper方式封装不完整,会丢失form参数。
要实现restapi拦截处理,有两种方式:
- 继续完善现在的wrapper,覆盖并实现getParameter 方法。
- 扩展CUBA的restapi 身份认证bean:com.haulmont.addon.restapi.api.auth.CubaUserAuthenticationProvider, 实现方法:authenticate(Authentication authentication) 。在这个方法中对密码进行额外处理。
建议使用第二种方式,因为第一种方式涉及到了更多Spring 框架技术细节,实现成本较高。