User info associated with current user session is stale

Hi
I faced this problem a lot of times during my journey in CUBA, and it’s very annoying.

I’ll give you a practical problem I faced:

  • I have some dynamic queries, used by REST clients, that performs date/time checks based on current user’s timezone
  • The user, or an administrator, changes the user’s timezone
  • The middleware and web components continue to cache the old User info inside the user’s session, and even obtaining a new token with /oauth/token endpoint does not refresh this info

The only solution I found is to restart the application server, but you should agree with me that is NOT a solution…

Thanks
Paolo

I want to add that there’s something inherently wrong in keeping a user’s session cached in a REST api.

What I mean, is that when you issue a new token on behalf of a user, you simply login using the usual LoginService#login also used in the web tier, and then the session is cached in the cluster.
But at least in the web tier, a user is able to request an explicit logout, and thus the session is expliclitly destroyed/invalidated.

While in the REST api there is no such facility, and revoking a token does not touch a cached user session (so no real logout).

So the problem with this approach, is that the user session becomes stale from a REST client perspective.
The token you issue to the client should be the only mean to retrieve the user’s session on the cluster, and it must be tied to it, and not simply cached indefinitely. That is, the session’s lifetime must be tied to the token’s one, and you should create a new session on every token request.

Also, you should expose a simple method to request a refresh of the User entity inside the current user’s session, without forcing a logout/login (see this Refresh UserSession - CUBA.Platform)

Paolo

I’m experiencing this strange behaviour. (Cuba PLatform 6.10.11)
I implemented a Custom rest Auth controller as explained here:
https://doc.cuba-platform.com/manual-6.10/rest_api_v2_custom_auth.html

When I get token 2 session are created, the last one is returned in OAuth2AccessTokenResult, which I enrich in middleware whith session attributes representing external user in secondary RDMSStore associated with a web-application (different from Standard-UI, saving a rest authentication log in primary database. (cuba-login configured as ldap whith custom rest-token url /rest/extdb/token, where is associated my Spring MVC controller, POST method, similar in scheme to LDAP controller in source)

Late using a service in middleware i try to get a Session Attribute (session obtained via UserSessionSource) to get atrribute extID representing logged user, but session identifier is of first session created when getting token.
I do not know if it is a bug or I do not understand something.

Custom Controller extract (similar to LDAP and Example) and service consuming UserSession to filter whith attribute records from secondary RDBMS Store)

 // Enrich APPContext on Server
        attributes.put("extID", personId);

        // Generate Token for APP User
        OAuthTokenIssuer.OAuth2AccessTokenResult tokenResult = oAuthTokenIssuer.issueToken("app- logicway", locale, Collections.emptyMap());

        // Register in Attributes of UserSession in Middleware
        //attributes.put("userSession", tokenResult.getUserSession().getId());
        attributes.put("restToken", tokenResult.getAccessToken().getValue());
        attributes.put("restRefreshToken", tokenResult.getAccessToken().getRefreshToken().getValue());
        attributes.put("tokenExpire", tokenResult.getAccessToken().getExpiration());

When I get UserSession via UserSessionSource I get the first one with no attributes

@Service(DdtService.NAME)
public class DdtServiceBean implements DdtService {

    @Inject
    private DataManager dataManager;


    @Inject
    private UserSessionSource uss;

    @Inject
    protected ExtLoginService extLoginService;

    private static Integer badId = -1;
    private UserSession userSession = null;
    private UUID userSessionID = null;



    @Override
    public List<Ddtinfo> getLastDDT(Integer num) {

        if (uss.checkCurrentUserSession()) {
            userSession = uss.getUserSession();
            userSessionID = userSession.getId();
        } else {
            return null;
        }

        //Integer userID = extLoginService.getIDbySession(userSessionID);
        //Integer userID = userSession.getAttribute("extID");
        Integer userID = 989;


        //if ((userID != null) || (userID != badId)) {
        if (userID != null) {
            return searchDdt(userID,num);
        }

        return null;
    }

    private  List<Ddtinfo> searchDdt(Integer personID, Integer num)  {
        // Search DDTs
        String queryStr ="select d from applogicway$Ddtinfo d where d.idPersona.id=:personID order by d.uploadTime DESC";

        LoadContext<Ddtinfo> loadContext = LoadContext.create(Ddtinfo.class)
                .setQuery(LoadContext.createQuery(queryStr)
                        .setParameter("personID",personID)
                            .setMaxResults(num));

        return (List<Ddtinfo>) dataManager.loadList(loadContext);
    }

I tried some workaround getting Attributes (not found in UserSession) but session is different so no success.

Atthached app.log and some screens of saved token,log and sessions.

Thanks in advance
Fabrizio
Screenshots.zip (1.2 MB)
tokenSessionProblems.zip (14.6 KB)

Any news?