【发布时间】:2018-07-17 13:36:30
【问题描述】:
我有一个项目完全跳过了 Spring 安全性的使用并手动处理事情。
不过,现在我想将 Spring Security 合并到我的项目中。完成所有操作后,将显示默认登录表单,并且我设法让用户使用 UserDetailsService 实现(我的代码中的 userLoginService)进行身份验证。我已经完成了调试步骤,以确保 Spring 正确地对用户进行身份验证。
但是,在身份验证后重定向到受保护的端点时,Spring 再次将我重定向到登录页面,就好像从未执行过身份验证一样。我已经研究了 3 天了,我已经感到很累了。下图显示了对身份验证端点的 POST 调用,重定向到受保护的端点 (/),然后再次重定向到登录表单。
我使用的是Spring Security 3.2.7,我的应用是通过xml配置的。
我对 xml 配置的经验真的很缺乏,在参考了 Spring Security 3 和 4 之后,我一直无法发现为什么这种情况一直发生。我最好的猜测是这个角色以某种方式把事情搞混了,但我对此一无所知。
我发现的东西:
- 我已经调试到密码在内部匹配,并且还检查了经过身份验证的字段是否为真,它确实做到了。
- 如果我将 (/merchants) 置于此保护之外,则身份验证对象将返回匿名身份验证
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();。 - 身份验证失败可以正常工作。
以下是代码:
spring-security.xml
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http use-expression="true">
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"/>
<form-login />
<csrf />
</http>
<authentication-manager>
<authentication-provider user-service-ref="userLoginService">
<password-encoder hash="sha-256"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
调度程序-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<context:component-scan base-package="com.example.panel"/>
<import resource="applicationContext.xml"/>
<context:property-placeholder location="classpath:message.properties"/>
<mvc:resources mapping="/media/**" location="/WEB-INF/media/"/>
<mvc:annotation-driven/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/media/**"/>
<mvc:exclude-mapping path="/user/test"/>
<mvc:exclude-mapping path="/user/some-mapping"/>
<bean class="com.example.panel.interceptor.Interceptor">
<property name="some-map" ref="map-list"/>
</bean>
</mvc:interceptor>
</mvc:interceptors>
.... other beans here
<util:map id="mapList">
<entry key="1" value-ref="ADMIN"/>
........................
</util:map>
还有我的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<listener>
<listener-class> org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring-security.xml,
classpath:dispatcher-servlet.xml,
classpath:applicationContext.xml
</param-value>
</context-param>
<welcome-file-list>
<welcome-file>/</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>60</session-timeout>
<tracking-mode>SSL</tracking-mode>
</session-config>
<!--Multipart Filter-->
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<init-param>
<param-name>multipartResolverBeanName</param-name>
<param-value>multipartResolver</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- MDC INSERTING SERVLET FILTER -->
<filter>
<filter-name>MDCInsertingServletFilter</filter-name>
<filter-class>
ch.qos.logback.classic.helpers.MDCInsertingServletFilter
</filter-class>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>MDCInsertingServletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring Security -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<security-constraint>
<web-resource-collection>
<web-resource-name>panel</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
而我的 applicationContext.xml 只包含一些 bean 声明。
我可以做些什么来修复这个应用程序的安全性?在此先感谢:)
更新
春季安全日志
2018-02-08 09:37:19 [INFO] Spring Security Debugger line: 39 -
************************************************************
Request received for GET '/spring_security_login':
org.apache.catalina.connector.RequestFacade@5e366601
servletPath:/spring_security_login
pathInfo:null
headers:
host: localhost:8443
user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8
accept-language: en-US,en;q=0.7,bn;q=0.3
accept-encoding: gzip, deflate, br
referer: https://localhost:8443/panel/spring_security_login
cookie: Idea-e04cc54f=d38290c3-dd3e-450f-b445-765ae8b09682; JSESSIONID=4DFA0CA25924C875A75D36369AC3B7D8
dnt: 1
connection: keep-alive
upgrade-insecure-requests: 1
cache-control: max-age=0
Security filter chain: [
SecurityContextPersistenceFilter
WebAsyncManagerIntegrationFilter
CsrfFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2018-02-08 09:37:39 [INFO] Spring Security Debugger line: 39 -
************************************************************
Request received for POST '/j_spring_security_check':
org.apache.catalina.connector.RequestFacade@5e366601
servletPath:/j_spring_security_check
pathInfo:null
headers:
host: localhost:8443
user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8
accept-language: en-US,en;q=0.7,bn;q=0.3
accept-encoding: gzip, deflate, br
referer: https://localhost:8443/panel/spring_security_login
content-type: application/x-www-form-urlencoded
content-length: 92
cookie: Idea-e04cc54f=d38290c3-dd3e-450f-b445-765ae8b09682; JSESSIONID=4DFA0CA25924C875A75D36369AC3B7D8
dnt: 1
connection: keep-alive
upgrade-insecure-requests: 1
Security filter chain: [
SecurityContextPersistenceFilter
WebAsyncManagerIntegrationFilter
CsrfFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2018-02-08 09:37:39 [INFO] c.d.b.s.UserLoginService line: 40 - login => org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN
2018-02-08 09:37:39 [INFO] Spring Security Debugger line: 39 -
************************************************************
Request received for GET '/':
org.apache.catalina.connector.RequestFacade@5e366601
servletPath:/
pathInfo:null
headers:
host: localhost:8443
user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8
accept-language: en-US,en;q=0.7,bn;q=0.3
accept-encoding: gzip, deflate, br
referer: https://localhost:8443/panel/spring_security_login
cookie: Idea-e04cc54f=d38290c3-dd3e-450f-b445-765ae8b09682; JSESSIONID=4DFA0CA25924C875A75D36369AC3B7D8
dnt: 1
connection: keep-alive
upgrade-insecure-requests: 1
Security filter chain: [
SecurityContextPersistenceFilter
WebAsyncManagerIntegrationFilter
CsrfFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2018-02-08 09:37:39 [INFO] Spring Security Debugger line: 39 -
************************************************************
New HTTP session created: 5a7bc5959c07bb1757b60ce4e3091b65bdecee60fae8302527be62c6894f5915
Call stack:
at org.springframework.security.web.debug.Logger.info(Logger.java:29)
at org.springframework.security.web.debug.DebugRequestWrapper.getSession(DebugFilter.java:144)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at org.springframework.security.web.savedrequest.HttpSessionRequestCache.saveRequest(HttpSessionRequestCache.java:40)
at org.springframework.security.web.access.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:184)
at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:168)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:131)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.security.web.debug.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:70)
at org.springframework.security.web.debug.DebugFilter.doFilter(DebugFilter.java:59)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:118)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:616)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:285)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
************************************************************
2018-02-08 09:37:39 [INFO] Spring Security Debugger line: 39 -
************************************************************
Request received for GET '/spring_security_login':
org.apache.catalina.connector.RequestFacade@5e366601
servletPath:/spring_security_login
pathInfo:null
headers:
host: localhost:8443
user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8
accept-language: en-US,en;q=0.7,bn;q=0.3
accept-encoding: gzip, deflate, br
referer: https://localhost:8443/panel/spring_security_login
cookie: Idea-e04cc54f=d38290c3-dd3e-450f-b445-765ae8b09682; JSESSIONID=4DFA0CA25924C875A75D36369AC3B7D8
dnt: 1
connection: keep-alive
upgrade-insecure-requests: 1
Security filter chain: [
SecurityContextPersistenceFilter
WebAsyncManagerIntegrationFilter
CsrfFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2018-02-08 10:25:03 [DEBUG] o.s.s.w.FilterChainProxy line: 337 - /spring_security_login at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-02-08 10:25:03 [DEBUG] o.s.s.w.c.HttpSessionSecurityContextRepository line: 152 - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-02-08 10:25:03 [DEBUG] o.s.s.w.c.HttpSessionSecurityContextRepository line: 91 - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@3078ac38. A new one will be created.
2018-02-08 10:25:03 [DEBUG] o.s.s.w.FilterChainProxy line: 337 - /spring_security_login at position 2 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-02-08 10:25:03 [DEBUG] o.s.s.w.FilterChainProxy line: 337 - /spring_security_login at position 3 of 11 in additional filter chain; firing Filter: 'CsrfFilter'
2018-02-08 10:25:03 [DEBUG] o.s.s.w.FilterChainProxy line: 337 - /spring_security_login at position 4 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2018-02-08 10:25:03 [DEBUG] o.s.s.w.FilterChainProxy line: 337 - /spring_security_login at position 5 of 11 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2018-02-08 10:25:03 [DEBUG] o.s.s.w.c.HttpSessionSecurityContextRepository line: 304 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-02-08 10:25:03 [DEBUG] o.s.s.w.c.SecurityContextPersistenceFilter line: 97 - SecurityContextHolder now cleared, as request processing completed
第二次更新
如果我按照this answer 回滚到 Spring security 3.1.2.Release,它会成功运行。但是但是,3.1.2 不包括csrf 支持。因此,我的目标是让它与 Spring Security 3.2(或更高版本,默认支持 csrf)一起使用。
第三次更新
您可以找到 Spring Security 版本 3.1.2 和 3.2.5 in the gist here 的日志。
因为它被标记为重复
Spring security 在 3.1 版本之后有很多版本。我不想相信身份验证在所有这些更新中都不起作用(尤其是在 3.2 版本中都不起作用),当然,它们确实起作用了。现在,回滚显示我的 spring security xml 并没有完全错误地编写。但相反,我想弄清楚是什么导致了这个问题,并相应地处理事情。当然回滚不是解决方案。引用的问题建议回滚 - 我根本不在寻找解决方案。
附:如果您需要查看或了解任何其他代码/信息,请告诉我。
第四次更新
我完全放弃了所有剩余的 xml 配置并放入基于 Java 的配置。现在一切都按预期工作。为一个简单的 xml 配置经历这一切根本不值得。
【问题讨论】:
-
@dur 我已经将该问题中的答案作为更新引用,并且还提到了这不能满足我的要求。
-
Spring security 在 3.1 版本之后有超过 10 个版本。我不想相信身份验证在所有这些更新中都不起作用,当然,它们确实起作用了。现在,回滚显示我的 spring security 并没有完全错误地编写。但相反,我想弄清楚是什么导致了这个问题,并相应地处理事情。当然回滚不是解决方案。
-
我有,结果是一样的。 Spring security 主要用于身份验证,一直有一个失败的身份验证模块会很有趣。
-
@dur 这个复杂性导致我删除所有 xml 配置并插入 java 配置和 spring 安全工作。谢谢你的时间:)
标签: java spring authentication spring-security xml-configuration