在实际应用中,我们可能会限制一个用户同时登录同一个应用的次数。例如,我们希望系统中只有一个‘张三’能登录,从而阻止用户‘张三’利用两个不同的session进入我们的web应用中,为此spring security为我们提供了以下两种策略实现这个功能:
- 当同样的用户再次登录的时候,就将前一次登录过的session信息自动设置成过期
- 直接报出一个错误,提示用户已经登录,从而阻止本次登录
注意: 当采用第二种方式时,如果一个用户没有明确的执行logout(例如用户直接关闭了浏览器),在这个用户的session没有过期前,他将不能再次登录系统
本示例采用第一种策略,设置最大并发登录次数为1
环境:
spring boot 版本:1.5.4.RELEASE
1.项目结构
2.配置类SecurityConfig.java
package falcon.chengf.security.sample.javaconfig.concurrency; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * @author: 作者: chengaofeng * @date: 创建时间:2018-02-15 10:33:55 * @Description: TODO * @version V1.0 */ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // @formatter:off @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } // @formatter:on // @formatter:off @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .and() .sessionManagement() .maximumSessions(1) .expiredUrl("/login?expired"); } // @formatter:on }
主要是追加了sessionManagement().maximumSessions(1).expiredUrl("/login?expired");这个配置,代表的意思是启用session控制,最大并发session数是1,当session过期后用户被重定向到 /login页面
3.启动类SecurityConcurrencyApp.java
package falcon.chengf.security.sample.javaconfig.concurrency; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Hello world! * */ @SpringBootApplication public class SecurityConcurrencyApp { public static void main( String[] args ) { SpringApplication.run(SecurityConcurrencyApp.class, args); } }
4.项目pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>falcon.chengf</groupId> <artifactId>security-sample-javaconfig-concurrency</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>security-sample-javaconfig-concurrency</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <mainClass>${start-class}</mainClass> </configuration> </plugin> </plugins> </build> </project>
5.index页面
<!DOCTYPE html> <html> <head> <title>Static</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> hello,security </body> </html>
6.启动项目
选中启动类,选择 Run As->Java application,启动后在浏览器中输入
http://localhost:8080/index.html
正常情况下,我们会被重定向到login界面
输入用户名:user;密码:password,进入index页面
之后我们打开另一个浏览器(例如之前用safari,现在用chrome,或者在另一台电脑上打开浏览器),重新执行上面的登录步骤,当在新浏览器中进入index页面后,再回到之前的浏览器中执行刷新,会发现我们被重新定向到了登录页面,证明我们设定的并发登录控制起到了作用
下载源码