Application scenarios
Recently, there are always people in the community who have posted articles with small advertisements, which seriously affects the community atmosphere. I’m so angry! For this type of user, it should be blocked permanently!
The community's security framework uses spring-security and spring-session, and the login status is valid for 30 days. The session information exists in Redis. How to deal with these dishonest users gracefully?
First, simply divide the user's permissions:
Then, block the specified user (ROLE_USER -> ROLE_BLACK) and force the user to exit (delete the user's session information in redis).
Project-related dependencies and configuration
Maven dependencies
<!-- 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 Policy Configuration Application.yml
# omit redis connection related configuration here spring: session: store-type: redis
Spring Security Configuration Code Sample
@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(); }}Forced exit assign to user interface
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; /** * Manage the logout of the specified user* @param userId User ID * @return User Session Information*/ @PreAuthorize("hasRole('MANAGER')") @GetMapping("/manager/logout/{userId}") public ResponseBean data(@PathVariable() Long userId){ // Query PrincipalNameIndexName (the key of Redis user information), and combine its own business logic to implement String indexName = userService.getPrincipalNameIndexName(userId); // Query the user's Session information, the return value key is sessionId Map<String, ? extends Session> userSessions = sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, indexName); // Remove the user's session Information List<String> sessionIds = new ArrayList<>(userSessions.keySet()); for (String session : sessionIds) { redisOperationsSessionRepository.deleteById(session); } return ResponseBean.success(userSessions); }} Description indexName is the return value of Principal.getName().
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.