spring/spring security
[Spring Security] redis 세션에서 SecurityContext 수정
moonsiri
2021. 7. 12. 17:39
728x90
반응형
FindByIndexNameSessionRepository의 save 메소드를 사용하여 SecurityContext 수정할 수 있습니다.
@Resource(name = "sessionRepository")
private FindByIndexNameSessionRepository<Session> findByIndexNameSessionRepository;
public void refreshSecurityContext(String targetUsername) {
// targetUsername의 session 모두 조회
Map<String, Session> sessionMap = findByIndexNameSessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, targetUsername);
for (Map.Entry<String, Session> entry : sessionMap.entrySet()) {
Session session = entry.getValue();
// get contextHolder
// SecurityContext securityContext = SecurityContextHolder.getContext();
SecurityContext securityContext = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
if (securityContext == null) {
continue;
}
// get UserDetails
UserDetails userDetails = (UserDetails) securityContext.getAuthentication().getPrincipal();
// userDetails 수정 영역
// set securityContext
Authentication newAuth = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
securityContext.setAuthentication(newAuth);
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, securityContext);
findByIndexNameSessionRepository.save(session);
}
}
더보기
@Resource(name = "sessionRepository")
private FindByIndexNameSessionRepository<Session> findByIndexNameSessionRepository;
@Resource
private RedisCommands<byte[], byte[]> redisCommands;
private static final String redisNamespace = "siri";
private static final String SESSION_KEY_PATTERN = redisNamespace + ":sessions:%s";
private static final StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
private static final JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
private static final byte[] HASH_KEY_OF_SPRING_SECURITY_CONTEXT = stringRedisSerializer.serialize("sessionAttr:" + SPRING_SECURITY_CONTEXT_KEY);
private void refreshSecurityContext(String targetUsername) {
Map<String, Session> sessionMap = findByIndexNameSessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, targetUsername);
for (String key : sessionMap.keySet()) {
byte[] sessionKey = String.format(SESSION_KEY_PATTERN, key).getBytes();
if (redisCommands.exists(sessionKey) == 0) {
continue;
}
// get contextHolder
byte[] sessionAddInfoAsBytes = redisCommands.hget(sessionKey, HASH_KEY_OF_SPRING_SECURITY_CONTEXT);
SecurityContext securityContext = (SecurityContext)jdkSerializationRedisSerializer.deserialize(sessionAddInfoAsBytes);
if (securityContext == null) {
continue;
}
// get UserDetails
UserDetails userDetails = (UserDetails) securityContext.getAuthentication().getPrincipal();
// userDetails 수정
// set securityContext
Authentication newAuth = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
securityContext.setAuthentication(newAuth);
redisCommands.hset(sessionKey, HASH_KEY_OF_SPRING_SECURITY_CONTEXT, jdkSerializationRedisSerializer.serialize(securityContext));
}
}
findByIndexNameSessionRepository.getById(sessionKey); 를 사용하면 Session을 조회 할 수 있고,
findByIndexNameSessionRepository.deleteById(sessionKey); 를 사용하면 session을 제거할 수도 있습니다.
728x90
반응형