Spring security - 身份验证在几天后停止工作 - 需要重新启动

Posted

技术标签:

【中文标题】Spring security - 身份验证在几天后停止工作 - 需要重新启动【英文标题】:Spring security - Authentication stops working after some days - reboot needed 【发布时间】:2016-03-17 03:59:28 【问题描述】:

我有一个在 Spring 4.1.4 和 Spring Security 4.0.2 上开发的应用程序,部署在具有 Apache Tomcat 8 和 JDK 1.7 的服务器上。 碰巧的是,一些用户即使指定正确的用户/密码组合,也无法再登录。 重新启动 Tomcat 即可解决此问题。

有什么建议吗? 这可能是与会话相关的问题吗?

这是我的安全配置

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee" 
xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd 
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
">

<http auto-config="true" use-expressions="true">
    <custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="ajaxTimeoutRedirectFilter"/>

    <custom-filter position="SWITCH_USER_FILTER" ref="switchUserProcessingFilter" />
    <intercept-url pattern="/j_spring_security_switch_user" access="hasRole('ROLE_SUPERVISOR')"/>

    <session-management  invalid-session-url="/login.html?invalidSession=1" session-fixation-protection="newSession">
        <concurrency-control max-sessions="10" error-if-maximum-exceeded="true" />
    </session-management>

    <intercept-url pattern="/login.html" access="hasRole('ROLE_ANONYMOUS')" requires-channel="https"/>
    <intercept-url pattern="/resources/**" access="permitAll" requires-channel="any"/>
    <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" requires-channel="https"/>
    <intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')" requires-channel="https"/>
    <intercept-url pattern="/index" access="hasRole('ROLE_USER')" requires-channel="https"/>
    <intercept-url pattern="/upload/**" access="hasRole('ROLE_USER')" requires-channel="https"/>

    <headers>
        <xss-protection block="false"/>
        <frame-options disabled="true"/>
        <cache-control/>
    </headers>

    <!-- access denied page -->
    <access-denied-handler error-page="/403" />
    <form-login 
        login-page="/login.html" 
        default-target-url="/index" 
        always-use-default-target="true"
        authentication-failure-url="/login.html?error=1" 
        username-parameter="username" 
        password-parameter="password"/>
    <logout logout-success-url="/login.html?logout=1" invalidate-session="false" delete-cookies="JSESSIONID"/>
    <!-- enable csrf protection -->
    <!-- <csrf disabled="true" /> -->

    <port-mappings>
        <port-mapping http="8080" https="8443"/>
    </port-mappings>
</http>

<beans:bean id="ajaxTimeoutRedirectFilter" class="com.finconsgroup.mens.springsecurity.AjaxTimeoutRedirectFilter">
    <beans:property name="customSessionExpiredErrorCode" value="419"/>
</beans:bean>

<beans:bean id="switchUserProcessingFilter" class="com.finconsgroup.mens.springsecurity.MensSwitchUserFilter">
    <beans:property name="userDetailsService" ref="mensAuthenticationService"/>
    <beans:property name="switchUserUrl" value="/j_spring_security_switch_user"/>
    <beans:property name="exitUserUrl" value="/j_spring_security_exit_user"/>
    <beans:property name="targetUrl" value="/index"/>
</beans:bean>

<beans:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!-- Select users and user_roles from database -->
<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="mensAuthenticationService">
        <password-encoder ref="bcryptEncoder"/>
    </authentication-provider>
</authentication-manager>
<beans:bean id="mensAuthenticationService" class="com.finconsgroup.mens.springsecurity.MensAuthenticationProvider">
    <beans:property name="dataSource" ref="mensDataSource"/>
    <beans:property name="usersByUsernameQuery" value="my_query"/>
    <beans:property name="authoritiesByUsernameQuery" value="my_query"/>
    <beans:property name="groupAuthoritiesByUsernameQuery" value="my_query"/>
    <beans:property name="enableGroups" value="true"/>
</beans:bean>

<!-- Spring Security -->

<beans:bean id="mensPermissionEvaluator" class="com.finconsgroup.mens.springsecurity.MensPermissionEvaluator">
    <beans:constructor-arg ref="aclService"/>
</beans:bean>

<beans:bean id="securityExpressionHandler" 
        class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <beans:property name="permissionEvaluator" ref="mensPermissionEvaluator"/>
</beans:bean>

<global-method-security
    authentication-manager-ref="authenticationManager"
    pre-post-annotations="enabled"
    secured-annotations="enabled">
    <expression-handler ref="securityExpressionHandler"/>
</global-method-security>

<!-- ================================================================== -->
<!-- ACL service                                                        -->
<!-- ================================================================== -->

<beans:bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
    <beans:constructor-arg ref="mensDataSource" />
    <beans:constructor-arg ref="lookupStrategy" />
    <beans:constructor-arg ref="aclCache" />
</beans:bean>

<beans:bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
    <beans:constructor-arg>
        <beans:bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
            <beans:property name="cacheManager">
                <beans:ref bean="mensEhCacheManager"/>
            </beans:property>
            <beans:property name="cacheName" value="aclCache"/>
        </beans:bean>
    </beans:constructor-arg>
    <beans:constructor-arg>
        <beans:bean class="org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy">
            <beans:constructor-arg>
                <beans:bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
            </beans:constructor-arg>
        </beans:bean>
    </beans:constructor-arg>
    <beans:constructor-arg>
        <beans:bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
            <beans:constructor-arg>
                <beans:list>
                    <beans:bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
                        <beans:constructor-arg value="ROLE_ACL_ADMIN"/>
                    </beans:bean>
                </beans:list>
            </beans:constructor-arg>
        </beans:bean>
    </beans:constructor-arg>
</beans:bean>

<beans:bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
    <beans:constructor-arg ref="mensDataSource" />
    <beans:constructor-arg ref="aclCache" />
    <beans:constructor-arg>
        <!-- Decides whether current principal can make ACL changes. See
             AclAuthorizationStrategyImpl Javadoc for the rules involved. -->
        <beans:bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
            <beans:constructor-arg>
                <beans:list>
                    <!-- Role required to change ACL ownership -->
                    <beans:ref bean="adminRole" />
                    <!-- Role required to change auditing details -->
                    <beans:ref bean="adminRole" />
                    <!-- Role required to change other ACL/ACE details -->
                    <beans:ref bean="adminRole" />
                </beans:list>
            </beans:constructor-arg>
        </beans:bean>
    </beans:constructor-arg>
    <beans:constructor-arg>
        <beans:bean class="org.springframework.security.acls.domain.ConsoleAuditLogger" />
    </beans:constructor-arg>
</beans:bean>

<beans:bean id="adminRole" class="org.springframework.security.core.authority.SimpleGrantedAuthority">
    <beans:constructor-arg value="ADMIN" />
</beans:bean>

提前感谢您的帮助!

【问题讨论】:

什么不起作用?会发生什么,你期望会发生什么?它只是您的部分安全配置,您的用户信息存储(和检索)在哪里,身份验证管理器的配置不在这里。 我在主帖中发布了完整的配置。问题是它说用户/密码不正确。 这是前端的症状,但后端也是这个问题吗?不就是你的数据库不能再查询了吗?我看到您有很多自定义类确保它们正常工作并且您的数据库事务/资源处理设置正确。 感谢您的回复。大多数自定义类实际上是空的,它们只是调用超类,但我需要它们进行进一步的演变。我认为数据库没问题,因为如果我尝试使用不同的用户登录(通常我在开发时总是使用相同的用户)登录效果很好。 我刚遇到这个问题。我的应用程序已经运行好几个星期了,突然之间,spring security 将不再验证任何正确的凭据。重启 tomcat 解决了这个问题。 【参考方案1】:

我修复了将 session-fixation-protection 属性更改为 migrateSession 的问题。 现在我不需要定期重启Tomcat了。

【讨论】:

以上是关于Spring security - 身份验证在几天后停止工作 - 需要重新启动的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Security:优化获取当前经过身份验证的用户...

Spring Security 中的基本身份验证(身份验证失败消息)

Spring MVC REST + Spring Security + 基本身份验证

不使用 Spring Security 身份验证?

在向 Twitter/Facebook 进行身份验证后向 Spring Security 进行身份验证

如何使用 Spring Security 模拟身份验证和授权