Announcement Announcement Module
No announcement yet.
Login As Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Login As


    I have an application which require customer to login, acegi works fine with that.

    Now, I need an Admin which can login as any customer. Once an admin is login as customer, his username (e.g. admin) will change to customer username (e.g. nathan). My question is how do I do something like that with acegi, should i use RunAs??


  • #2
    Hi !

    I have a similar thing I need to do, but everything will be code-based.

    I have automated jobs that should execute as the user for which I'm doing the thing. Any pointers on that would be appreciated too.

    I suspect the answer will be similar in both cases.

    Thanks !


    • #3
      You could use run-as, with perhaps a custom RunAsManager which could look on the ContextHolder to obtain some property that identifies the target user.

      Alternatively, allow the admin user to login and then that gives them access to some web MVC controller which allows the user to specify who they would like to become (think the Unix 'su' command). Then they submit, the ContextHolder gets updated with the new Authentication (probably obtained from the AuthenticationDao) and the next request returns them to the home page. They are then the new user, but without resorting to the comparative complexity of context management and run-as.


      • #4
        how do i switch back to admin after switching to a customer?


        • #5
          It would be difficult to do this, as you'd need to store some sort of token that the user is really an administrator. It could be done, perhaps by your MVC controller adding an additional GrantedAuthority called PREVIOUSLY_ADMINISTRATOR. Then you could have an MVC controller listening to some URI like /exitRunAsUser, which requires PREVIOUSLY_ADMINISTRATOR. That controller will revert them back to the their original Authentication. You could use a custom GrantedAuthority that stored the original Authentication object.

          This actually sounds like a useful feature to offer out-of-the-box. I will add it to JIRA:


          • #6
            Useful, yes, but on the other hand this could be called a security hole by IT risk analysts/auditors if appropriate logging hooks aren't provided. In environments where Sarbanes Oxley ("SOX") regulations and other security sensitivities dominate, you wouldn't want to give an admin the ability to impersonate another user without it being clearly logged, and that may not be as straightforward as it sounds.

            In my experience logging requirements are quite specific to each environment, application and events being logged. For example one site may require very detailed info about the user and their substituted persona on each and every event executed during the "impersonation," (into a database of course), whereas another's may just want a few fields announcing the identity *change* into a text file. The point here is that in the second case, we'd only need to provide a logging hook for the identity change, whereas in the first case we'd need to make the "runAs" user persona available, maybe in the Security Context, so that the application can pull it out when needed...

            ...but even this may be undesirable, because in my mind logging should primarily be done at the service level, and the services themselves should be as atomic, decoupled and course-grained as possible. Some developers may chose to use an AOP logging interceptor whereas others may have to do it programmatically (within transaction boundaries of course) to get the level of detail needed. Adding "runAs/impersonation" capabilities could require adding lots of method parameters to app services to keep them from being coupled to Acegi's Security Context. At best, it starts to blend security, logging and transaction concerns.

            I hope I'm missing some obvious solutions, because I could actually use this feature in one of my apps, but without a robust logging strategy included I think it'll be more trouble than it's worth.

            Just my 2c.


            • #7
              A project I was just working on used a LoggingInterceptor, which took advantage of the TransactionSynchronizationManager.bindResource() method so that it could record whether it was the "first" invocation for a given transaction and thus know to log. Therefore internal services layer invocations that the outer transaction caused did not cause additional log messages. As Scott said, business logging is typically application-specific (as distinct from developer logging, which Commons Logging or Log4J will handle for you).