Spring Security forcibly exits the method of the specified user, springsecurity
Application scenarios
Recently, some people in the community have posted articles with Small advertisements, which seriously affects the Community atmosphere! This type of user should be permanently hacked!
The Community's security framework uses spring-security and spring-session. The logon status is valid for 30 days and the session information is stored in redis. How can we handle these dishonest users elegantly?
First, we will briefly divide the user's permissions:
- Administrator (ROLE_MANAGER): basic operations + management operations
- Normal user (ROLE_USER): basic operation
- ROLE_BLACK: logon not allowed
Then, blacklist the specified user (ROLE_USER-> ROLE_BLACK) and force the user to exit (delete the user's session information in redis ).
Project dependencies and configurations
Maven dependency
<! -- Security 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
# Redis connection configuration spring: session: store-type: redis is omitted here
Sample Spring Security configuration code
@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(); }}
Force exit specified 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. an Notation. 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 logon logout for a 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 (key of Redis user information), combined Use its own business logic to implement String indexName = userService. getPrincipalNameIndexName (userId); // query the user's Session information. The returned 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 );}}
The returned value of indexName is Principal. getName.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.