Announcement Announcement Module
Collapse
No announcement yet.
Stateless Remote Invocation and ContextHolder issue Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Stateless Remote Invocation and ContextHolder issue

    hi,

    current we are using acegi security package to secure our web application communicating to a swing rich client.

    we are using httpInvoker for the remoting. the httpinvoker invocation is essentially stateless.

    however, after looking thru the acegi codes, we found that the AutoIntegrationFilter stores the userId and password in the web container session object.

    as such if we were to open 2 instance of our swing application and log in using different user id.

    at the server side invocation from the 2 apps instance will still have the userId and password for the first login and not the second.

    as such, we would like to know if there's a workaround for this issue. or if this is the intended result, what should be the correct way to do this type of security checking.

    thank you very much.

  • #2
    Re: Stateless Remote Invocation and ContextHolder issue

    Originally posted by bthh78
    as such if we were to open 2 instance of our swing application and log in using different user id.

    at the server side invocation from the 2 apps instance will still have the userId and password for the first login and not the second.
    Sorry, but I don't follow what you mean. Your two swing Rich apps will each store the username and password in their local ContextHolder, and present then to the server via AuthenticationSimpleHttpInvokerRequestExecutor.

    On the server-side, the BASIC header will be unwrapped by BasicProcessingFilter, who authenticates the user via an AuthenticationManager and then puts the resulting Authentication into the HttpSession. The AutoIntegrationFilter (which is removed from 0.7.0, so use HttpSessionIntegrationFilter instead) then grabs the Authentication from HttpSession and manages its exposure on the server-side ContextHolder.

    As HttpInvoker is stateless, this means a session will be created each time a request is received. If this concerns you, just set a very low session timeout value in web.xml.

    Comment


    • #3
      hi ben,

      does that means multiple sessions may exists for requests from the same user?

      in that case, we will set a very low session timeout value in web.xml as you suggest.

      however, would it cause a performance issue? if there are many users sending many requests at the same time? then there will be many sessions created, as many as there are requests coming in.

      thanks.

      Comment


      • #4
        Originally posted by bthh78
        does that means multiple sessions may exists for requests from the same user?
        Yes, if a user sends two separate HttpInvoker requests, two HttpSessions will be created. The reason BasicProcessingFilter writes to HttpSession - and not straight to the ContextHolder - is because in most deployments someone will be exposing both a webapp AND a web service. In other words, two types of users need to be supported: interactive web MVC users (ie those that login via a web form) and web services (who login via BASIC authentication headers). If we had the BasicProcessingFilter write directly to the ContextHolder, the situation in which both types of users need to coexist would be a problem (basically as HttpSessionIntegrationFilter and BasicProcessingFilter would compete for control of ContextHolder).

        Let's not forget a HttpSession being created for a single request is not a major overhead, as the Authentication object that gets added to it is very small in size.

        The simplest option is to set a low HttpSession timeout value, or modify HttpInvoker to present the same jsessionid on subsequent requests. Either approach is legitimate and achievable.

        Another way would be to modify BasicProcessingFilter so it has a property that directs whether or not it should write to HttpSession or directly to ContextHolder. As such you would not need to use HttpSessionIntegrationFilter. Personally I feel this would confuse users, when it's not exactly obvious what is happening even now. In your case you could easily write your own equivalent of BasicProcessingFilter which wrote directly to ContextHolder (not HttpSession). Thus no HttpSessions get used by Acegi Security.

        So there you have three approaches that would work. Probably the last one is the most elegant, as it avoids the needless HttpSession to begin with.

        Comment


        • #5
          hi ben,

          if we write directly to the ContextHolder, would there be a case where 2 concurrent requests from 2 different users get into a race condition?

          that is,
          - the first writes to the ContextHolder do some processing
          - 2nd writes to the ContextHolder, do some processing
          - the first gets the authentication token from the ContextHolder for verification but it gotten the 2nd's instead

          thanks

          Comment


          • #6
            The race condition shouldn't happen, as a ContextHolder is a ThreadLocal and as such each separate web server worker thread has its own ContextHolder.

            Comment


            • #7
              noted, will try to implement a custom BasicProcessingFilter that to write directly to the ContextHolder.

              thanks!

              Comment


              • #8
                On the server-side, the BASIC header will be unwrapped by BasicProcessingFilter, who authenticates the user via an AuthenticationManager and then puts the resulting Authentication into the HttpSession. The AutoIntegrationFilter (which is removed from 0.7.0, so use HttpSessionIntegrationFilter instead) then grabs the Authentication from HttpSession and manages its exposure on the server-side ContextHolder.

                As HttpInvoker is stateless, this means a session will be created each time a request is received. If this concerns you, just set a very low session timeout value in web.xml.
                How does the client then read Authentication attributes populated on the server? For example, I want to be able to retrieve the GrantedAuthority objects based on the Authenticated user on the web server. Does the BasicProcessingFilter mapping take care of this too? Is it as simple as executing something like the following upon completion of the HttpInvoker remote method call?

                Code:
                SecurityContextHolder.getContext().getAuthentication().getAuthorities();

                Comment


                • #9
                  Not quite sure what you mean - a remote client is authenticating to the server, so it submits an authentication token to the server, which authenticates the client and populates the context on the server-side based on the information submitted. The client doesn't obtain any security information back again.

                  Comment


                  • #10
                    Originally posted by Luke View Post
                    Not quite sure what you mean - a remote client is authenticating to the server, so it submits an authentication token to the server, which authenticates the client and populates the context on the server-side based on the information submitted. The client doesn't obtain any security information back again.
                    This is not a web app. It is a rich client(A normal Swing app) which needs to obtain a list of GrantedAuthority objects based on an ACL on the server. The Rich Client app will then iterate through this collection of GrantedAuthority settings and display or hide certain pieces of functionality.

                    It's not like I want to check whether a user is authorized to a particular URL through Spring HttpInvoker every time a user initiates an action through the remote URL call. I want to control what features and functionality the user sees and subsequently has access to right when they log in.

                    There must be some relatively easy way to obtain this back in the SecurityContext Authentication object.

                    Comment


                    • #11
                      I'm aware it's not a webapp, but the purpose of the standard filters is to authenticate a remote client *to the server*. You presumably want to authenticate someone on the client machine to the client application so you want the acegi infrastructure on the client, configured to access whatever repository of security information you want to use. Of course this raises quite a few issues since the configuration information may be sensitive and would have to be secured on the client machine. But presumably this will be possible otherwise it wouldn't really be possible to secure the app in the first place?

                      Comment

                      Working...
                      X