SpringBoot2的session使用与1有点区别。如果根据1的组件包含使用redis是会报异常的。没有细研究,先解决问题。
在SpringBoot1中要使用redis session如下包含:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
而SpringBoot2中:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
redis配置也有点区别:
SpringBoot1:
spring:
redis:
# redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突
database: 9
# redis服务器地址(默认为localhost)
host: localhost
# redis端口(默认为6379)
port: 6379
# redis访问密码(默认为空)
password:
# redis连接超时时间(单位为毫秒)
timeout: 3600000
# redis连接池配置
pool:
# 最大可用连接数(默认为8,负数表示无限)
max-active: -1
# 最大空闲连接数(默认为8,负数表示无限)
max-idle: 200
# 最小空闲连接数(默认为0,该值只有为正数才有作用)
min-idle: 0
# 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
max-wait: -1
SpringBoot2:
spring:
redis:
# redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突
database: 9
# redis服务器地址(默认为localhost)
host: localhost
# redis端口(默认为6379)
port: 6379
# redis访问密码(默认为空)
password:
# redis连接超时时间(单位为毫秒)
timeout: 3600000
# redis连接池配置
jedis:
pool:
# 最大可用连接数(默认为8,负数表示无限)
max-active: -1
# 最大空闲连接数(默认为8,负数表示无限)
max-idle: 200
# 最小空闲连接数(默认为0,该值只有为正数才有作用)
min-idle: 0
# 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
max-wait: -1
如上包含与配置完成后,加入“@EnableRedisHttpSession”可以使用spring session。集群情况下,session也是想通的。即用户服务中保存数值到session中,其它服务可以访问到同一个session。
spring security与spring session
使用SessionRegistry
- 创建bean
@Bean
public SessionRegistry sessionRegistry(){
SessionRegistry sessionRegistry = new SessionRegistryImpl();
return sessionRegistry;
}
- 配置sessionManagement
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home", "/oauth/token", "/oauth/authorize").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.sessionManagement()
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
.and().and()
.logout()
.permitAll();
http.addFilterBefore(mobileCodeAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
// @formatter:on
}
- 使用SessionRegistry
@Autowired
private SessionRegistry sessionRegistry;
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
List<Object> principals = sessionRegistry.getAllPrincipals();
System.out.println(principals.size());
for (Object principal : principals) {
System.out.println(principal);
System.out.println(principal instanceof String);
}
return "hello";
}
这里只是做记录,项目中没有使用SessionRegistry
获取当前登录用户
spring scurity配合spring session获取当前登录的用户有三种方法(还有其它方法的话,还望留言告知):
@RequestMapping(value = "/demo")
@ResponseBody
public String username(Principal principal, HttpSession session) {
System.out.println("1:" + principal.getName());
Object springSecurityContext = session.getAttribute("SPRING_SECURITY_CONTEXT");
if (springSecurityContext instanceof SecurityContext) {
SecurityContext sc = (SecurityContext) springSecurityContext;
Authentication authentication = sc.getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
System.out.println("2:" + authentication.getName());
}
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (null != authentication) {
if (!(authentication instanceof AnonymousAuthenticationToken)) {
System.out.println("3:" + authentication.getName());
}
}
return principal.getName();
}
其中principal.getName()与authentication.getName()打印出来的结果是一样的。而第三种方法是可以使用在service中的。可以到service中获取当前登录用户,这样就不必每个API中都带上principal或session参数了。因为这里session是保存在redis中。所以,即使是在集群(微服务)中的各个服务都可以这样获取当前登录的用户。
网友评论