spring security实现单用户登录

    在完成spring基础配置之后,可以在配置限制单个用户只能一处登录应用程序的功能,Spring Security支持这种开箱即用的功能。

    第一步:配置ConcurrentSessionFilter,用来判断session是否过期以及更新最新访问时间;

    在配置收到HTTP请求时的安全验证中添加以下配置:

<custom-filter ref="concurrencySessionFilter" position="CONCURRENT_SESSION_FILTER"/>

    并配置相应的<b:bean>

<b:bean id="concurrencySessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
    <b:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
    <b:constructor-arg name="expiredUrl" value="/login.html" />
</b:bean>

    第二步:注入SessionAuthenticationStrategy到CustomUsernamePasswordAuthenticationFilter中,否则默认使用的是NullAuthenticatedSessionStrategy,则获取不到登录用户数;

<!--自定义实现用户名密码及验证码判断功能的Filter,因为用户认证模块涉及了验证码,所以单独写了一个filter,这里这个类就只起了比对用户密码的功能 -->
<b:bean id="customUsernamePasswordAuthenticationFilter" class="cn.topcheer.common.authority.springsec.CustomUsernamePasswordAuthenticationFilter">
    <b:property name="enableValidateCode" value="false"></b:property>
    <b:property name="authenticationManager" ref="authenticationManager"></b:property>
    <b:property name="authenticationFailureHandler" ref="failureHandler"></b:property>
    <b:property name="authenticationSuccessHandler" ref="successHandler"></b:property>
    <!--注入sessionAuthenticationStrategy-->
    <b:property name="sessionAuthenticationStrategy" ref="sas"/>
</b:bean>

其中“sas”配置为:

<b:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
	<b:constructor-arg>
	    <b:list>
	        <!-- 并行控制 -->
	        <b:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
		    <b:constructor-arg ref="sessionRegistry" />
		    <b:property name="maximumSessions" value="1" />
		    <!--控制第二次登录将把第一次登录的用户踢下线-->
		    <b:property name="exceptionIfMaximumExceeded" value="false" />
	        </b:bean>
	        <b:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
		<b:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
			<b:constructor-arg ref="sessionRegistry" />
	        </b:bean>
	    </b:list>
	</b:constructor-arg>
</b:bean>
“sessionRegistry”配置为:
<b:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

配置完成后,重跑程序发现功能并没有实现,在调试过程中发现,判断当前用户是否重复时,这里的sessionCount总是0


于是,我点开sessionReistry.getAllSessions方法


发现这里取principle是根据HashMap取值的,hashMap判断相等需要hashCode相同,因此两个相同用户登录的时候需要相同的hashCode。在实现userDetails接口的用户信息中添加以下代码

     /**
     * 当同一用户登录多次时,获取的用户不是同一个用户
     * 所以需要重写hashcode和equals方法
     */
    @Override
    public boolean equals(Object rhs) {
        if (rhs instanceof CustomSecurityUser) {
            return getUsername().equals(((CustomSecurityUser) rhs).getUsername());
        }
        return false;
    }

    @Override
    public int hashCode() {
        return getUsername().hashCode();
    }

猜你喜欢

转载自blog.csdn.net/u013984781/article/details/80117152