Spring-session: Cannot save redis session object retrieved from repository.

Created on 21 Sep 2016  路  6Comments  路  Source: spring-projects/spring-session

I have scenario when I want to reload Pricipal information stored in session when specific user is edited by admin.

I wrote following code.

@Service
public class UserSecurityService implements UserDetailsService {
    @Autowired  //This will be RedisOperationsSessionRepository
    private FindByIndexNameSessionRepository<? extends ExpiringSession> repository;

    public void reloadLoggedInUser(User user) {
        repository
                .findByIndexNameAndIndexValue(
                        FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
                        user.getEmail())
                .values().forEach(s -> {
                    SecurityContext context = s.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
                    setAuthentication(context, user);
                    s.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context);
                    repository.save(s); //<-- Incompatibile types error here
                });
    }

    private void setAuthentication(SecurityContext context, User user) {
        List<GrantedAuthority> authorities = buildUserAuthority(user);

        context.setAuthentication(
                new UsernamePasswordAuthenticationToken(
                        new GenericUserDetails(user, authorities),
                        null,
                        authorities
                )
        );
    }
}

I understand that you may want to preserve RedisSession as private class but I think that there should be any interface to save it after modifications of public part of it.

stack-overflow

Most helpful comment

@marcoblos Thanks for the comment, it helped me to resolve the problem. Here is an example:

@Autowired
RedisOperations<Object, Object> sessionRedisTemplate;

public void setInterval(String sessionId, int interval) {
    sessionRedisTemplate.boundHashOps("spring:session:sessions:" + sessionId).put("maxInactiveInterval", interval);
}

All 6 comments

@glapa I have same problem.
I need to serialize RedisSession to use with RMI in other applications and I don't find way for this.

I have a lot of system and I need to control sessions for all systems in one system and this one system persist the sessions in Redis. The operations like a getSession, createSession, delete and save I want expose by a server session system.

In client application I implemented a SessionRepository making bind to server application through RMI.
In server application I expose the same SessionsRepository methods injecting RedisOperationSessionRepository (just for use the implementation and persistence in redis) and bind the methods with RMI Server.

Did I make everything wrong? There is other way to implement this?

@rwinch, please, give a way of thinking in this problem :cry:

Thanks in advance.

Same problem here.
I have a backend service which stores the user's custom session timeout interval. After the login procedure, I want to overwrite the default maxInactiveInterval, but I can not save the session into Redis because of this package private RedisSession class.

Anyone has an idea for this problem?

@kkocsis As I said, I have a lot of system, and all these system need to persist the session in redis.
My alternative for this problem was import in all systems the library spring-boot-data-redis to give me "powers" to connect to the redis and persist the session "automagically" with @EnableRedisHttpSession.
To "filter" all sessions in one point for all systems, I did expose a service in a unique server that controll the permissions and invalidate sessions, and all other systems connect to this service, passing the loggedUser parameter (the object was persisted in the redis) to be validated or invalidated.
This solution resolve my problem, but, I really did want more.

@marcoblos Thanks for the comment, it helped me to resolve the problem. Here is an example:

@Autowired
RedisOperations<Object, Object> sessionRedisTemplate;

public void setInterval(String sessionId, int interval) {
    sessionRedisTemplate.boundHashOps("spring:session:sessions:" + sessionId).put("maxInactiveInterval", interval);
}

This looks like the the same problem as #849 - take a look at this comment in particular.

Closing as answered. If you have additional questions or feel that your original question isn't properly answered, please re-open the issue.

Was this page helpful?
0 / 5 - 0 ratings