spring-security.md 3.8 KB
Newer Older
D
dallascao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
# Spring 安全集成

Spring 会话提供了具有 Spring 安全性的集成。

## [](#spring-security-rememberme) Spring 安全 Remember-Me 支持

Spring 会话提供了与[Spring Security’s Remember-me Authentication](https://docs.spring.io/spring-security/site/docs/5.6.2/reference/html5/#servlet-rememberme)的集成。支持:

* 更改会话过期长度

* 确保会话 cookie 在`Integer.MAX_VALUE`处过期。cookie 过期时间被设置为可能的最大值,因为只有在创建会话时才设置 cookie 过期时间。如果将其设置为与会话到期日相同的值,则会话将在用户使用会话时获得更新,但不会更新 cookie 到期日(导致过期时间固定)。

要在 Java 配置中配置具有 Spring 安全性的 Spring 会话,可以使用以下清单作为指导:

```
@Override
protected void configure(HttpSecurity http) throws Exception {
	http
		// ... additional configuration ...
		.rememberMe((rememberMe) -> rememberMe
			.rememberMeServices(rememberMeServices())
		);
}

@Bean
public SpringSessionRememberMeServices rememberMeServices() {
	SpringSessionRememberMeServices rememberMeServices =
			new SpringSessionRememberMeServices();
	// optionally customize
	rememberMeServices.setAlwaysRemember(true);
	return rememberMeServices;
}
```

基于 XML 的配置类似于以下内容:

```
<security:http>
	<!-- ... -->
	<security:form-login />
	<security:remember-me services-ref="rememberMeServices"/>
</security:http>

<bean id="rememberMeServices"
	class="org.springframework.session.security.web.authentication.SpringSessionRememberMeServices"
	p:alwaysRemember="true"/>
```

## [](#spring-security-concurrent-sessions) Spring 安全并发会话控制

Spring 会话提供与 Spring 安全性的集成,以支持其并发的会话控制。这允许限制单个用户可以并发的活动会话的数量,但是,与默认的 Spring 安全支持不同,这也适用于集群环境。这是通过提供 Spring Security 的`SessionRegistry`接口的自定义实现来完成的。

当使用 Spring Security 的 Java Config DSL 时,你可以通过`SessionManagementConfigurer`配置自定义`SessionRegistry`,如下所示:

```
@Configuration
public class SecurityConfiguration<S extends Session> extends WebSecurityConfigurerAdapter {

	@Autowired
	private FindByIndexNameSessionRepository<S> sessionRepository;

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// @formatter:off
		http
			// other config goes here...
			.sessionManagement((sessionManagement) -> sessionManagement
				.maximumSessions(2)
				.sessionRegistry(sessionRegistry())
			);
		// @formatter:on
	}

	@Bean
	public SpringSessionBackedSessionRegistry<S> sessionRegistry() {
		return new SpringSessionBackedSessionRegistry<>(this.sessionRepository);
	}

}
```

这假定你还配置了 Spring 会话,以提供一个`FindByIndexNameSessionRepository`,返回`Session`实例。

当使用 XML 配置时,它看起来类似于以下清单:

```
<security:http>
	<!-- other config goes here... -->
	<security:session-management>
		<security:concurrency-control max-sessions="2" session-registry-ref="sessionRegistry"/>
	</security:session-management>
</security:http>

<bean id="sessionRegistry"
	  class="org.springframework.session.security.SpringSessionBackedSessionRegistry">
	<constructor-arg ref="sessionRepository"/>
</bean>
```

这假定你的 Spring 会话`SessionRegistry` Bean 被称为`sessionRegistry`,这是所有`SpringHttpSessionConfiguration`子类使用的名称。

## [](#spring-security-concurrent-sessions-limitations)限制

Spring session 的 Spring security 的`SessionRegistry`接口的实现不支持`getAllPrincipals`方法,因为无法通过使用 Spring session 来检索此信息。 Spring Security 从不调用此方法,因此这只会影响访问`SessionRegistry`本身的应用程序。