在spring security前添加一個Filter

acdxxx188 發布于 02/14 20:48
閱讀 111
收藏 1

請教大神,為什么我在增加一個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.se[email protected]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錯誤,并且顯示到前端

加載中
1
a
acdxxx188

終于找到原因了,原來忘記在 chain.doFilter(s, response); 后面加一個return,導致執行完后拿原來的 request 又請求了一遍,汗

返回頂部
頂部
真人龙虎斗论坛