在spring security前添加一个Filter
请教大神,为什么我在增加一个filter后,能获取正常获取Oatuh2,但是为什么会出现unauthorized错误,前端能正常获取token,也显示错误
下面是我加的Filter,直接通过spring加载,没有在AuthorizationServerConfigurerAdapter里加载,因为我要加载到ClientCredentialsTokenEndpointFilter前面
功能是为spring security oatuh2增加JSON解析的能力,拦截/oauth/token路径,把Body中的JSON转换成params
@Slf4j
@Component
@Order(value = Integer.MIN_VALUE)
public class JsonToUrlEncodedAuthenticationFilter implements Filter {
private final ObjectMapper mapper;
private final String filterProcessesUrl="/oauth/token";
public JsonToUrlEncodedAuthenticationFilter(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
@SneakyThrows
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
log.debug("JSON过滤开始工作");
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("just supports HTTP requests");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (new AntPathRequestMatcher(filterProcessesUrl, "POST").matches(httpRequest)){
if (httpRequest.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
|| httpRequest.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)){
log.debug("开始转换");
InputStream is = httpRequest.getInputStream();
try (BufferedReader br = new BufferedReader(new InputStreamReader(is), 16384)) {
String json = br.lines()
.collect(Collectors.joining(System.lineSeparator()));
HashMap<String, String> result = mapper.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] = httpRequest.getMethod();
r.put("_method", val);
HttpServletRequest s = new MyServletRequestWrapper(httpRequest, r);
chain.doFilter(s, response);
}
}
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
class MyServletRequestWrapper extends HttpServletRequestWrapper {
private final HashMap<String, String[]> params;
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);
}
}
}
1 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.jdbc.datasource.DataSourceUtils | Returning JDBC Connection to DataSource
2 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor | Found 'Content-Type:application/json;charset=UTF-8' in response
3 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor | Writing [eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYXV0aG9yaXphdGlvbiIsIm1hZGVkaWFuZmVpIl0sInVzZXJfbmFtZSI6ImFjZHh4eDE3NyIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSIsImFsbCJdLCJleHAiOjE1ODE2ODYxODcsImF1dGhvcml0aWVzIjpbIlJPTEVf5pmu6YCa5Lq6Il0sImp0aSI6ImFjYjVhNTQ0LTQzMWMtNDlkNC04N2QyLWNkMDYxOGVlMDRhNyIsImNsaWVudF9pZCI6Im1hZGVkaWFuZmVpIn0.g3-ThU6s1CHpWH9FSp5pmxLdeRohL9N_yYcT072iUypggOguul702lXmtmqABZyNkYhzfterl2UZ4fDG40i8KJk79ivFJ5c_Rx5nMpA7ubJrnz0wgLcrg8mg8PCkXNKFGgB6S8CQiYPglQXoxFlHm767iOp0pJkSpn-jV4pvKLPHIRHgWaRysA2PdmikSZz8WaXrCVLBnzf2YyGd0h3xS2Nk-uWMJBHS-TH1lfOfkJWU7KeePEdsdvNMiBTwNAJ--9NC-WyNlrGub7B2OFaAXNc7wMhxvozpUAH_qoccasrg2aLhX3P-Gs2usQCifdlSI687b_T8ZaykMqGGJQrUgg]
4 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.security.web.header.writers.HstsHeaderWriter | Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@30bb94e4
5 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.DispatcherServlet | Completed 200 OK
6 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.security.web.access.ExceptionTranslationFilter | Chain processed normally
7 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.security.web.context.SecurityContextPersistenceFilter | SecurityContextHolder now cleared, as request processing completed
8 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.DispatcherServlet | POST "/oauth/token", parameters={}
9 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping | Mapped to public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map) throws org.springframework.web.HttpRequestMethodNotSupportedException
10 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver | Using @ExceptionHandler public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.handleException(java.lang.Exception) throws java.lang.Exception
11 >>| WARN | http-nio-8050-exec-1 | org.springframework.security.oauth2.provider.endpoint.TokenEndpoint | Handling error: InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter.
12 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor | Found 'Content-Type:application/json;charset=UTF-8' in response
13 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor | Writing [error="unauthorized", error_description="There is no client authentication. Try adding an appropriate authentication filter."]
14 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver | Resolved [org.springframework.security.authentication.InsufficientAuthenticationException: There is no client authentication. Try adding an appropriate authentication filter.]
15 >>| DEBUG | http-nio-8050-exec-1 | org.springframework.web.servlet.DispatcherServlet | Completed 200 OK
以上是日志,照理来说应该在第7行已经结束了,为什么又来一个请求,导致TokenEndpoint.postAccessToken()又执行了一边,但是这次的Principal没有值,导致unauthorized错误,并且显示到前端
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
见图片
终于找到原因了,原来忘记在 chain.doFilter(s, response); 后面加一个return,导致执行完后拿原来的 request 又请求了一遍,汗