@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        if (!authConfigs.isAuthEnabled()) {
            chain.doFilter(request, response);
            return;
        }
        
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        
        if (authConfigs.isEnableUserAgentAuthWhite()) {
            String userAgent = WebUtils.getUserAgent(req);
            if (StringUtils.startsWith(userAgent, Constants.NACOS_SERVER_HEADER)) {
                chain.doFilter(request, response);
                return;
            }
        } else if (StringUtils.isNotBlank(authConfigs.getServerIdentityKey()) && StringUtils.isNotBlank(
                authConfigs.getServerIdentityValue())) {
            String serverIdentity = req.getHeader(authConfigs.getServerIdentityKey());
            if (StringUtils.isNotBlank(serverIdentity)) {
                if (authConfigs.getServerIdentityValue().equals(serverIdentity)) {
                    chain.doFilter(request, response);
                    return;
                }
                Loggers.AUTH.warn("Invalid server identity value for {} from {}", authConfigs.getServerIdentityKey(),
                        req.getRemoteHost());
            }
        } else {
            resp.sendError(HttpServletResponse.SC_FORBIDDEN,
                    "Invalid server identity key or value, Please make sure set `nacos.core.auth.server.identity.key`"
                            + " and `nacos.core.auth.server.identity.value`, or open `nacos.core.auth.enable.userAgentAuthWhite`");
            return;
        }
        
        try {
            
            Method method = methodsCache.getMethod(req);
            
            if (method == null) {
                chain.doFilter(request, response);
                return;
            }
            
            if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) {
                
                if (Loggers.AUTH.isDebugEnabled()) {
                    Loggers.AUTH.debug("auth start, request: {} {}", req.getMethod(), req.getRequestURI());
                }
                
                Secured secured = method.getAnnotation(Secured.class);
                if (!protocolAuthService.enableAuth(secured)) {
                    chain.doFilter(request, response);
                    return;
                }
                Resource resource = protocolAuthService.parseResource(req, secured);
                IdentityContext identityContext = protocolAuthService.parseIdentity(req);
                boolean result = protocolAuthService.validateIdentity(identityContext, resource);
                RequestContext requestContext = RequestContextHolder.getContext();
                requestContext.getAuthContext().setIdentityContext(identityContext);
                requestContext.getAuthContext().setResource(resource);
                if (null == requestContext.getAuthContext().getAuthResult()) {
                    requestContext.getAuthContext().setAuthResult(result);
                }
                if (!result) {
                    // TODO Get reason of failure
                    throw new AccessException("Validate Identity failed.");
                }
                String action = secured.action().toString();
                result = protocolAuthService.validateAuthority(identityContext, new Permission(resource, action));
                if (!result) {
                    // TODO Get reason of failure
                    throw new AccessException("Validate Authority failed.");
                }
            }
            chain.doFilter(request, response);
        } catch (AccessException e) {
            if (Loggers.AUTH.isDebugEnabled()) {
                Loggers.AUTH.debug("access denied, request: {} {}, reason: {}", req.getMethod(), req.getRequestURI(),
                        e.getErrMsg());
            }
            resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getErrMsg());
        } catch (IllegalArgumentException e) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ExceptionUtil.getAllExceptionMsg(e));
        } catch (Exception e) {
            Loggers.AUTH.warn("[AUTH-FILTER] Server failed: ", e);
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server failed, " + e.getMessage());
        }
    }
@Test
    void testDoFilter() {
        try {
            FilterChain filterChain = new MockFilterChain();
            Mockito.when(authConfigs.isAuthEnabled()).thenReturn(true);
            MockHttpServletRequest request = new MockHttpServletRequest();
            HttpServletResponse response = new MockHttpServletResponse();
            authFilter.doFilter(request, response, filterChain);
            
            Mockito.when(authConfigs.isEnableUserAgentAuthWhite()).thenReturn(true);
            request.addHeader(HttpHeaderConsts.USER_AGENT_HEADER, Constants.NACOS_SERVER_HEADER);
            authFilter.doFilter(request, response, filterChain);
            
            Mockito.when(authConfigs.isEnableUserAgentAuthWhite()).thenReturn(false);
            Mockito.when(authConfigs.getServerIdentityKey()).thenReturn("1");
            Mockito.when(authConfigs.getServerIdentityValue()).thenReturn("2");
            request.addHeader("1", "2");
            authFilter.doFilter(request, response, filterChain);
            
            Mockito.when(authConfigs.getServerIdentityValue()).thenReturn("3");
            authFilter.doFilter(request, response, filterChain);
            
            Mockito.when(methodsCache.getMethod(Mockito.any())).thenReturn(filterChain.getClass().getMethod("testSecured"));
            authFilter.doFilter(request, response, filterChain);
            
        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }