SessionRegistry注入后为null
时间: 2023-11-26 11:03:16 浏览: 23
如果你在使用Spring时,发现SessionRegistry注入后为null,可能是因为没有正确配置Spring Security。在Spring Security中,SessionRegistry是通过HttpSessionEventPublisher来注册的。因此,在配置Spring Security时,需要将HttpSessionEventPublisher添加到web.xml中:
```
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
```
如果你已经正确配置了HttpSessionEventPublisher,但仍然无法注入SessionRegistry,可能是因为你没有在Spring配置文件中声明SessionRegistry bean。可以尝试在Spring配置文件中添加以下内容:
```
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
```
如果还是无法解决问题,可以检查一下代码中是否有其他地方将SessionRegistry注入了,导致冲突。
相关问题
使用SpringSecurity内置过滤器 调用接口到达1次后限制1小时候调用 不要用最新版本的SpringSecurity 写代码
好的,针对你的要求,我们可以使用Spring Security的内置过滤器`ConcurrentSessionFilter`结合`SessionRegistry`和`SessionInformation`来实现调用接口到达1次后限制1小时后才能再次调用的功能。具体实现步骤如下:
1. 在Spring Security的配置类中添加`ConcurrentSessionFilter`过滤器:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAt(concurrentSessionFilter(), ConcurrentSessionFilter.class);
//其他配置
}
@Bean
public ConcurrentSessionFilter concurrentSessionFilter() {
return new ConcurrentSessionFilter(sessionRegistry(), sessionInformationExpiredStrategy());
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public SessionInformationExpiredStrategy sessionInformationExpiredStrategy() {
return new SimpleRedirectSessionInformationExpiredStrategy("/login");
}
//其他配置
}
```
2. 在接口方法中获取当前用户的`SessionInformation`对象,并判断该对象是否存在且距离上次访问时间是否大于1小时:
```java
@RestController
@RequestMapping("/api")
public class ApiController {
private Map<String, Integer> userCountMap = new ConcurrentHashMap<>();
@GetMapping("/test")
public String test(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
SessionInformation sessionInformation = sessionRegistry().getSessionInformation(session.getId());
if (sessionInformation != null && System.currentTimeMillis() - sessionInformation.getLastRequest() < 3600000) {
throw new RuntimeException("操作太频繁,请稍后再试!");
}
}
String username = request.getParameter("username");
userCountMap.compute(username, (k, v) -> v == null ? 1 : v + 1);
return "Hello " + username;
}
}
```
在上述代码中,我们首先通过`HttpServletRequest`对象获取当前用户的`HttpSession`对象,然后通过`sessionRegistry().getSessionInformation(session.getId())`方法获取当前用户的`SessionInformation`对象。如果该对象存在且距离上次访问时间不足1小时,则抛出异常提示用户操作太频繁。否则,我们将当前用户的执行次数记录到`userCountMap`中。
这样,就可以实现调用接口到达1次后限制1小时后才能再次调用的功能了。需要注意的是,这种方式只适用于单机部署的情况,如果是分布式部署,则需要使用分布式锁等机制来实现。
使用SpringSecurity内置过滤器 写一个接口限制次数后每小时执行一次 写代码 限制接口执行次数 每个用户单独限制
好的,针对你的要求,我们可以使用Spring Security的内置过滤器`ConcurrentSessionFilter`来实现每个用户单独限制接口执行次数的功能。具体实现步骤如下:
1. 在Spring Security的配置类中添加`ConcurrentSessionFilter`过滤器:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAt(concurrentSessionFilter(), ConcurrentSessionFilter.class);
//其他配置
}
@Bean
public ConcurrentSessionFilter concurrentSessionFilter() {
return new ConcurrentSessionFilter(sessionRegistry(), sessionInformationExpiredStrategy());
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public SessionInformationExpiredStrategy sessionInformationExpiredStrategy() {
return new SimpleRedirectSessionInformationExpiredStrategy("/login");
}
//其他配置
}
```
2. 在接口方法上添加`@PreAuthorize`注解,使用SpEL表达式限制用户的执行次数:
```java
@RestController
@RequestMapping("/api")
public class ApiController {
private Map<String, Integer> userCountMap = new ConcurrentHashMap<>();
@GetMapping("/test")
@PreAuthorize("#userCountMap.compute(#username, (k, v) -> v == null ? 1 : v + 1) <= 3")
public String test(@RequestParam String username) {
return "Hello " + username;
}
}
```
在上述代码中,我们使用了`ConcurrentHashMap`来记录每个用户执行接口的次数,然后在`@PreAuthorize`注解中使用SpEL表达式判断用户的执行次数是否超过了限制。
这里的表达式`#userCountMap.compute(#username, (k, v) -> v == null ? 1 : v + 1) <= 3`的含义是:
- `#userCountMap`表示`userCountMap`这个Map对象;
- `#username`表示方法参数中的`username`参数;
- `.compute(key, remappingFunction)`表示使用`remappingFunction`函数计算`key`对应的值,并将计算结果存储到Map中;
- `(k, v) -> v == null ? 1 : v + 1`表示一个Lambda表达式,如果`v`为`null`,则返回`1`,否则返回`v+1`;
- `<= 3`表示判断用户执行接口的次数是否小于等于3次。
这样,就可以实现每个用户单独限制接口执行次数的功能了。