JSON Spring 安全 OAuth2 中的请求不工作 tomcat 9
JSON Request in Spring security OAuth2 not working tomcat 9
已关注 post 将请求更改为 json。
我的配置
过滤器:
@Component
@Order(value = Integer.MIN_VALUE)
public class JsonToUrlEncodedAuthenticationFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
if (Objects.equals(request.getContentType(), "application/json") && Objects.equals(((RequestFacade) request).getServletPath(), "/oauth/token")) {
InputStream is = request.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] json = buffer.toByteArray();
HashMap<String, String> result = new ObjectMapper().readValue(json, HashMap.class);
HashMap<String, String[]> r = new HashMap<>();
for (String key : result.keySet()) {
String[] val = new String[1];
val[0] = result.get(key);
r.put(key, val);
}
String[] val = new String[1];
val[0] = ((RequestFacade) request).getMethod();
r.put("_method", val);
HttpServletRequest s = new MyServletRequestWrapper(((HttpServletRequest) request), r);
chain.doFilter(s, response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
请求包装器:
public class MyServletRequestWrapper extends HttpServletRequestWrapper {
private final HashMap<String, String[]> params;
public MyServletRequestWrapper(HttpServletRequest request, HashMap<String, String[]> params) {
super(request);
this.params = params;
}
@Override
public String getParameter(String name) {
if (this.params.containsKey(name)) {
return this.params.get(name)[0];
}
return "";
}
@Override
public Map<String, String[]> getParameterMap() {
return this.params;
}
@Override
public Enumeration<String> getParameterNames() {
return new Enumerator<>(params.keySet());
}
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
}
以上配置在 spring 嵌入式启动 tomcat 中有效。
不幸的是,当我调试过滤器时,它在 tomcat 9.0.1 中不起作用,它获取一次值并通过它传递给 doFilter(),从那里再次循环,下次它得到错误
ERROR boot.web.support.ErrorPageFilter - Forwarding to error page from
request[/oauth/token] due to exception [No content to map due to
end-of-input]
由于 json 不存在第二个循环,但是当使用 springboot 时它不会进入第二个循环。
关于使其在 spring 引导以及独立 tomcat 中工作的任何建议。
The issue was Duplicate Filter registration for
'springSecurityFilterChain'
。
Spring 开机启动一次,我的代码也尝试注册 springSecurityFilterChain 手动扩展
AbstractSecurityWebApplicationInitializer.class
,这导致 trouble.After 删除它,它在 spring 引导和独立 tomcat 中工作。
已关注
我的配置
过滤器:
@Component
@Order(value = Integer.MIN_VALUE)
public class JsonToUrlEncodedAuthenticationFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
if (Objects.equals(request.getContentType(), "application/json") && Objects.equals(((RequestFacade) request).getServletPath(), "/oauth/token")) {
InputStream is = request.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] json = buffer.toByteArray();
HashMap<String, String> result = new ObjectMapper().readValue(json, HashMap.class);
HashMap<String, String[]> r = new HashMap<>();
for (String key : result.keySet()) {
String[] val = new String[1];
val[0] = result.get(key);
r.put(key, val);
}
String[] val = new String[1];
val[0] = ((RequestFacade) request).getMethod();
r.put("_method", val);
HttpServletRequest s = new MyServletRequestWrapper(((HttpServletRequest) request), r);
chain.doFilter(s, response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
请求包装器:
public class MyServletRequestWrapper extends HttpServletRequestWrapper {
private final HashMap<String, String[]> params;
public MyServletRequestWrapper(HttpServletRequest request, HashMap<String, String[]> params) {
super(request);
this.params = params;
}
@Override
public String getParameter(String name) {
if (this.params.containsKey(name)) {
return this.params.get(name)[0];
}
return "";
}
@Override
public Map<String, String[]> getParameterMap() {
return this.params;
}
@Override
public Enumeration<String> getParameterNames() {
return new Enumerator<>(params.keySet());
}
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
}
以上配置在 spring 嵌入式启动 tomcat 中有效。 不幸的是,当我调试过滤器时,它在 tomcat 9.0.1 中不起作用,它获取一次值并通过它传递给 doFilter(),从那里再次循环,下次它得到错误
ERROR boot.web.support.ErrorPageFilter - Forwarding to error page from request[/oauth/token] due to exception [No content to map due to end-of-input]
由于 json 不存在第二个循环,但是当使用 springboot 时它不会进入第二个循环。
关于使其在 spring 引导以及独立 tomcat 中工作的任何建议。
The issue was Duplicate Filter registration for 'springSecurityFilterChain'
。 Spring 开机启动一次,我的代码也尝试注册 springSecurityFilterChain 手动扩展
AbstractSecurityWebApplicationInitializer.class
,这导致 trouble.After 删除它,它在 spring 引导和独立 tomcat 中工作。