当前位置: 首页 > 工具软件 > login > 使用案例 >

踩坑记录 - 关于使用Spring security的一个坑(自定义登录页面访问配置的login.do报404)

邵献
2023-12-01

今天分享一个使用Spring security的一个坑。。。
废话不说,上代码:

<!-- 登录页面login.html -->
<form id="login-form" action="/login.do">
	用户名:<input type="text" name="username"/>
	<br>
	密码:<input type="password" name="password"/>
	<br>
	<input type="submit" value="登录"/>
</form>

为了方便说明,登录页面的代码我没有加上css、js。

<!--security的配置:自定义登录表单信息-->
<security:form-login
         login-page="/login.html"
         username-parameter="username"
         password-parameter="password"
         login-processing-url="/login.do"
         default-target-url="/index.html"
         always-use-default-target="true"
         authentication-failure-url="/login.html"
 />

其中,login-processing-url="/login.do"是点击登录按钮时,访问的url。



重点来了!!!

我点了登录按钮后。页面直接404 NOT FOUND。。。。控制台打印的完整日志如下:


2020-03-22 11:01:23,501 DEBUG DefaultListableBeanFactory.doGetBean():254 - Returning cached instance of singleton bean 'environment'
2020-03-22 11:01:23,503 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/js/**'
2020-03-22 11:01:23,503 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/plugins/**'
2020-03-22 11:01:23,503 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/css/**'
2020-03-22 11:01:23,503 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/img/**'
2020-03-22 11:01:23,503 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/login.html'
2020-03-22 11:01:23,503 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/index.html'
2020-03-22 11:01:23,503 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 1 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-03-22 11:01:23,503 DEBUG HttpSessionSecurityContextRepository.readSecurityContextFromSession():186 - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2020-03-22 11:01:23,503 DEBUG HttpSessionSecurityContextRepository.loadContext():116 - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@572ca96a. A new one will be created.
2020-03-22 11:01:23,504 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 2 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-03-22 11:01:23,504 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-03-22 11:01:23,504 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2020-03-22 11:01:23,504 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/logout.do'
2020-03-22 11:01:23,504 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2020-03-22 11:01:23,504 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/login.do'
2020-03-22 11:01:23,504 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2020-03-22 11:01:23,504 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-03-22 11:01:23,505 DEBUG DefaultSavedRequest.propertyEquals():364 - pathInfo: both null (property equals)
2020-03-22 11:01:23,505 DEBUG DefaultSavedRequest.propertyEquals():364 - queryString: both null (property equals)
2020-03-22 11:01:23,505 DEBUG DefaultSavedRequest.propertyEquals():388 - requestURI: arg1=/pages/report-info.html; arg2=/member/login.do (property not equals)
2020-03-22 11:01:23,505 DEBUG HttpSessionRequestCache.getMatchingRequest():98 - saved request doesn't match
2020-03-22 11:01:23,505 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-03-22 11:01:23,505 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-03-22 11:01:23,505 DEBUG AnonymousAuthenticationFilter.doFilter():100 - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@c03c45e3: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 61A162389B7A17D1EE3E5348C77C7FB5; Granted Authorities: ROLE_ANONYMOUS'
2020-03-22 11:01:23,505 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-03-22 11:01:23,505 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-03-22 11:01:23,505 DEBUG FilterChainProxy.doFilter():328 - /member/login.do at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-03-22 11:01:23,505 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/pages/health-inquiry.html'
2020-03-22 11:01:23,506 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/pages/order-inquiry.html'
2020-03-22 11:01:23,506 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/member/login.do'; against '/pages/report-info.html'
2020-03-22 11:01:23,506 DEBUG FilterSecurityInterceptor.beforeInvocation():210 - Public object - authentication not attempted
2020-03-22 11:01:23,506 DEBUG FilterChainProxy.doFilter():313 - /member/login.do reached end of additional filter chain; proceeding with original chain
2020-03-22 11:01:23,506 DEBUG DispatcherServlet.doService():891 - DispatcherServlet with name 'spring-mvc' processing POST request for [/member/login.do]
2020-03-22 11:01:23,506 DEBUG RequestMappingHandlerMapping.getHandlerInternal():312 - Looking up handler method for path /member/login.do
2020-03-22 11:01:23,507 DEBUG RequestMappingHandlerMapping.getHandlerInternal():319 - Returning handler method [public cn.skywalker.entity.Result cn.skywalker.controller.MemberController.login(javax.servlet.http.HttpServletResponse,java.util.Map)]
2020-03-22 11:01:23,507 DEBUG DefaultListableBeanFactory.doGetBean():254 - Returning cached instance of singleton bean 'memberController'
2020-03-22 11:01:23,507 DEBUG DefaultCorsProcessor.processRequest():77 - Skip CORS processing: request is from same origin
2020-03-22 11:01:23,508 DEBUG RequestResponseBodyMethodProcessor.readWithMessageConverters():201 - Read [interface java.util.Map] as "application/json;charset=UTF-8" with [com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter@5f78e2c2]
2020-03-22 11:01:23,508 DEBUG AnnotationUtils.handleIntrospectionFailure():1889 - Failed to meta-introspect annotation interface org.springframework.web.bind.annotation.RequestBody: java.lang.NullPointerException
2020-03-22 11:01:23,880 DEBUG DecodeHandler.decode():58 -  [DUBBO] Decode decodeable message com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult, dubbo version: 2.6.0, current host: 169.254.245.239
2020-03-22 11:01:24,196 DEBUG DecodeHandler.decode():58 -  [DUBBO] Decode decodeable message com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult, dubbo version: 2.6.0, current host: 169.254.245.239
2020-03-22 11:01:24,314 DEBUG HstsHeaderWriter.writeHeaders():129 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@245f5db2
2020-03-22 11:01:24,314 DEBUG HttpSessionSecurityContextRepository.saveContext():352 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-03-22 11:01:24,314 DEBUG RequestResponseBodyMethodProcessor.writeWithMessageConverters():277 - Written [cn.skywalker.entity.Result@60d5cc42] as "application/json" using [com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter@5f78e2c2]
2020-03-22 11:01:24,315 DEBUG DispatcherServlet.processDispatchResult():1076 - Null ModelAndView returned to DispatcherServlet with name 'spring-mvc': assuming HandlerAdapter completed request handling
2020-03-22 11:01:24,315 DEBUG DispatcherServlet.processRequest():1000 - Successfully completed request
2020-03-22 11:01:24,315 DEBUG ExceptionTranslationFilter.doFilter():121 - Chain processed normally
2020-03-22 11:01:24,315 DEBUG SecurityContextPersistenceFilter.doFilter():119 - SecurityContextHolder now cleared, as request processing completed
2020-03-22 11:01:24,329 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/js/**'
2020-03-22 11:01:24,329 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/plugins/**'
2020-03-22 11:01:24,329 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/css/**'
2020-03-22 11:01:24,329 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/img/**'
2020-03-22 11:01:24,329 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/login.html'
2020-03-22 11:01:24,329 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/index.html'
2020-03-22 11:01:24,330 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 1 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-03-22 11:01:24,330 DEBUG HttpSessionSecurityContextRepository.readSecurityContextFromSession():186 - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2020-03-22 11:01:24,330 DEBUG HttpSessionSecurityContextRepository.loadContext():116 - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@572ca96a. A new one will be created.
2020-03-22 11:01:24,330 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 2 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-03-22 11:01:24,330 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-03-22 11:01:24,330 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2020-03-22 11:01:24,330 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/logout.do'
2020-03-22 11:01:24,330 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2020-03-22 11:01:24,330 DEBUG AntPathRequestMatcher.matches():137 - Request 'GET /login.do' doesn't match 'POST /login.do
2020-03-22 11:01:24,331 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2020-03-22 11:01:24,331 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-03-22 11:01:24,331 DEBUG DefaultSavedRequest.propertyEquals():364 - pathInfo: both null (property equals)
2020-03-22 11:01:24,331 DEBUG DefaultSavedRequest.propertyEquals():372 - queryString: arg1=null; arg2=username=15516533934&password=954355 (property not equals)
2020-03-22 11:01:24,331 DEBUG HttpSessionRequestCache.getMatchingRequest():98 - saved request doesn't match
2020-03-22 11:01:24,331 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-03-22 11:01:24,331 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-03-22 11:01:24,331 DEBUG AnonymousAuthenticationFilter.doFilter():100 - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@c03c45e3: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 61A162389B7A17D1EE3E5348C77C7FB5; Granted Authorities: ROLE_ANONYMOUS'
2020-03-22 11:01:24,331 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-03-22 11:01:24,332 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-03-22 11:01:24,332 DEBUG FilterChainProxy.doFilter():328 - /login.do?username=15516533934&password=954355 at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-03-22 11:01:24,332 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/pages/health-inquiry.html'
2020-03-22 11:01:24,332 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/pages/order-inquiry.html'
2020-03-22 11:01:24,332 DEBUG AntPathRequestMatcher.matches():157 - Checking match of request : '/login.do'; against '/pages/report-info.html'
2020-03-22 11:01:24,332 DEBUG FilterSecurityInterceptor.beforeInvocation():210 - Public object - authentication not attempted
2020-03-22 11:01:24,332 DEBUG FilterChainProxy.doFilter():313 - /login.do?username=15516533934&password=954355 reached end of additional filter chain; proceeding with original chain
2020-03-22 11:01:24,332 DEBUG DispatcherServlet.doService():891 - DispatcherServlet with name 'spring-mvc' processing GET request for [/login.do]
2020-03-22 11:01:24,333 DEBUG RequestMappingHandlerMapping.getHandlerInternal():312 - Looking up handler method for path /login.do
2020-03-22 11:01:24,333 DEBUG RequestMappingHandlerMapping.getHandlerInternal():322 - Did not find handler method for [/login.do]
2020-03-22 11:01:24,333  WARN PageNotFound.noHandlerFound():1205 - No mapping found for HTTP request with URI [/login.do] in DispatcherServlet with name 'spring-mvc'
2020-03-22 11:01:24,333 DEBUG HstsHeaderWriter.writeHeaders():129 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@245f5db2
2020-03-22 11:01:24,333 DEBUG HttpSessionSecurityContextRepository.saveContext():352 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-03-22 11:01:24,333 DEBUG DispatcherServlet.processRequest():1000 - Successfully completed request
2020-03-22 11:01:24,334 DEBUG ExceptionTranslationFilter.doFilter():121 - Chain processed normally
2020-03-22 11:01:24,334 DEBUG SecurityContextPersistenceFilter.doFilter():119 - SecurityContextHolder now cleared, as request processing completed

这的确是spring security拦截一次请求后,控制台打印的完整日志,稍微有点多,有时候感觉无从下手,第一反应看了一下WARN级别的日志,是这个:

2020-03-22 11:01:24,333  WARN PageNotFound.noHandlerFound():1205 - No mapping found for HTTP request with URI [/login.do] in DispatcherServlet with name 'spring-mvc'

说找不到uri的映射关系。
然后我就困惑了,spring security登录表单的映射不应该是security框架自动帮我们做好了吗?
在经历了一下午加一晚上的查找资料、不断调试后,我终于放弃了。。
不过我确定了一点:
问题原因肯定是no mapping found,但是一定不会是因为security框架没有为我们做映射。
今天早上调试的时候,又认真分析了一下完整的日志信息。果然从一个隐藏的很深的地方找到了突破口:

2020-03-22 11:01:24,330 DEBUG AntPathRequestMatcher.matches():137 - Request 'GET /login.do' doesn't match 'POST /login.do

这是什么!!!
我差点就没忍住口吐芬芳。。。
然后我才突然想到,html中form表单的默认提交方式是GET,而通过上面那行日志,不难看出,在spring security中配置自定义登录的时候,登录请求方式必须为POST,怪不得404 NOT FOUND ,GET方式的请求spring security并不能正确的匹配到(match)。

解决方式

在登录表单添加method="post"即可。

<!-- 登录页面login.html -->
<form id="login-form" action="/login.do" method="post">
	用户名:<input type="text" name="username"/>
	<br>
	密码:<input type="password" name="password"/>
	<br>
	<input type="submit" value="登录"/>
</form>

总结

这行关键的日志,在上面完整的日志里面能找到,当时只关注到了WARN级别的日志,而且就那一条WARN,没怎么注意看DEBUG日志。整体的日志确实有点多,找到有用的确实不容易,但是,我们程序员的优秀品质不就体现在这里么?细心与耐心的结合,对于bug至死方休!加油,共勉!

 类似资料: