dynamically change user roles and refresh security

1
Known behavior of the framework is that when you have a microflow that change the user roles of the currentuser the currentuser have to logout / login before the new role become effective. This time that's not what I want. Is there a way to bypass this behaviour and force the Mx Runtime to reload the users roles (logout/login -> reload session). If that's possible we can make a client side widget that refreshes the client so that the menu is also adapted to the new role(s). Edit 11-02: The case is a multi tenant application where people can be assigned to multiple companies but with different roles/rights for each company. Now they have to use seperate accounts, and therefore have to logout/login many times.
asked
6 answers
10

I've managed to do this in the mean while. Here how I did it. I think this is useful for multi tenant apps where users can be linked to multiple organizations with different rights.

  1. First of all add a request handler in a after start up java action like:

    Core.addRequestHandler("reloadSecurity/", new ReloadSecurityRequestHandler());
    
  2. Implement the request handler als follows:

    public class ReloadSecurityRequestHandler extends RequestHandler { @Override public void processRequest(IMxRuntimeRequest request, IMxRuntimeResponse response, String arg2) throws Exception {

        String curSession = request.getCookie(XAS_SESSION_ID);
        String userName = request.getParameter("userName");
        ISession currentMxSession = Core.getActiveSession(userName);
    
        if(currentMxSession.getId().toString().equals(curSession)){
            IContext systemContext = Core.createSystemContext();
    
            ISession newSession = Core.initializeSession(systemContext, Core.getUser(systemContext, userName), curSession,"nl_NL");
            response.addCookie(XAS_SESSION_ID, newSession.getId().toString(),"/" ,"" ,-1 );
            response.addCookie(XAS_ID, "0." + Core.getXASId(),"/" ,"" ,-1);
    
            Core.logout(currentMxSession);
        }
    
        response.setStatus(IMxRuntimeResponse.SEE_OTHER);
        response.addHeader("location", "../index.html");
    }
    
    private static final String XAS_ID = "XASID";
    

    }

  3. Create a microflow where you assign the new roles to the user and open a blocking popup form called something like: redirectToReloadSecurity. Adds the URL redirector widget to the form and use the URL: https://youapplication.something.com/reloadSecurity?userName=theUserNameThatHasToReload

That should do it. The Java action creates a new session and let the client refresh with the location header. Menu's, security, everything will be updated.

answered
1

Has Anyone had any luck implementing this in Mendix 5 (5.10). I had a version working in 4.7.2 but I can't seem to get the user logged back in. Any help would be appreciated.

answered
0

No, there is no such mechanism.

answered
0

I would also really love to be able to do this, but unfortunately Bas is right. It is currently not possible.

(We also tried to dynamically assign userroles to anonymous users. Because of this limitation this is also not possible.)

answered
0

I think I've found a way to achieve this. First of all, add a "reloadSecurity" request handler in a after startup Java action:

Core.addRequestHandler("reloadSecurity/", new ReloadSecurityRequestHandler());

Second implement the request handler as follows:

public void processRequest(IMxRuntimeRequest request, IMxRuntimeResponse response,
        String arg2) throws Exception {


    String curSession = request.getCookie(XAS_SESSION_ID);
    String userName = request.getParameter("userName");

    ISession currentMxSession = Core.getActiveSession(userName);

    Core.getLogger("Security").log(LogLevel.INFO, "Mx Session: " + currentMxSession.getId().toString());
    Core.getLogger("Security").log(LogLevel.INFO, "Rq Session: " + curSession);

    if(currentMxSession.getId().toString().equals(curSession)){
        ISession newSession = Core.initializeSession(Core.createSystemContext(), Core.getUser(Core.createSystemContext(), userName), curSession,"en_US");
        response.addCookie(XAS_SESSION_ID, newSession.getId().toString(),"/" ,"" ,-1 );
        response.addCookie(XAS_ID, "0." + Core.getXASId(),"/" ,"" ,-1);
    }

    response.setStatus(IMxRuntimeResponse.SEE_OTHER);
    response.addHeader("location", "../index.html");
}

This seams to work.. :)

N.b. is there a way to get to the "IMxRuntimeResponse" from a Java action? If so, then my request handler is unnecessary.

answered
0

Herbert, just wondering but in the third step you write that the redirect URL would be something like https://youapplication.something.com/reloadSecurity?userName=theUserNameThatHasToReload this however didn't work in our case we had to make it:

https://youapplication.something.com/reloadSecurity/reloadSecurity?userName=theUserNameThatHasToReload

I don't know why, can you explain why? If we use the first url we get a file-not-found error on the reloadSecurity-file.

answered