spring-security(七)java config-sample之concurrency

燕宏胜
2023-12-01
前言:
在实际应用中,我们可能会限制一个用户同时登录同一个应用的次数。例如,我们希望系统中只有一个‘张三’能登录,从而阻止用户‘张三’利用两个不同的session进入我们的web应用中,为此spring security为我们提供了以下两种策略实现这个功能:
[list]
[*]当同样的用户再次登录的时候,就将前一次登录过的session信息自动设置成过期
[*]直接报出一个错误,提示用户已经登录,从而阻止本次登录
[/list]
注意:[b]当采用第二种方式时,如果一个用户没有明确的执行logout(例如用户直接关闭了浏览器),在这个用户的session没有过期前,他将不能再次登录系统[/b]
本示例采用第一种策略,设置最大并发登录次数为1
环境:
spring boot 版本:1.5.4.RELEASE

1.项目结构

[img]http://dl2.iteye.com/upload/attachment/0128/9162/67c323a3-bd4e-3d87-a481-853de7830abf.png[/img]

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界面

[img]http://dl2.iteye.com/upload/attachment/0128/9164/4d43e7e8-90ba-3245-9cf0-52d2b9c64e63.png[/img]

输入用户名:user;密码:password,进入index页面

[img]http://dl2.iteye.com/upload/attachment/0128/9166/ee024cc4-b8a9-3b12-89e5-9e6fcd2cdb49.png[/img]
之后我们打开另一个浏览器(例如之前用safari,现在用chrome,或者在另一台电脑上打开浏览器),重新执行上面的登录步骤,当在新浏览器中进入index页面后,再回到之前的浏览器中执行刷新,会发现我们被重新定向到了登录页面,证明我们设定的并发登录控制起到了作用

[url=https://github.com/fengyilin/spring-security-sample/tree/master]下载源码[/url]
 类似资料: