问题描述
我想在Spring Security(3.1.0)中使用略微定制的记住我"功能.
I want to use a slightly customized rememberme functionality with spring security (3.1.0).
我这样声明"rememberme"标签:
I declare the rememberme tag like this:
<security:remember-me key="JNJRMBM" user-service-ref="gymUserDetailService" />
由于我拥有自己的Rememberme服务,因此需要将其注入到我这样定义的RememberMeAuthenticationFilter中:
As I have my own rememberme service I need to inject that into the RememberMeAuthenticationFilter which I define like this:
<bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="gymRememberMeService"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
我在我的web.xml中以标准方式集成了Spring Security:
I have spring security integrated in a standard way in my web.xml:
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
一切正常,除了RememberMeAuthenticationFilter使用标准的RememberMeService,所以我认为未使用我定义的RememberMeAuthenticationFilter.
Everything works fine, except that the RememberMeAuthenticationFilter uses the standard RememberMeService, so I think that my defined RememberMeAuthenticationFilter is not being used.
如何确保使用过滤器的定义?我需要创建自定义滤镜链吗?如果是这样,如何查看我当前的隐式"过滤器链,并确保使用与我的RememberMeAuthenticationFilter相同的过滤器链(而不是默认的过滤链)?
How can I make sure that my definition of the filter is being used?Do I need to create a custom filterchain?And if so, how can I see my current "implicit" filterchain and make sure I use the same one except my RememberMeAuthenticationFilter instead of the default one?
感谢任何建议和/或指示!
Thanks for any advice and/or pointers!
这是完整的spring-security.xml:
Here the complete spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http pattern="/_ui/**" security="none" />
<!-- Default security config -->
<security:http disable-url-rewriting="true">
<security:anonymous username="anonymous" granted-authority="ROLE_ANONYMOUS" />
<!-- session stealing is prevented by using secure GUID cookie -->
<security:session-management session-fixation-protection="none" />
<!-- SSL / AUTHENTICATED pages -->
<security:intercept-url pattern="/my-account*" access="ROLE_CUSTOMERGROUP" requires-channel="https" />
<security:intercept-url pattern="/my-account/**" access="ROLE_CUSTOMERGROUP" requires-channel="https" />
<!-- SSL / ANONYMOUS pages Login pages need to be SSL, but occur before authentication -->
<security:intercept-url pattern="/login" requires-channel="https" />
<security:intercept-url pattern="/login/**" requires-channel="https" />
<security:intercept-url pattern="/register" requires-channel="https" />
<security:intercept-url pattern="/register/**" requires-channel="https" />
<security:intercept-url pattern="/j_spring_security_check" requires-channel="https" />
<security:intercept-url pattern="/logout" requires-channel="https" />
<!-- MiniCart and CartPopup can occur on either secure or insecure pages -->
<security:intercept-url pattern="/cart/rollover/*" requires-channel="any" />
<security:intercept-url pattern="/cart/miniCart/*" requires-channel="any" />
<security:intercept-url pattern="/cart/show" requires-channel="any" />
<security:intercept-url pattern="/cart/lightboxmybag" requires-channel="any" />
<security:intercept-url pattern="/cart/remove/*" requires-channel="any" />
<security:intercept-url pattern="/cart/update/*" requires-channel="any" />
<security:intercept-url pattern="/cart/getProductSizes/**" requires-channel="any" />
<security:intercept-url pattern="/cart/getShippingMethods" requires-channel="any" />
<security:intercept-url pattern="/cart/setShippingMethod" requires-channel="any" />
<security:intercept-url pattern="/cart/applyVoucherDiscount" requires-channel="any" />
<security:intercept-url pattern="/cart/removeVoucherDiscount" requires-channel="any" />
<security:intercept-url pattern="/checkout/**" requires-channel="https" />
<!-- product suggest -->
<security:intercept-url pattern="/suggest*" requires-channel="any" />
<!-- cybersource response -->
<security:intercept-url pattern="/cybersource/response" requires-channel="any" />
<security:intercept-url pattern="/cybersource/csResponse" requires-channel="http" />
<!-- regions -->
<security:intercept-url pattern="/regions*" requires-channel="any" />
<security:intercept-url pattern="/regions/*" requires-channel="any" />
<!-- popup links -->
<security:intercept-url pattern="/popupLink/*" requires-channel="any" />
<!-- addresses -->
<security:intercept-url pattern="/my-addresses*" requires-channel="any" />
<security:intercept-url pattern="/my-addresses/**" requires-channel="any" />
<security:intercept-url pattern="/search/autocompleteSecure/**" requires-channel="https" />
<!-- OPEN / ANONYMOUS pages Run all other (public) pages openly. Note that while credentials are secure, the session id can be sniffed.
If this is a security concern, then this line should be re-considered -->
<security:intercept-url pattern="/**" requires-channel="any" method="POST" /> <!-- Allow posts on either secure or insecure -->
<security:intercept-url pattern="/**" requires-channel="http" /> <!-- Everything else should be insecure -->
<security:form-login
login-page="/login"
authentication-failure-handler-ref="loginAuthenticationFailureHandler"
authentication-success-handler-ref="loginGuidAuthenticationSuccessHandler" />
<security:logout logout-url="/logout" success-handler-ref="logoutSuccessHandler" />
<security:port-mappings>
<security:port-mapping http="#{configurationService.configuration.getProperty('tomcat.http.port')}"
https="#{configurationService.configuration.getProperty('tomcat.ssl.port')}" />
<security:port-mapping http="80" https="443" />
<!--security:port-mapping http="#{configurationService.configuration.getProperty('proxy.http.port')}"
https="#{configurationService.configuration.getProperty('proxy.ssl.port')}" /-->
</security:port-mappings>
<security:request-cache ref="httpSessionRequestCache" />
<security:remember-me key="JNJRMBM" user-service-ref="gymUserDetailService" />
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="acceleratorAuthenticationProvider" />
</security:authentication-manager>
<bean id="acceleratorAuthenticationProvider" class="org.jnj.storefront.security.AcceleratorAuthenticationProvider"
scope="tenant">
<property name="userDetailsService" ref="gymUserDetailService" />
<property name="adminGroup" value="ROLE_ADMINGROUP"/>
<property name="userService" ref="userService"/>
<property name="gymCustomerLoginService" ref="defaultGymCustomerLoginService"/>
</bean>
<bean id="gymUserDetailService" class="org.jnj.storefront.security.services.impl.GymCoreUserDetailsService" scope="tenant">
<property name="baseDao" ref="asyBaseDao" />
</bean>
<bean id="coreUserDetailsService" class="de.hybris.platform.spring.security.CoreUserDetailsService" scope="tenant" />
<bean id="guidCookieStrategy" class="org.jnj.storefront.security.impl.DefaultGUIDCookieStrategy"
scope="tenant">
<property name="cookieGenerator" ref="guidCookieGenerator" />
</bean>
<alias name="defaultGuidCookieGenerator" alias="guidCookieGenerator"/>
<bean id="defaultGuidCookieGenerator" class="org.jnj.storefront.security.cookie.EnhancedCookieGenerator" scope="tenant">
<property name="cookieSecure" value="true" />
<property name="cookieName" value="acceleratorSecureGUID" />
<property name="httpOnly" value="false"/>
<!-- if context allows a httpOnly adjust to true -->
</bean>
<bean id="autoLoginStrategy" class="org.jnj.storefront.security.impl.DefaultAutoLoginStrategy" scope="tenant">
</bean>
<bean id="httpSessionRequestCache" class="org.jnj.storefront.security.impl.WebHttpSessionRequestCache"
scope="tenant" />
<bean id="loginUserType" class="org.jnj.storefront.security.impl.LoginUserTypeBean" scope="tenant" />
<bean id="redirectStrategy" class="org.springframework.security.web.DefaultRedirectStrategy" scope="tenant" />
<!-- Login Success Handlers -->
<bean id="loginGuidAuthenticationSuccessHandler" class="org.jnj.storefront.security.GUIDAuthenticationSuccessHandler" scope="tenant">
<property name="authenticationSuccessHandler" ref="loginAuthenticationSuccessHandler" />
<property name="guidCookieStrategy" ref="guidCookieStrategy" />
</bean>
<bean id="loginAuthenticationSuccessHandler" class="org.jnj.storefront.security.StorefrontAuthenticationSuccessHandler" scope="tenant">
<property name="customerFacade" ref="customerFacade" />
<property name="defaultTargetUrl" value="/my-account"/>
<property name="useReferer" value="true"/>
<property name="alwaysUseDefaultTargetUrl" value="false"/>
<property name="requestCache" ref="httpSessionRequestCache" />
</bean>
<bean id="loginCheckoutGuidAuthenticationSuccessHandler" class="org.jnj.storefront.security.GUIDAuthenticationSuccessHandler" scope="tenant">
<property name="authenticationSuccessHandler" ref="loginCheckoutAuthenticationSuccessHandler" />
<property name="guidCookieStrategy" ref="guidCookieStrategy" />
<property name="defaultGymCartFacade" ref="gymCartFacade"/>
</bean>
<bean id="loginCheckoutAuthenticationSuccessHandler" class="org.jnj.storefront.security.StorefrontAuthenticationSuccessHandler" scope="tenant">
<property name="customerFacade" ref="customerFacade" />
<property name="defaultTargetUrl" value="/checkout/single/summary"/>
</bean>
<!-- Login Failure Handlers -->
<bean id="loginAuthenticationFailureHandler" class="org.jnj.storefront.security.LoginAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login?error=auth"/>
<property name="accountBlockedUrl" value="/login?error=blocked"/>
<property name="passwordMigrationUrl" value="/login?error=migration"/>
</bean>
<bean id="loginCheckoutAuthenticationFailureHandler" class="org.jnj.storefront.security.LoginAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login/checkout?error=auth"/>
<property name="accountBlockedUrl" value="/login/checkout?error=blocked"/>
<property name="passwordMigrationUrl" value="/login/checkout?error=migration"/>
</bean>
<!-- Logout Success Handler -->
<bean id="logoutSuccessHandler" class="org.jnj.storefront.security.StorefrontLogoutSuccessHandler" scope="tenant">
<property name="defaultTargetUrl" value="/?logout=true"/>
<property name="guidCookieStrategy" ref="guidCookieStrategy"/>
<property name="cmsSiteService" ref="cmsSiteService"/>
</bean>
<bean id="gymRememberMeService" class="org.jnj.storefront.security.cookie.DefaultRememberMeService" scope="tenant">
<property name="tokenService" ref="secureTokenService" />
<property name="rememberMeCookieGenerator" ref="defaultRememberMeCookieGenerator" />
</bean>
<bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="gymRememberMeService"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
推荐答案
我最终不得不显式声明form-login和Remember-me标记,并在过滤器链中对其进行声明.
I ended up having to declare both the form-login and the remember-me tags explicitly and declare them in the filter chain.
因此,我不得不将相应的过滤器声明为bean,而不是标签和标签,对其进行相应配置,然后使用标签在过滤器链中的相应位置定义它们.(如果使用自定义过滤器标签和显式标签,则在启动时会出现spring错误).
so instead of the tag and the tag I had to declare the respective filters as beans, configure them accordingly and then define them in their respective position in the filterchain with the tag.(If you use custom-filter tags and the explicit tags you get spring errors during startup time).
这对我有用:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http pattern="/_ui/**" security="none" />
<!-- Default security config -->
<security:http disable-url-rewriting="true" entry-point-ref="gymAuthenticationEntryPoint">
<!-- using custom login filter config and rememberme filter config -->
<security:custom-filter ref="gymRememberMeFilter" position="REMEMBER_ME_FILTER"/>
<security:custom-filter ref="gymAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
<security:anonymous username="anonymous" granted-authority="ROLE_ANONYMOUS" />
<!-- session stealing is prevented by using secure GUID cookie -->
<security:session-management session-fixation-protection="none" />
<!-- SSL / AUTHENTICATED pages -->
<security:intercept-url pattern="/my-account*" access="ROLE_CUSTOMERGROUP" requires-channel="https" />
<!-- omitting intercept definitions for readability -->
<!-- use explicit FORM_LOGIN_FILTER (see above) and entry-point (see entry-point-ref in http tag) instead of form-login definition
<security:form-login
login-page="/login"
authentication-failure-handler-ref="loginAuthenticationFailureHandler"
authentication-success-handler-ref="loginGuidAuthenticationSuccessHandler" />
-->
<security:logout logout-url="/logout" success-handler-ref="logoutSuccessHandler" />
<security:port-mappings>
<security:port-mapping http="#{configurationService.configuration.getProperty('tomcat.http.port')}"
https="#{configurationService.configuration.getProperty('tomcat.ssl.port')}" />
<security:port-mapping http="80" https="443" />
<!--security:port-mapping http="#{configurationService.configuration.getProperty('proxy.http.port')}"
https="#{configurationService.configuration.getProperty('proxy.ssl.port')}" /-->
</security:port-mappings>
<security:request-cache ref="httpSessionRequestCache" />
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="acceleratorAuthenticationProvider" />
<security:authentication-provider ref="rememberMeAuthenticationProvider" />
</security:authentication-manager>
<bean id="acceleratorAuthenticationProvider" class="org.jnj.storefront.security.AcceleratorAuthenticationProvider"
scope="tenant">
<property name="userDetailsService" ref="gymUserDetailService" />
<property name="adminGroup" value="ROLE_ADMINGROUP"/>
<property name="userService" ref="userService"/>
<property name="gymCustomerLoginService" ref="defaultGymCustomerLoginService"/>
</bean>
<bean id="gymUserDetailService" class="org.jnj.storefront.security.services.impl.GymCoreUserDetailsService" scope="tenant">
<property name="baseDao" ref="asyBaseDao" />
</bean>
<bean id="coreUserDetailsService" class="de.hybris.platform.spring.security.CoreUserDetailsService" scope="tenant" />
<!-- Login Success Handlers -->
<bean id="loginGuidAuthenticationSuccessHandler" class="org.jnj.storefront.security.GUIDAuthenticationSuccessHandler" scope="tenant">
<property name="authenticationSuccessHandler" ref="loginAuthenticationSuccessHandler" />
<property name="guidCookieStrategy" ref="guidCookieStrategy" />
</bean>
<bean id="loginAuthenticationSuccessHandler" class="org.jnj.storefront.security.StorefrontAuthenticationSuccessHandler" scope="tenant">
<property name="customerFacade" ref="customerFacade" />
<property name="defaultTargetUrl" value="/my-account"/>
<property name="useReferer" value="true"/>
<property name="alwaysUseDefaultTargetUrl" value="false"/>
<property name="requestCache" ref="httpSessionRequestCache" />
</bean>
<bean id="loginCheckoutGuidAuthenticationSuccessHandler" class="org.jnj.storefront.security.GUIDAuthenticationSuccessHandler" scope="tenant">
<property name="authenticationSuccessHandler" ref="loginCheckoutAuthenticationSuccessHandler" />
<property name="guidCookieStrategy" ref="guidCookieStrategy" />
<property name="defaultGymCartFacade" ref="gymCartFacade"/>
</bean>
<bean id="loginCheckoutAuthenticationSuccessHandler" class="org.jnj.storefront.security.StorefrontAuthenticationSuccessHandler" scope="tenant">
<property name="customerFacade" ref="customerFacade" />
<property name="defaultTargetUrl" value="/checkout/single/summary"/>
</bean>
<!-- Login Failure Handlers -->
<bean id="loginAuthenticationFailureHandler" class="org.jnj.storefront.security.LoginAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login?error=auth"/>
<property name="accountBlockedUrl" value="/login?error=blocked"/>
<property name="passwordMigrationUrl" value="/login?error=migration"/>
</bean>
<bean id="loginCheckoutAuthenticationFailureHandler" class="org.jnj.storefront.security.LoginAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login/checkout?error=auth"/>
<property name="accountBlockedUrl" value="/login/checkout?error=blocked"/>
<property name="passwordMigrationUrl" value="/login/checkout?error=migration"/>
</bean>
<!-- Logout Success Handler -->
<bean id="logoutSuccessHandler" class="org.jnj.storefront.security.StorefrontLogoutSuccessHandler" scope="tenant">
<property name="defaultTargetUrl" value="/?logout=true"/>
<property name="guidCookieStrategy" ref="guidCookieStrategy"/>
<property name="cmsSiteService" ref="cmsSiteService"/>
</bean>
<!-- remember me services -->
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="gymUserDetailService"/>
<property name="key" value="someprivatekey"/> <!-- must match the rememberMeAuthenticationProvider key -->
<property name="parameter" value="rememberMe" /><!-- must match the parameter in the login form -->
<property name="cookieName" value="JNJ_RMMBRM" />
<property name="useSecureCookie" value="false" /> <!-- if set to true "remember me" only gets detected when accessed via https -->
<property name="tokenValiditySeconds" value="31536000" /> <!-- 1 year -->
</bean>
<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="someprivatekey"/>
</bean>
<bean id="gymRememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="loginGuidAuthenticationSuccessHandler"/>
</bean>
<!-- login filter and entry point -->
<bean id="gymAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationSuccessHandler" ref="loginGuidAuthenticationSuccessHandler"/>
<property name="authenticationFailureHandler" ref="loginAuthenticationFailureHandler"/>
</bean>
<bean id="gymAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login"/>
</bean>
这篇关于如何在Spring Security中使用自定义配置的RememberMeAuthenticationFilter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!