我的应用程序编译为 ROOT.war,这基本上意味着我没有除 / 之外的上下文根。有需要保护的页面;但是有些 URL 不需要它;例如我的http://localhost:8080/给出了这个应用程序的主页;并且有类似的页面,例如关于我们、联系我们等不需要安全性的页面。所以我将它添加到配置中
<security:intercept-url pattern="/" access="permitAll" />
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="/register/confirm" access="isAuthenticated()" />
<security:intercept-url pattern="/register/accept" access="isAuthenticated()" />
<security:intercept-url pattern="/shopper/**" access="isAuthenticated()" />
但这只是说允许用户“无需身份验证”访问这些 URL,如果您访问这些 URL,则安全过滤器都已应用,如下面的调试日志所示
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 1 of 12 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No HttpSession currently exists
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 3 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 4 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 5 of 12 in additional filter chain; firing Filter: 'OpenIDAuthenticationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG: org.springframework.security.web.authentication.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/'; against '/'
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /; Attributes: [permitAll]
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
DEBUG: org.springframework.security.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2b06c17b, returned: 1
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Authorization successful
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - RunAsManager did not change Authentication object
DEBUG: org.springframework.security.web.FilterChainProxy - / reached end of additional filter chain; proceeding with original chain
DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [/
]
当我尝试使用此配置时(按下面提到的顺序):
<!-- No Security required for the ROOT Context -->
<security:http pattern="/**" security="none" />
<!-- Apply secyrity for shopper URLs -->
<security:http auto-config="true" use-expressions="true" access-denied-page="/denied">
<security:intercept-url pattern="/" access="permitAll" />
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="/register/confirm" access="isAuthenticated()" />
<security:intercept-url pattern="/register/accept" access="isAuthenticated()" />
<security:intercept-url pattern="/shopper/**" access="isAuthenticated()" /
....
</security:http>
<security:http pattern="/resources/**" security="none" />
它打破了给出错误
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/auth/login'; against '/'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/auth/login'; against '/resources/**'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/auth/login'; against '/register/confirm'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/auth/login'; against '/register/accept'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/auth/login'; against '/shopper/**'
DEBUG: org.springframework.security.config.http.DefaultFilterChainValidator - No access attributes defined for login page URL
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5bebacc8: defining beans [placeholderConfig,dataSource,entityManagerFactory,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,registrationService,shopperService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.security.filterChains,org.springframework.security.filterChainProxy,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.core.session.SessionRegistryImpl#0,org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.openid.OpenIDAuthenticationFilter#0,org.springframework.security.openid.OpenIDAuthenticationProvider#0,org.springframework.security.userDetailsServiceFactory,org.springframework.security.web.DefaultSecurityFilterChain#0,org.springframework.security.web.DefaultSecurityFilterChain#1,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,passwordEncoder,registrationAwareUserDetailsService,registrationAwareAuthSuccessHandler,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
INFO : org.hibernate.impl.SessionFactoryImpl - closing
ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
我无法真正理解这背后的原因。我必须实现自己的请求模式匹配器吗?
解决方案
<beans:bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy" >
<beans:constructor-arg>
<beans:list>
<security:filter-chain pattern="/resources/**"
filters="none" />
<security:filter-chain pattern="/aboutus"
filters="none" />
<security:filter-chain pattern="/contactus"
filters="none" />
<security:filter-chain pattern="/news"
filters="none" />
</beans:list>
</beans:constructor-arg>
</beans:bean>