Spring-Security 控制用户并发登入,并剔除前一个用户

本文参考至:https://blog.csdn.net/xusanhong/article/details/53260373

添加该功能是在原有功能上新增功能: SpringBoot +SpringSecurity+mysql 实现用户数据权限管理

spring-security 配置文件:添加用户并发登入的数量,session 失效跳转地址,实例化session 内存存储对象。

package com.zzg.security.config;

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;

import com.zzg.security.kaptch.filter.KaptchaFilter;
import com.zzg.security.provider.SpringSecurityProvider;

/**
 * spring-security 配置文件
 * @author zzg
 *
 */

@Configuration
@EnableWebSecurity //开启Spring Security的功能
@EnableGlobalMethodSecurity(prePostEnabled=true)//开启注解控制权限
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
	
	 /**
     * עSpringSecurityProvider
     */
    @Autowired
    private SpringSecurityProvider provider;
    
    /**
     *AuthenticationSuccessHandler
     */
    @Autowired
    private AuthenticationSuccessHandler securityAuthenticationSuccessHandler;
    /**
     *  AuthenticationFailureHandler
     */
    @Autowired
    private AuthenticationFailureHandler securityAuthenticationFailHandler;
    
    @Autowired
    private DataSource dataSource; 
    
    
    
   

    /**
	 * 定义需要过滤的静态资源(等价于HttpSecurity的permitAll)
	 */
	@Override
	public void configure(WebSecurity webSecurity) throws Exception {
		webSecurity.ignoring().antMatchers("static/css/**");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// TODO Auto-generated method stub
		http.authorizeRequests()
        .antMatchers("/login")
        .permitAll() // 登入界面不需要权限
        .antMatchers("/defaultKaptcha")
        .permitAll() // 图像验证码不需要权限
        .anyRequest().authenticated()      
        .and()
        .formLogin()
        .loginPage("/login")    // 登入页面
        .successHandler(securityAuthenticationSuccessHandler)  //自定义成功处理器
        .failureHandler(securityAuthenticationFailHandler)     //自定义失败处理器
        .permitAll()
        .and()
        .logout();
	
		// 当通过JDBC方式记住密码时必须设置 key,key 可以为任意非空(null 或 "")字符串,但必须和 RememberMeService 构造参数的
        // key 一致,否则会导致通过记住密码登录失败
        http.authorizeRequests()
                .and()
                .rememberMe()
                .rememberMeServices(rememberMeServices())
                .key("INTERNAL_SECRET_KEY");
        
        //在认证用户名之前认证验证码,如果验证码错误,将不执行用户名和密码的认证
        http.addFilterBefore(new KaptchaFilter("/login", "/login?error"), UsernamePasswordAuthenticationFilter.class); 
        

        http.sessionManagement() //Session管理器
        	.maximumSessions(1)  //相同用户并发数量
        	.sessionRegistry(getSessionRegistry()) //session内存操作对象
        	.expiredUrl("/login?error=session 失效"); //session 失效,跳转页面地址
        
	}



	@Override
	protected void configure(AuthenticationManagerBuilder builder) throws Exception {
		// 自定义身份验证提供者
		builder.authenticationProvider(provider);
	}
	
	
    
    /**
     * 返回 RememberMeServices 实例
     *
     * @return the remember me services
     */
    @Bean
    public RememberMeServices rememberMeServices() {
        JdbcTokenRepositoryImpl rememberMeTokenRepository = new JdbcTokenRepositoryImpl();
     
        // 此处需要设置数据源,否则无法从数据库查询验证信息
        rememberMeTokenRepository.setDataSource(dataSource);
        // 启动创建表,创建成功后注释掉
        // rememberMeTokenRepository.setCreateTableOnStartup(true);

        // 此处的 key 可以为任意非空值(null 或 ""),单必须和起前面
        // rememberMeServices(RememberMeServices rememberMeServices).key(key)的值相同
        PersistentTokenBasedRememberMeServices rememberMeServices =
                new PersistentTokenBasedRememberMeServices("INTERNAL_SECRET_KEY", provider.getUserDetailsService(), rememberMeTokenRepository);

        // 该参数不是必须的,默认值为 "remember-me", 但如果设置必须和页面复选框的 name 一致
        rememberMeServices.setParameter("remember-me");
        return rememberMeServices;
    }
    /**
     * session 内存存储方式
     * @return
     */
    @Bean
    public SessionRegistry getSessionRegistry(){
    	SessionRegistry sessionRegistry = new SessionRegistryImpl(); 
    	return sessionRegistry;
    }

}

 spring-security 发现登录同一个账号,并没有剔除前一个账号,这是如何实现的?

抛开框架暂且不说,如果是我直接写一个剔除前一个用户的话,我肯定是要得到全部用户,然后挨个挨个遍历筛选,如果存在当前登录用户就剔除前一个用户,这个需要使用if比较来实现的。

好了,问题找到了,因为SpringSecurity是通过管理UserDetails对象来实现用户管理的,按照上一步的原理,是需要进行比较实现效果的,然后呢,类的比较是不能用==比较的,类之间的比较是通过类的equals方法进行比较的,好了,问题找到了,我们自定义的User对象是没有实现equals方法的,好了,我们现在开始重写equals方法吧,关于重写的规则是:如果要重写equals方法,那么就必须要重写toStirng方法,如果要重写toString方法就最好要重写hashCode方法,所以我们需要在自定义的User对象中重写三个方法,hashCode、toString和equals方法。
 

@Override
	public String toString() {
		return this.nickname;
	}
	
	@Override
	public int hashCode() {
		return nickname.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		return this.toString().equals(obj.toString());
	}

Okay,重启项目,剔除前一个用户成功!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值