spring-session导致request.getInputStream流数据丢失问题

博客介绍了一个关于spring-session导致的数据流被提前读取并消耗的问题,详细分析了问题产生的原因,并给出了三种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

  跨境系统新版本上线之后发现凡是通联支付的订单都卡在了准备支付报关这个状态,原因系统拿到的通联支付回抛的支付报关结果全是空(这里取数据是通过流方式读取的,即流中是空的)。

问题查找

  由于这个接口已经用了很久,所以开始认为是通联支付那边的问题,找他们的人沟通说确定已经把状态回抛给我们了,而我们拿到的数据又确实为空。问题到底出在哪?通过mock站点自测发现发送的时候有数据,但是到了Controller处理时流中数据为空。现在可以确定是我们自身系统问题了。那究竟是什么原因导致的呢?
第一次遇到这种问题(一个简单的Controller request.getInputStream()无故丢失了),肯定是请求到达Controller之前已经被使用过了,但是具体是什么引起的完全没什么思路。由于通联支付的订单比较少,零星的几单,出问题的这一单离上一正常单已经有段时间了。这期间上了很多版本。现在只能通过逐一排查新功能来查找到底是哪个功能影响到了这里。这一过程是痛苦的~~。最好把目标锁定在了集成oums时使用的spring-session。发现把spring-session禁掉接口变正常了,所以可以确定问题肯定出在这。先看下发送端和接收端的代码以方便下文深入探讨:

/**
 * 这是根据对接文档自己写的,可以说明问题
 */
public Result<String> doPost(String content) throws Exception {
    HttpEntity resEntity;
    try {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost method = new HttpPost(url);
        ByteArrayEntity byteArrayEntity = new ByteArrayEntity(content.getBytes(Constants.DEFAULT_CHARSET));
        byteArrayEntity.setContentEncoding(Constants.DEFAULT_CHARSET);
        byteArrayEntity.setContentType("application/x-www-form-urlencoded;charset=UTF-8");
        method.setEntity(byteArrayEntity);
        HttpResponse response = httpClient.execute(method);
        resEntity = response.getEntity();
    } catch (IOException e) {
        logger.error("", e);
        return Results.exception();
    }
    return Results.of(resEntity.toString());
}
/**
 * 通联支付报关结果
 */
@RequestMapping("/allinpay")
public void allinpay(HttpServletRequest request, HttpServletResponse response) {
    String btResponse;
    try {
        Result<AllinpayResultParam> statusResult = HttpRequestUtil.getRequestObjectByXml(request, AllinpayResultParam.class);
        btResponse = statusResult.isSuccess() ? allinpayRequestService.processOrderDeclareRequest(statusResult.getData()) :
                statusResult.getRes().getMsg();
    } catch (Exception e) {
        logger.error("通联支付报关结果处理失败", e);
        btResponse = "系统异常";
    }
    try {
        response.getOutputStream().write(btResponse.getBytes(Constants.DEFAULT_CHARSET));
    } catch (IOException e) {
        logger.error(e.getMessage(), e);
    }
}

/*主要看这里,很简单的流读取*/
public static String getRequestData(HttpServletRequest request) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    InputStream inputStream = null;
    String message;
    try {
        /*流中一直没数据 */
        inputStream = request.getInputStream();
        int c;
        while ((c = inputStream.read()) != -1) {
            os.write(c);
        }
        message = new String(os.toByteArray());
        logger.info(String.format("请求链接:%s; 请求内容:%s", request.getRequestURI(), message));
    } catch (IOException e) {
        logger.error(e.getMessage(), e);
        throw new RuntimeException("读取数据流失败");
    } finally {
        os.close();
        if (inputStream != null) {
            inputStream.close();
        }
    }
    return message;
}

spring-session源码解析

  在filter中打个断点可以看到filterChain中有一个DelegatingFilterProxy:
这里写图片描述
这是一个代理Filter,它代理的实际上是SessionRepositoryFilter,这个Filter是spring-session提供的。它对HttpServletRequest , HttpServletResponse 进行了一层包装来实现自己的功能,引发这个问题的关键点是重写了getSession方法:

@Override
public HttpSession getSession(boolean create) {
    if(currentSession != null) {
        return currentSession;
    }
    //关键是这里
    String requestedSessionId = getRequestedSessionId();
    if(requestedSessionId != null) {
        S session = sessionRepository.getSession(requestedSessionId);
        if(session != null) {
            this.requestedSessionIdValid = true;
            currentSession = new HttpSessionWrapper(session, getServletContext());
            currentSession.setNew(false);
            return currentSession;
        }
    }
    if(!create) {
        return null;
    }
    S session = sessionRepository.createSession();
    currentSession = new HttpSessionWrapper(session, getServletContext());
    return currentSession;
}

其中有一个getRequestSessionId()最终调用到了CookieHttpSessionStrategygetCurrentSessionAlias()方法:

    public String getCurrentSessionAlias(HttpServletRequest request) {
        if(sessionParam == null) {
            return DEFAULT_ALIAS;
        }
        //罪魁祸首
        String u = request.getParameter(sessionParam);
        if(u == null) {
            return DEFAULT_ALIAS;
        }
        if(!ALIAS_PATTERN.matcher(u).matches()) {
            return DEFAULT_ALIAS;
        }
        return u;
    }

说了这么多,罪魁祸首出来了,就是: request.getParameter(sessionParam)。回过头来看下上图FilterChain中有一个LocalUserFilter,这个Filter是oums中添加。其中有获取session的操作,最终会调用这个request.getParameter()。而request.getParameter()操作会读取流信息,从而导致流被掏空,以致请求到达Controller时没数据可以读取。

request.getParameter()与request.getInputStream()的关系

  getParameter方法为什么会读取流中的信息呢?它有没有什么规则呢?继续深究需要研究tomcat源码。我们使用的HttpServletRequest接口的底层承载类是tomcat中的**org.apache.coyote.Request**Parameters类也被封装在这里:

private final Parameters parameters = new Parameters();

这里主要看下Parameters是如何赋值的,当第一次调用request.getParamater()的时候会进行一次参数的解析操作,具体逻辑在org.apache.catalina.connector.Request类中的parseParameters()方法中:

protected void parseParameters() {
        parametersParsed = true;
        Parameters parameters = coyoteRequest.getParameters();
        boolean success = false;
        try {
            //省略不必要的代码
            ......
            ......
            //解析查询字符串中的参数
            parameters.handleQueryParameters();
            ......
            ......

            String contentType = getContentType();
            //如果contentType是multipart/form-data,解析请求中附带的参数
            if ("multipart/form-data".equals(contentType)) {
                parseParts(false);
                success = true;
                return;
            }
            //如果contentType是application/x-www-form-urlencoded类型才继续往下执行,其他类型的contentType到此就解析结束了
            if (!("application/x-www-form-urlencoded".equals(contentType))) {
                success = true;
                return;
            }
            int len = getContentLength();
            if (len > 0) {
                ......
                ......
                try {
                    //读取请求体中的内容到缓存中
                    if (readPostBody(formData, len) != len) {
                        ......
                        ......
                        return;
                    }
                } catch (IOException e) {
                   ......
                }
                //解析请求体中的参数
                parameters.processParameters(formData, 0, len);
            } 
            ......
            ......
            success = true;
        } finally {
            ......
            ......
        }
    }

从上面的代码可以看出关键点在32行的readPostBody这里,继续看代码:

    protected int readPostBody(byte body[], int len) throws IOException {
        int offset = 0;
        do {
            int inputLen = getStream().read(body, offset, len - offset);
            if (inputLen <= 0) {
                return offset;
            }
            offset += inputLen;
        } while ((len - offset) > 0);
        return len;

    }

    public InputStream getStream() {
        if (inputStream == null) {
            inputStream = new CoyoteInputStream(inputBuffer);
        }
        return inputStream;
    }

看到这里应该就明白了,这里读取的是InputStream中的数据。

更深层次探讨

  在上文parseParameters()方法中,不知道你有没有注意到请求体中的数据只有当contentTypeapplication/x-www-form-urlencoded时,才会被解析成Paramater,其他类型的contentType只会解析queryString中的参数。所以最终产生问题的原因还与发送请求时的contentType有关。假如我们指定其他类型的contentType就可以避免这个问题的产生。但是由于调用方是第三方企业,所以我们无法控制。对于这方面的内容Servlet规范中有提及:
这里写图片描述

解决方案

  • 1 修改contentType
  • 2 不使用spring-session
  • 3 重写HttpServletRequest
      我们知道可以通过修改contentType来避免这个问题,但是由于请求是第三方发送的,所以我们只能在接收端做手脚,怎么解决呢?最终选择了一个比较挫的方法。我们是通过请求到达LocalUserFilter之前对HttpServletRequest做一个封装,将流改造成可以重复读取的,不多说了,看代码吧:
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
    private ByteArrayOutputStream cachedBytes;

    public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
        super(request);
        cacheInputStream();
    }

    //每次获取流都创建一个从cachedBytes读取数据的流
    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new CachedServletInputStream();
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    //将流中的内容缓存起来
    private void cacheInputStream() throws IOException {
        cachedBytes = new ByteArrayOutputStream();
        IOUtils.copy(super.getInputStream(), cachedBytes);
    }

    public class CachedServletInputStream extends ServletInputStream {
        private ByteArrayInputStream input;
        public CachedServletInputStream() {
            input = new ByteArrayInputStream(cachedBytes.toByteArray());
        }
        ......
        ......
        @Override
        public int read() throws IOException {
            return input.read();
        }
    }
}

这个方法可以解决当前的问题,但是会引发其他问题,因为getInpustream和getParamater是相互影响的,这里把流用掉了,getParamater()就取不到了。所以只能用在特殊的接口上,在Filter中使用的时候只对需要的请求进行包装。谁有什么更好的方法欢迎提出来。

收到认证请求,路径:/KuCun2/users/login 请求方法:POST Content-Type:application/json Authentication attempt with: 123456_987987 123456 2025-05-29 16:22:32.170 DEBUG 28236 --- [nio-8080-exec-2] org.hibernate.SQL : select * from user where andy=? Hibernate: select * from user where andy=? {id:1, name:超管, andy:123456, pass:$2a$10$JflS0yjBRY6yDRxdhAuHVunetrG2P6q8gj8HQzuaPtW8tt/OqO73S, role:0} 0 [{"authority":"ROLE_ADMIN"}] 0 com.kucun.Config.user.CustomUserDetails@2362529c123456 0 2025-05-29 16:22:34.049 DEBUG 28236 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/index.html", parameters={} 2025-05-29 16:22:34.049 DEBUG 28236 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.054 DEBUG 28236 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.138 DEBUG 28236 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/util.css", parameters={} 2025-05-29 16:22:34.139 DEBUG 28236 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.150 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/fonts/font-awesome-4.7.0/css/font-awesome.min.css", parameters={} 2025-05-29 16:22:34.152 DEBUG 28236 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.155 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.156 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/main.css", parameters={} 2025-05-29 16:22:34.158 DEBUG 28236 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.162 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.168 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/index2.css", parameters={} 2025-05-29 16:22:34.169 DEBUG 28236 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.171 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.174 DEBUG 28236 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jquery-3.2.1.min.js", parameters={} 2025-05-29 16:22:34.175 DEBUG 28236 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.198 DEBUG 28236 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jsyilai.js", parameters={} 2025-05-29 16:22:34.199 DEBUG 28236 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.202 DEBUG 28236 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.210 DEBUG 28236 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.225 DEBUG 28236 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.309 DEBUG 28236 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/index.html", parameters={} 2025-05-29 16:22:34.309 DEBUG 28236 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.314 DEBUG 28236 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.319 DEBUG 28236 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/main.js?1748506954294&_=1748506954258", parameters={masked} 2025-05-29 16:22:34.319 DEBUG 28236 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.322 DEBUG 28236 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.324 DEBUG 28236 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/index.js?1748506954296&_=1748506954259", parameters={masked} 2025-05-29 16:22:34.324 DEBUG 28236 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.326 DEBUG 28236 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.456 DEBUG 28236 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/check-session", parameters={} 2025-05-29 16:22:34.457 DEBUG 28236 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.kucun.Config.SecurityConfig$SessionCheckController#checkSession(HttpServletRequest) 2025-05-29 16:22:34.473 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/bootstrap-3.3.7-dist/js/MyTable.js", parameters={} 2025-05-29 16:22:34.473 DEBUG 28236 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.476 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.493 DEBUG 28236 --- [nio-8080-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : No match for [*/*], supported: [] 2025-05-29 16:22:34.494 DEBUG 28236 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.628 DEBUG 28236 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/login.html", parameters={} 2025-05-29 16:22:34.628 DEBUG 28236 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.631 DEBUG 28236 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.744 DEBUG 28236 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/fonts/font-awesome-4.7.0/css/font-awesome.min.css", parameters={} 2025-05-29 16:22:34.746 DEBUG 28236 --- [nio-8080-exec-7] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.747 DEBUG 28236 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/util.css", parameters={} 2025-05-29 16:22:34.748 DEBUG 28236 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.758 DEBUG 28236 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jquery-3.2.1.min.js", parameters={} 2025-05-29 16:22:34.758 DEBUG 28236 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.777 DEBUG 28236 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/main.css", parameters={} 2025-05-29 16:22:34.778 DEBUG 28236 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.779 DEBUG 28236 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jsyilai.js", parameters={} 2025-05-29 16:22:34.780 DEBUG 28236 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.779 DEBUG 28236 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.782 DEBUG 28236 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.786 DEBUG 28236 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.787 DEBUG 28236 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.799 DEBUG 28236 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.854 DEBUG 28236 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/images/bg-01.jpg", parameters={} 2025-05-29 16:22:34.855 DEBUG 28236 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.859 DEBUG 28236 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.905 DEBUG 28236 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/main.js?1748506954900&_=1748506954847", parameters={masked} 2025-05-29 16:22:34.905 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/login.js?1748506954903&_=1748506954848", parameters={masked} 2025-05-29 16:22:34.907 DEBUG 28236 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.909 DEBUG 28236 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:22:34.910 DEBUG 28236 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:22:34.914 DEBUG 28236 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK package com.kucun.Config; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.json.Json; import javax.servlet.Filter; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.ObjectMapper; import com.kucun.Config.user.CustomUserDetails; // 2. 基础安全配置 @Configuration @EnableWebSecurity // 启用Web安全功能 public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/check-session"); } // 添加自定义Controller @RestController public static class SessionCheckController { @GetMapping("/check-session") public ResponseEntity<?> checkSession(HttpServletRequest request) { return request.getSession(false) != null ? ResponseEntity.ok().build() : ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } } /** * 核心安全过滤器链配置 * @param http HTTP安全构建器 * @return 安全过滤器链 * @throws Exception 配置异常 * * █ 配置逻辑说明: * 1. authorizeHttpRequests: 定义访问控制规则 * 2. formLogin: 配置表单登录 * 3. logout: 配置注销行为 * 4. exceptionHandling: 处理权限异常[^3] */ // 修正后的配置方法 @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .invalidSessionUrl("/login.html?session=invalid") .maximumSessions(1) .maxSessionsPreventsLogin(false) .and() .and() .addFilterBefore(jsonAuthFilter(), UsernamePasswordAuthenticationFilter.class) // 关键配置 .authorizeRequests() .antMatchers("/login.html", "/users/login").permitAll() .antMatchers("/js/**", "/css/**", "/fonts/**", "/images/**").permitAll() .antMatchers("/users/guanli/**").hasAuthority("ROLE_ADMIN") .anyRequest().authenticated() .and() .formLogin().disable() // .loginPage("/login.html") // .loginProcessingUrl("/users/login") // // .successHandler(ajaxAuthenticationSuccessHandler()) // 自定义成功处理器 // .failureHandler(ajaxAuthenticationFailureHandler()) // 自定义失败处理器 // .defaultSuccessUrl("/index.html") // .failureUrl("/login.html?error=true") // .usernameParameter("andy") // 修改用户名参数名 // .passwordParameter("pass") // 修改密码参数名 // .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login.html") .and() .csrf() .ignoringAntMatchers("/users/login") .and() .headers() .frameOptions().sameOrigin() .and() .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()); // 统一使用Handler } // 返回JSON格式的成功响应 @Bean public AuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { return (request, response, authentication) -> { // 强制创建服务端会话 request.getSession(true); HttpSession session = request.getSession(true); Cookie cookie = new Cookie("JSESSIONID", session.getId()); cookie.setPath("/KuCun2/"); // 明确指定上下文路径 cookie.setMaxAge(1800); // 30分钟 response.addCookie(cookie); //构建安全响应数据 Map<String, Object> responseData = new HashMap<>(); responseData.put("sessionId", request.getSession().getId()); responseData.put("userInfo",Collections.unmodifiableMap(new HashMap<String, Object>() {/** * */ private static final long serialVersionUID = 1L; { put("Name", ((CustomUserDetails)authentication.getPrincipal()).getName()); put("role", ((CustomUserDetails)authentication.getPrincipal()).getRole()); }})); // 统一返回JSON格式 response.setContentType(MediaType.APPLICATION_JSON_VALUE); // new ObjectMapper().writeValue(response.getWriter(), responseData); response.setContentType(MediaType.APPLICATION_JSON_VALUE); CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); response.setStatus(HttpStatus.OK.value()); System.out.println(authentication.getPrincipal()+""+authentication.getName()); if (request.getHeader("X-Requested-With") == null) { // 非AJAX请求 response.sendRedirect("/index.html"); } else { //String re=userDetails.getUser().toString() new ObjectMapper().writeValue(response.getWriter(), userDetails.getUser() ); } }; } // 返回401状态码和错误信息 @Bean public AuthenticationFailureHandler ajaxAuthenticationFailureHandler() { return (request, response, exception) -> { if (request.getHeader("X-Requested-With") == null) { response.sendRedirect("/login.html?error=true"); } else { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write("{\"error\":\"Authentication failed\"}"); } }; } // 处理未认证请求 @Bean public AuthenticationEntryPoint ajaxAuthenticationEntryPoint() { return (request, response, exception) -> { if (request.getHeader("X-Requested-With") == null) { response.sendRedirect("/login.html?error=true"); } else { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write("{\"error\":\"Authentication failed\"}"); } }; } @Bean public JsonUsernamePasswordAuthenticationFilter jsonAuthFilter() throws Exception { JsonUsernamePasswordAuthenticationFilter filter = new JsonUsernamePasswordAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); filter.setUsernameParameter("andy"); // 设置自定义参数名 filter.setPasswordParameter("pass"); filter.setFilterProcessesUrl("/users/login"); filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()); filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()); return filter; } /** * 密码编码器(必须配置) * 使用BCrypt强哈希算法加密 */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AccessDeniedHandler accessDeniedHandler() { System.out.println("0000"); return (request, response, ex) -> { if (!response.isCommitted()) { response.sendRedirect("/error/403"); } }; } } class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { System.out.println("收到认证请求,路径:" + request.getRequestURI()); System.out.println("请求方法:" + request.getMethod()); System.out.println("Content-Type:" + request.getContentType()); if (request.getContentType() != null && request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)) { try (InputStream is = request.getInputStream()) { Map<String, String> authMap = objectMapper.readValue(is, Map.class); String username = authMap.getOrDefault(getUsernameParameter(), ""); String password = authMap.getOrDefault(getPasswordParameter(), ""); // 调试日志 System.out.println("Authentication attempt with: " + username+'_'+ password); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } catch (IOException e) { throw new AuthenticationServiceException("认证请求解析失败", e); } } Authentication aut= super.attemptAuthentication(request, response); System.out.println("结果:"+aut.isAuthenticated()); return aut; } }
05-30
package com.kucun.Config; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.json.Json; import javax.servlet.Filter; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.ObjectMapper; import com.kucun.Config.user.CustomUserDetails; // 2. 基础安全配置 @Configuration @EnableWebSecurity // 启用Web安全功能 public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/check-session"); } // 添加自定义Controller @RestController public static class SessionCheckController { @GetMapping("/check-session") public ResponseEntity<?> checkSession(HttpServletRequest request) { return request.getSession(false) != null ? ResponseEntity.ok().build() : ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } } /** * 核心安全过滤器链配置 * @param http HTTP安全构建器 * @return 安全过滤器链 * @throws Exception 配置异常 * * █ 配置逻辑说明: * 1. authorizeHttpRequests: 定义访问控制规则 * 2. formLogin: 配置表单登录 * 3. logout: 配置注销行为 * 4. exceptionHandling: 处理权限异常[^3] */ // 修正后的配置方法 @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) .invalidSessionUrl("/login.html?session=invalid") .maximumSessions(1) .maxSessionsPreventsLogin(false) .and() .and() .addFilterBefore(jsonAuthFilter(), UsernamePasswordAuthenticationFilter.class) // 关键配置 .authorizeRequests() .antMatchers("/login.html", "/users/login").permitAll() .antMatchers("/js/**", "/css/**", "/fonts/**", "/images/**","/check-session","/main/bootstrap-3.3.7-dist/**").permitAll() .antMatchers("/users/guanli/**").hasAuthority("ROLE_ADMIN") .anyRequest().authenticated() .and() .formLogin().disable() // .loginPage("/login.html") // .loginProcessingUrl("/users/login") // // .successHandler(ajaxAuthenticationSuccessHandler()) // 自定义成功处理器 // .failureHandler(ajaxAuthenticationFailureHandler()) // 自定义失败处理器 // .defaultSuccessUrl("/index.html") // .failureUrl("/login.html?error=true") // .usernameParameter("andy") // 修改用户名参数名 // .passwordParameter("pass") // 修改密码参数名 // .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login.html") .and() .csrf() .ignoringAntMatchers("/users/login") .and() .headers() .frameOptions().sameOrigin() .and() .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()); // 统一使用Handler } // 返回JSON格式的成功响应 @Bean public AuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { return (request, response, authentication) -> { // 强制创建服务端会话 request.getSession(true); String contextPath = request.getContextPath(); HttpSession session = request.getSession(true); Cookie cookie = new Cookie("JSESSIONID", session.getId()); cookie.setPath(contextPath.isEmpty() ? "/" : contextPath + "/"); cookie.setMaxAge(1800); // 30分钟 response.addCookie(cookie); //构建安全响应数据 Map<String, Object> responseData = new HashMap<>(); responseData.put("sessionId", request.getSession().getId()); responseData.put("userInfo",Collections.unmodifiableMap(new HashMap<String, Object>() {/** * */ private static final long serialVersionUID = 1L; { put("Name", ((CustomUserDetails)authentication.getPrincipal()).getName()); put("role", ((CustomUserDetails)authentication.getPrincipal()).getRole()); }})); // 统一返回JSON格式 response.setContentType(MediaType.APPLICATION_JSON_VALUE); // new ObjectMapper().writeValue(response.getWriter(), responseData); response.setContentType(MediaType.APPLICATION_JSON_VALUE); CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); response.setStatus(HttpStatus.OK.value()); System.out.println(authentication.getPrincipal()+""+authentication.getName()); if (request.getHeader("X-Requested-With") == null) { // 非AJAX请求 response.sendRedirect("/index.html"); } else { //String re=userDetails.getUser().toString() new ObjectMapper().writeValue(response.getWriter(), userDetails.getUser() ); } }; } // 返回401状态码和错误信息 @Bean public AuthenticationFailureHandler ajaxAuthenticationFailureHandler() { return (request, response, exception) -> { if (request.getHeader("X-Requested-With") == null) { response.sendRedirect("/login.html?error=true"); } else { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write("{\"error\":\"Authentication failed\"}"); } }; } // 处理未认证请求 @Bean public AuthenticationEntryPoint ajaxAuthenticationEntryPoint() { return (request, response, exception) -> { if (request.getHeader("X-Requested-With") == null) { response.sendRedirect("/login.html?error=true"); } else { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write("{\"error\":\"Authentication failed\"}"); } }; } @Bean public JsonUsernamePasswordAuthenticationFilter jsonAuthFilter() throws Exception { JsonUsernamePasswordAuthenticationFilter filter = new JsonUsernamePasswordAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); filter.setUsernameParameter("andy"); // 设置自定义参数名 filter.setPasswordParameter("pass"); filter.setFilterProcessesUrl("/users/login"); filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()); filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()); return filter; } /** * 密码编码器(必须配置) * 使用BCrypt强哈希算法加密 */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AccessDeniedHandler accessDeniedHandler() { System.out.println("0000"); return (request, response, ex) -> { if (!response.isCommitted()) { response.sendRedirect("/error/403"); } }; } } class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { System.out.println("收到认证请求,路径:" + request.getRequestURI()); System.out.println("请求方法:" + request.getMethod()); System.out.println("Content-Type:" + request.getContentType()); if (request.getContentType() != null && request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)) { try (InputStream is = request.getInputStream()) { Map<String, String> authMap = objectMapper.readValue(is, Map.class); String username = authMap.getOrDefault(getUsernameParameter(), ""); String password = authMap.getOrDefault(getPasswordParameter(), ""); // 调试日志 System.out.println("Authentication attempt with: " + username+'_'+ password); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } catch (IOException e) { throw new AuthenticationServiceException("认证请求解析失败", e); } } Authentication aut= super.attemptAuthentication(request, response); System.out.println("结果:"+aut.isAuthenticated()); return aut; } } package com.kucun.Config.Role; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.json.Json; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; /** * 权限转化 * @author Administrator * */ @Component public class RoleConverter { private static final Map<Integer, String> ROLE_MAP = new HashMap<>(); @PostConstruct public void init() { ROLE_MAP.put(0, "ROLE_ADMIN"); ROLE_MAP.put(1, "ROLE_USER"); ROLE_MAP.put(2, "ROLE_MANAGER"); ROLE_MAP.put(3, "ROLE_AUDITOR"); } public List<GrantedAuthority> convert(int roleCode) { ObjectMapper mapper = new ObjectMapper(); try { System.out.println(mapper.writeValueAsString(Collections.singletonList( new SimpleGrantedAuthority(ROLE_MAP.getOrDefault(roleCode, "ROLE_GUEST")))).toString());//输出[{"authority":"ROLE_ADMIN"}] } catch (JsonProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return Collections.singletonList( new SimpleGrantedAuthority(ROLE_MAP.getOrDefault(roleCode, "ROLE_GUEST")) ); } } function https(url,data,fu){ $.ajax({ contentType:"application/json", url: url, // 假设后端 API 地址 method: "POST", data: JSON.stringify(data), type: "json", success:fu, error: function (e) { console.error(e) alert("请求失败,请稍后再试!"+e); } }); } function checkLoginStatus() { if (window.location.href.includes('/login.html')) return; const username = localStorage.getItem("name"); if (!username) { window.location.href = '/KuCun2/login.html'; alert("meijin") return; } // 检查会话是否有效 fetch('/KuCun2/check-session', { headers: { "X-Requested-With": "XMLHttpRequest", // 显式添加头 "Content-Type": "application/json" }, credentials: 'include' // 强制携带 Cookie }).then(response => { if (!response.ok) { localStorage.removeItem("name"); alert("meijin2") window.location.href = '/KuCun2/login.html'; alert("meijin3") } }); } function deepMergeArrays(frontend, backend) { const resultMap = new Map(); // 遍历前端数据并存入 Map 中以便快速查找 frontend.forEach(item => resultMap.set(item.id, { ...item })); // 遍历后端数据并与前端数据进行合并 backend.forEach(item => { if (resultMap.has(item.id)) { // 如果存在相同 ID,则合并两者的内容 resultMap.set( item.id, Object.assign(resultMap.get(item.id), item) ); } else { // 如果不存在相同 ID,则新增该条目 resultMap.set(item.id, { ...item }); } }); // 将最终结果转回数组形式 return Array.from(resultMap.values()); } (function ($){ // 页面加载时检查登录状态 checkLoginStatus(); })(jQuery); function removeSpecificCharactersAndConvertToNumber(str, charsToRemove) { const regex = new RegExp(`[${charsToRemove}]`, 'g'); // 创建用于匹配指定字符的正则表达式 const cleanedStr = str.replace(regex, ''); // 移除指定字符 const numberValue = parseFloat(cleanedStr); // 转换为浮点数 return isNaN(numberValue) ? null : numberValue; // 如果无法解析,则返回 null } /// <reference path="jquery.d.ts" /> // $(document).ready(function(){ // $("#submit").click(function(){ // // // $.ajax({ // url:"../users/login", // async:false, // data:JSON.stringify({ // andy:$("#andy").val(), // pass:$("#pass").val(), // name:$("#name").val()}), // type:"post", // contentType:"application/json", // success:function(e){ // alert(e) // } // }); // // // }); // }) (function ($) { "use strict"; /*================================================================== [ Focus Contact2 ]*/ $('.input100').each(function () { $(this).on('blur', function () { if ($(this).val().trim() != "") { $(this).addClass('has-val'); } else { $(this).removeClass('has-val'); } }) }) /*================================================================== [ Validate ]*/ var input = $('.validate-input .input100'); $('.validate-form').on('submit', function (e) { e.preventDefault(); var check = true; for (var i = 0; i < input.length; i++) { if (validate(input[i]) == false) { showValidate(input[i]); check = false; } } if(check) login(input); return check; }); $('.validate-form .input100').each(function () { $(this).focus(function () { hideValidate(this); }); }); function validate(input) { if ($(input).attr('type') == 'email' || $(input).attr('name') == 'email') { if ($(input).val().trim().match(/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{1,5}|[0-9]{1,3})(\]?)$/) == null) { return false; } } else { if ($(input).val().trim() == '') { return false; } } } function showValidate(input) { var thisAlert = $(input).parent(); alert(input) $(thisAlert).addClass('alert-validate'); } function hideValidate(input) { var thisAlert = $(input).parent(); $(thisAlert).removeClass('alert-validate'); } // 登录按钮点击事件 function login(datas) { var data={} datas.each(function(a,element){ alert() data[$(element).attr('name')]=$(element).val() }) //var data={ andy,pass } // 模拟 AJAX 请求 https("/KuCun2/users/login",data,function (response) { alert("1"); if (response.name) { localStorage.setItem("name", response.name); // 保存用户名到本地存储 localStorage.setItem("role", response.role); // 保存权限到本地存储 alert( response) //window.location.href = '/KuCun2/index.html'; } else { alert("登录失败,请检查用户名和密码!"); } }) }; // 注销按钮点击事件 $("#logout-btn").click(function () { localStorage.removeItem("name"); // 清除本地存储中的用户名 checkLoginStatus(); // 更新登录状态 }); })(jQuery);2025-05-29 16:48:55.354 DEBUG 2708 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/index.html", parameters={} 2025-05-29 16:48:55.372 DEBUG 2708 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.400 DEBUG 2708 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.441 DEBUG 2708 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/fonts/font-awesome-4.7.0/css/font-awesome.min.css", parameters={} 2025-05-29 16:48:55.442 DEBUG 2708 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.450 DEBUG 2708 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.453 DEBUG 2708 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/main.css", parameters={} 2025-05-29 16:48:55.455 DEBUG 2708 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.457 DEBUG 2708 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/util.css", parameters={} 2025-05-29 16:48:55.459 DEBUG 2708 --- [nio-8080-exec-7] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.459 DEBUG 2708 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/index2.css", parameters={} 2025-05-29 16:48:55.460 DEBUG 2708 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.461 DEBUG 2708 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jsyilai.js", parameters={} 2025-05-29 16:48:55.462 DEBUG 2708 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.462 DEBUG 2708 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.465 DEBUG 2708 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jquery-3.2.1.min.js", parameters={} 2025-05-29 16:48:55.465 DEBUG 2708 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.466 DEBUG 2708 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.473 DEBUG 2708 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.506 DEBUG 2708 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.509 DEBUG 2708 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.619 DEBUG 2708 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/index.html", parameters={} 2025-05-29 16:48:55.621 DEBUG 2708 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.625 DEBUG 2708 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.678 DEBUG 2708 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/main.js?1748508535614&_=1748508535584", parameters={masked} 2025-05-29 16:48:55.681 DEBUG 2708 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.696 DEBUG 2708 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.711 DEBUG 2708 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/index.js?1748508535617&_=1748508535585", parameters={masked} 2025-05-29 16:48:55.711 DEBUG 2708 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.714 DEBUG 2708 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.769 DEBUG 2708 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/bootstrap-3.3.7-dist/js/MyTable.js", parameters={} 2025-05-29 16:48:55.772 DEBUG 2708 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:55.783 DEBUG 2708 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:55.846 DEBUG 2708 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/check-session", parameters={} 2025-05-29 16:48:55.851 DEBUG 2708 --- [nio-8080-exec-8] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.kucun.Config.SecurityConfig$SessionCheckController#checkSession(HttpServletRequest) 2025-05-29 16:48:55.903 DEBUG 2708 --- [nio-8080-exec-8] o.s.w.s.m.m.a.HttpEntityMethodProcessor : No match for [*/*], supported: [] 2025-05-29 16:48:55.904 DEBUG 2708 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.053 DEBUG 2708 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/login.html", parameters={} 2025-05-29 16:48:56.054 DEBUG 2708 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.057 DEBUG 2708 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.177 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/fonts/font-awesome-4.7.0/css/font-awesome.min.css", parameters={} 2025-05-29 16:48:56.178 DEBUG 2708 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.188 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.190 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/util.css", parameters={} 2025-05-29 16:48:56.190 DEBUG 2708 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.204 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.206 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/main.css", parameters={} 2025-05-29 16:48:56.206 DEBUG 2708 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.208 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.210 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jquery-3.2.1.min.js", parameters={} 2025-05-29 16:48:56.210 DEBUG 2708 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.218 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.220 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jsyilai.js", parameters={} 2025-05-29 16:48:56.221 DEBUG 2708 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.224 DEBUG 2708 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.345 DEBUG 2708 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/images/bg-01.jpg", parameters={} 2025-05-29 16:48:56.347 DEBUG 2708 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.351 DEBUG 2708 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.367 DEBUG 2708 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/main.js?1748508536335&_=1748508536268", parameters={masked} 2025-05-29 16:48:56.368 DEBUG 2708 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.374 DEBUG 2708 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:48:56.509 DEBUG 2708 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/login.js?1748508536338&_=1748508536269", parameters={masked} 2025-05-29 16:48:56.510 DEBUG 2708 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:48:56.512 DEBUG 2708 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK
05-30
package com.kucun.Config; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.json.Json; import javax.servlet.Filter; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.fasterxml.jackson.databind.ObjectMapper; import com.kucun.Config.user.CustomUserDetails; // 2. 基础安全配置 @Configuration @EnableWebSecurity // 启用Web安全功能 public class SecurityConfig extends WebSecurityConfigurerAdapter{ /** * 核心安全过滤器链配置 * @param http HTTP安全构建器 * @return 安全过滤器链 * @throws Exception 配置异常 * * █ 配置逻辑说明: * 1. authorizeHttpRequests: 定义访问控制规则 * 2. formLogin: 配置表单登录 * 3. logout: 配置注销行为 * 4. exceptionHandling: 处理权限异常[^3] */ // 修正后的配置方法 @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .invalidSessionUrl("/login.html?session=invalid") .maximumSessions(1) .maxSessionsPreventsLogin(false) .and() .and() .addFilterBefore(jsonAuthFilter(), UsernamePasswordAuthenticationFilter.class) // 关键配置 .authorizeRequests() .antMatchers("/login.html", "/users/login").permitAll() .antMatchers("/js/**", "/css/**", "/fonts/**", "/images/**").permitAll() .antMatchers("/users/guanli/**").hasAuthority("ROLE_ADMIN") .anyRequest().authenticated() .and() .formLogin().disable() // .loginPage("/login.html") // .loginProcessingUrl("/users/login") // // .successHandler(ajaxAuthenticationSuccessHandler()) // 自定义成功处理器 // .failureHandler(ajaxAuthenticationFailureHandler()) // 自定义失败处理器 // .defaultSuccessUrl("/index.html") // .failureUrl("/login.html?error=true") // .usernameParameter("andy") // 修改用户名参数名 // .passwordParameter("pass") // 修改密码参数名 // .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login.html") .and() .csrf() .ignoringAntMatchers("/users/login") .and() .headers() .frameOptions().sameOrigin() .and() .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()); // 统一使用Handler } // 返回JSON格式的成功响应 @Bean public AuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { return (request, response, authentication) -> { // 强制创建服务端会话 request.getSession(true); HttpSession session = request.getSession(true); session.setMaxInactiveInterval(1800); // 30分钟过期 // 将会话 ID 写入响应头 Cookie cookie = new Cookie("JSESSIONID", session.getId()); cookie.setPath("/"); cookie.setHttpOnly(true); response.addCookie(cookie); //构建安全响应数据 Map<String, Object> responseData = new HashMap<>(); responseData.put("sessionId", request.getSession().getId()); responseData.put("userInfo",Collections.unmodifiableMap(new HashMap<String, Object>() {/** * */ private static final long serialVersionUID = 1L; { put("Name", ((CustomUserDetails)authentication.getPrincipal()).getName()); put("role", ((CustomUserDetails)authentication.getPrincipal()).getRole()); }})); // 统一返回JSON格式 response.setContentType(MediaType.APPLICATION_JSON_VALUE); // new ObjectMapper().writeValue(response.getWriter(), responseData); response.setContentType(MediaType.APPLICATION_JSON_VALUE); CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); response.setStatus(HttpStatus.OK.value()); System.out.println(authentication.getPrincipal()+""+authentication.getName()); if (request.getHeader("X-Requested-With") == null) { // 非AJAX请求 response.sendRedirect("/index.html"); } else { //String re=userDetails.getUser().toString() new ObjectMapper().writeValue(response.getWriter(), userDetails.getUser() ); } }; } // 返回401状态码和错误信息 @Bean public AuthenticationFailureHandler ajaxAuthenticationFailureHandler() { return (request, response, exception) -> { if (request.getHeader("X-Requested-With") == null) { response.sendRedirect("/login.html?error=true"); } else { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write("{\"error\":\"Authentication failed\"}"); } }; } // 处理未认证请求 @Bean public AuthenticationEntryPoint ajaxAuthenticationEntryPoint() { return (request, response, exception) -> { if (request.getHeader("X-Requested-With") == null) { response.sendRedirect("/login.html?error=true"); } else { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write("{\"error\":\"Authentication failed\"}"); } }; } @Bean public JsonUsernamePasswordAuthenticationFilter jsonAuthFilter() throws Exception { JsonUsernamePasswordAuthenticationFilter filter = new JsonUsernamePasswordAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); filter.setUsernameParameter("andy"); // 设置自定义参数名 filter.setPasswordParameter("pass"); filter.setFilterProcessesUrl("/users/login"); filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()); filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()); return filter; } /** * 密码编码器(必须配置) * 使用BCrypt强哈希算法加密 */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AccessDeniedHandler accessDeniedHandler() { System.out.println("0000"); return (request, response, ex) -> { if (!response.isCommitted()) { response.sendRedirect("/error/403"); } }; } } class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { System.out.println("收到认证请求,路径:" + request.getRequestURI()); System.out.println("请求方法:" + request.getMethod()); System.out.println("Content-Type:" + request.getContentType()); if (request.getContentType() != null && request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)) { try (InputStream is = request.getInputStream()) { Map<String, String> authMap = objectMapper.readValue(is, Map.class); String username = authMap.getOrDefault(getUsernameParameter(), ""); String password = authMap.getOrDefault(getPasswordParameter(), ""); // 调试日志 System.out.println("Authentication attempt with: " + username+'_'+ password); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } catch (IOException e) { throw new AuthenticationServiceException("认证请求解析失败", e); } } Authentication aut= super.attemptAuthentication(request, response); System.out.println("结果:"+aut.isAuthenticated()); return aut; } } package com.kucun.Config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service; import com.kucun.Config.Role.RoleConverter; import com.kucun.Config.user.CustomUserDetails; import com.kucun.data.entity.User; import com.kucun.dataDo.UserRepository; /** * 获取数据 * @author Administrator * */ @Service public class CustomUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Autowired private RoleConverter roleConverter; public CustomUserDetailsService() { super(); System.out.println("11111"); } /** * 获取数据库中用户信息 * @param andy 账号 * * @return * */ @Override public UserDetails loadUserByUsername(String andy) { System.out.println(andy); User user = userRepository.findByAndy(andy); System.out.println(user); return new CustomUserDetails(user, roleConverter.convert(user.getRole()) // 关键转换点[^1] ); } }package com.kucun.Config.user; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import com.kucun.data.entity.User; public class CustomUserDetails implements UserDetails { /** * */ private static final long serialVersionUID = 1L; private final String andy; // 对应andy字段 private final String name; private final int role; private final String password; private final User users; private final Collection<? extends GrantedAuthority> authorities; public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities) { this.andy = user.getAndy(); this.name = user.getName(); this.role = user.getRole(); this.password = user.getPass(); user.setPass(null); this.users=user; this.authorities = authorities; } // 实现UserDetails接口方法 @Override public String getUsername() { return andy; } @Override public String getPassword() { return password; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } // 自定义字段访问方法 public String getName() { return name; } public User getUser() { return users; } public int getRole() { return role; } // 其他必要方法 @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } } function https(url,data,fu){ $.ajax({ contentType:"application/json", url: url, // 假设后端 API 地址 method: "POST", data: JSON.stringify(data), type: "json", success:fu, error: function (e) { console.error(e) alert("请求失败,请稍后再试!"+e); } }); } function checkLoginStatus() { if (window.location.href.includes('/login.html')) return; const username = localStorage.getItem("name"); if (!username) { window.location.href = '/KuCun2/login.html'; return; } // 检查会话是否有效 fetch('/KuCun2/check-session', { credentials: 'include' // 强制携带 Cookie }).then(response => { if (!response.ok) { localStorage.removeItem("name"); window.location.href = '/KuCun2/login.html'; } }); } function deepMergeArrays(frontend, backend) { const resultMap = new Map(); // 遍历前端数据并存入 Map 中以便快速查找 frontend.forEach(item => resultMap.set(item.id, { ...item })); // 遍历后端数据并与前端数据进行合并 backend.forEach(item => { if (resultMap.has(item.id)) { // 如果存在相同 ID,则合并两者的内容 resultMap.set( item.id, Object.assign(resultMap.get(item.id), item) ); } else { // 如果不存在相同 ID,则新增该条目 resultMap.set(item.id, { ...item }); } }); // 将最终结果转回数组形式 return Array.from(resultMap.values()); } (function ($){ // 页面加载时检查登录状态 checkLoginStatus(); })(jQuery); function removeSpecificCharactersAndConvertToNumber(str, charsToRemove) { const regex = new RegExp(`[${charsToRemove}]`, 'g'); // 创建用于匹配指定字符的正则表达式 const cleanedStr = str.replace(regex, ''); // 移除指定字符 const numberValue = parseFloat(cleanedStr); // 转换为浮点数 return isNaN(numberValue) ? null : numberValue; // 如果无法解析,则返回 null } /// <reference path="jquery.d.ts" /> // $(document).ready(function(){ // $("#submit").click(function(){ // // // $.ajax({ // url:"../users/login", // async:false, // data:JSON.stringify({ // andy:$("#andy").val(), // pass:$("#pass").val(), // name:$("#name").val()}), // type:"post", // contentType:"application/json", // success:function(e){ // alert(e) // } // }); // // // }); // }) (function ($) { "use strict"; /*================================================================== [ Focus Contact2 ]*/ $('.input100').each(function () { $(this).on('blur', function () { if ($(this).val().trim() != "") { $(this).addClass('has-val'); } else { $(this).removeClass('has-val'); } }) }) /*================================================================== [ Validate ]*/ var input = $('.validate-input .input100'); $('.validate-form').on('submit', function (e) { e.preventDefault(); var check = true; for (var i = 0; i < input.length; i++) { if (validate(input[i]) == false) { showValidate(input[i]); check = false; } } if(check) login(input); return check; }); $('.validate-form .input100').each(function () { $(this).focus(function () { hideValidate(this); }); }); function validate(input) { if ($(input).attr('type') == 'email' || $(input).attr('name') == 'email') { if ($(input).val().trim().match(/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{1,5}|[0-9]{1,3})(\]?)$/) == null) { return false; } } else { if ($(input).val().trim() == '') { return false; } } } function showValidate(input) { var thisAlert = $(input).parent(); alert(input) $(thisAlert).addClass('alert-validate'); } function hideValidate(input) { var thisAlert = $(input).parent(); $(thisAlert).removeClass('alert-validate'); } // 登录按钮点击事件 function login(datas) { var data={} datas.each(function(a,element){ alert() data[$(element).attr('name')]=$(element).val() }) //var data={ andy,pass } // 模拟 AJAX 请求 https("/KuCun2/users/login",data,function (response) { alert("1"); if (response.name) { localStorage.setItem("name", response.name); // 保存用户名到本地存储 localStorage.setItem("role", response.role); // 保存权限到本地存储 alert( response) window.location.href = '/KuCun2/index.html'; } else { alert("登录失败,请检查用户名和密码!"); } }) }; // 注销按钮点击事件 $("#logout-btn").click(function () { localStorage.removeItem("name"); // 清除本地存储中的用户名 checkLoginStatus(); // 更新登录状态 }); })(jQuery);收到认证请求,路径:/KuCun2/users/login 请求方法:POST Content-Type:application/json Authentication attempt with: 123456_987987 123456 2025-05-29 16:10:16.245 DEBUG 33108 --- [nio-8080-exec-7] org.hibernate.SQL : select * from user where andy=? Hibernate: select * from user where andy=? {id:1, name:超管, andy:123456, pass:$2a$10$JflS0yjBRY6yDRxdhAuHVunetrG2P6q8gj8HQzuaPtW8tt/OqO73S, role:0} 0 [{"authority":"ROLE_ADMIN"}] 0 com.kucun.Config.user.CustomUserDetails@5d3a4533123456 0 2025-05-29 16:10:34.013 DEBUG 33108 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/index.html", parameters={} 2025-05-29 16:10:34.019 DEBUG 33108 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.036 DEBUG 33108 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.077 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/fonts/font-awesome-4.7.0/css/font-awesome.min.css", parameters={} 2025-05-29 16:10:34.078 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.084 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.094 DEBUG 33108 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/util.css", parameters={} 2025-05-29 16:10:34.094 DEBUG 33108 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.098 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/main.css", parameters={} 2025-05-29 16:10:34.099 DEBUG 33108 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.101 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.103 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/index2.css", parameters={} 2025-05-29 16:10:34.105 DEBUG 33108 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.108 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.112 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jquery-3.2.1.min.js", parameters={} 2025-05-29 16:10:34.120 DEBUG 33108 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.117 DEBUG 33108 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jsyilai.js", parameters={} 2025-05-29 16:10:34.124 DEBUG 33108 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.145 DEBUG 33108 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.160 DEBUG 33108 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.160 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.279 DEBUG 33108 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/index.html", parameters={} 2025-05-29 16:10:34.280 DEBUG 33108 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.283 DEBUG 33108 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.349 DEBUG 33108 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/bootstrap-3.3.7-dist/js/MyTable.js", parameters={} 2025-05-29 16:10:34.350 DEBUG 33108 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.354 DEBUG 33108 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.351 DEBUG 33108 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/main.js?1748506234337&_=1748506234307", parameters={masked} 2025-05-29 16:10:34.356 DEBUG 33108 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.356 DEBUG 33108 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/index.js?1748506234340&_=1748506234308", parameters={masked} 2025-05-29 16:10:34.357 DEBUG 33108 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.358 DEBUG 33108 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.359 DEBUG 33108 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.448 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/check-session", parameters={} 2025-05-29 16:10:34.449 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.450 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found 2025-05-29 16:10:34.450 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND 2025-05-29 16:10:34.451 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for GET "/KuCun2/error", parameters={} 2025-05-29 16:10:34.451 DEBUG 33108 --- [nio-8080-exec-4] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2025-05-29 16:10:34.455 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json] 2025-05-29 16:10:34.456 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Thu May 29 16:10:34 CST 2025, status=404, error=Not Found, message=, path=/KuCun2/check-s (truncated)...] 2025-05-29 16:10:34.456 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 404 2025-05-29 16:10:34.754 DEBUG 33108 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/main/bootstrap-3.3.7-dist/css/bootstrap.css.map", parameters={} 2025-05-29 16:10:34.754 DEBUG 33108 --- [nio-8080-exec-7] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.758 DEBUG 33108 --- [nio-8080-exec-7] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found 2025-05-29 16:10:34.758 DEBUG 33108 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND 2025-05-29 16:10:34.765 DEBUG 33108 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/login.html", parameters={} 2025-05-29 16:10:34.768 DEBUG 33108 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.770 DEBUG 33108 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.763 DEBUG 33108 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for GET "/KuCun2/error", parameters={} 2025-05-29 16:10:34.773 DEBUG 33108 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2025-05-29 16:10:34.773 DEBUG 33108 --- [nio-8080-exec-7] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json] 2025-05-29 16:10:34.773 DEBUG 33108 --- [nio-8080-exec-7] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Thu May 29 16:10:34 CST 2025, status=404, error=Not Found, message=, path=/KuCun2/main/bo (truncated)...] 2025-05-29 16:10:34.787 DEBUG 33108 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 404 2025-05-29 16:10:34.823 DEBUG 33108 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/login.html", parameters={} 2025-05-29 16:10:34.824 DEBUG 33108 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.829 DEBUG 33108 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.984 DEBUG 33108 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/fonts/font-awesome-4.7.0/css/font-awesome.min.css", parameters={} 2025-05-29 16:10:34.985 DEBUG 33108 --- [nio-8080-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.986 DEBUG 33108 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/main.css", parameters={} 2025-05-29 16:10:34.986 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/css/util.css", parameters={} 2025-05-29 16:10:34.987 DEBUG 33108 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.987 DEBUG 33108 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:34.991 DEBUG 33108 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:34.994 DEBUG 33108 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jquery-3.2.1.min.js", parameters={} 2025-05-29 16:10:34.994 DEBUG 33108 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:35.009 DEBUG 33108 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:35.011 DEBUG 33108 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/jsyilai.js", parameters={} 2025-05-29 16:10:35.013 DEBUG 33108 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:35.019 DEBUG 33108 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:35.020 DEBUG 33108 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:35.024 DEBUG 33108 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:35.105 DEBUG 33108 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/images/bg-01.jpg", parameters={} 2025-05-29 16:10:35.106 DEBUG 33108 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:35.110 DEBUG 33108 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:35.123 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/main.js?1748506235115&_=1748506235076", parameters={masked} 2025-05-29 16:10:35.123 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:35.125 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2025-05-29 16:10:35.127 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/KuCun2/js/login.js?1748506235119&_=1748506235077", parameters={masked} 2025-05-29 16:10:35.128 DEBUG 33108 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/jsp/"] 2025-05-29 16:10:35.130 DEBUG 33108 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 200 OK
最新发布
05-31
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值