應用場景
最近社區總有人發文章帶上小廣告,嚴重影響社區氛圍,好氣!對於這種類型的用戶,就該永久拉黑!
社區的安全框架使用了spring-security 和spring-session,登錄狀態30 天有效,session 信息是存在redis 中,如何優雅地處理這些不老實的用戶呢?
首先,簡單劃分下用戶的權限:
然後,拉黑指定用戶(ROLE_USER -> ROLE_BLACK),再強制該用戶退出即可(刪除該用戶在redis 中session 信息)。
項目相關依賴及配置
Maven 依賴
<!-- 安全Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- Spring Session Redis --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
Spring Session 策略配置application.yml
# 此處省略redis 連接相關配置spring: session: store-type: redis
Spring Security 配置代碼示例
@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/user/**").authenticated() .antMatchers("/manager/**").hasAnyRole(RoleEnum.MANAGER.getMessage()) .anyRequest().permitAll() .and().formLogin().loginPage("/login").permitAll() .and().logout().permitAll() .and().csrf().disable(); }}強制退出指定給用戶接口
import com.spring4all.bean.ResponseBean;import com.spring4all.service.UserService;import lombok.AllArgsConstructor;import org.springframework.session.FindByIndexNameSessionRepository;import org.springframework.session.Session;import org.springframework.session.data.redis.RedisOperationsSessionRepository;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;import java.util.List;import java.util.Map;@RestController@AllArgsConstructorpublic class UserManageApi { private final FindByIndexNameSessionRepository<? extends Session> sessionRepository; private final RedisOperationsSessionRepository redisOperationsSessionRepository; private final UserService userService; /** * 管理指定用戶退出登錄* @param userId 用戶ID * @return 用戶Session 信息*/ @PreAuthorize("hasRole('MANAGER')") @GetMapping("/manager/logout/{userId}") public ResponseBean data(@PathVariable() Long userId){ // 查詢PrincipalNameIndexName(Redis 用戶信息的key),結合自身業務邏輯來實現String indexName = userService.getPrincipalNameIndexName(userId); // 查詢用戶的Session 信息,返回值key 為sessionId Map<String, ? extends Session> userSessions = sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, indexName); // 移除用戶的session 信息List<String> sessionIds = new ArrayList<>(userSessions.keySet()); for (String session : sessionIds) { redisOperationsSessionRepository.deleteById(session); } return ResponseBean.success(userSessions); }}說明indexName 為Principal.getName() 的返回值。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。