Announcement Announcement Module
Collapse
No announcement yet.
request.getRemoteUser() Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • request.getRemoteUser()

    Ben,
    Can Ageci set the correct remote user on the request object on successful authentication?

    ie
    Code:
    request.getRemoteUser()
    should transparently return

    Code:
    ((net.sf.acegisecurity.providers.dao.User) auth.getPrincipal()).getUsername()
    Some third party libraries/filters like Clickstream use the standard HttpServletRequest API call getRemoteUser() to determine the remote user. It would be nice if the same API call works even when using Acegi authentication as it would make the Acegi authentication more spec compliant or more aligned with the Servlet Web Container authentication.

    I do see the difficulty implementing this since the HttpServletRequest interface does not have a setRemoteUser(..) and neither does Weblogic's' implementation of this interface however maybe you can come up with a solution like wrapping the container HttpServletRequest with a proxy in the Agegi filter.


    Thanks,
    Sanjiv

  • #2
    If you'd like to implement a HttpServletRequest wrapper, I'd be happy to add it to the source code. Personally I'd try one of the following though:

    (i) Modify code relying on HttpServletRequest.getRemoteUser(). The "principal source" should be pluggable in any decent library, or made pluggable by introduction of an interface. I'm sure projects like ClickStream would welcome an pluggable approach. If it's pluggable you can easily obtain the Authentication in the standard way from the ContextHolder.

    (ii) Use a container adapter. That way Acegi Security will be used for authentication via servlet spec security, and the container will thus populate the HttpServletRequest. Although I tend to stay away from container adapters as much as possible (difficult configuration, need to use the servlet spec to commence authentication based on URL requests, non-portable between web containers).

    Comment


    • #3
      Here is the HttpServletRequestWrapper

      Code:
      public class AcegiHttpServletRequestWrapper extends HttpServletRequestWrapper {
      
          public AcegiHttpServletRequestWrapper(HttpServletRequest request) {
              super(request);
          }
      
          public boolean isUserInRole(String role) {
              return isGranted(role);
          }
      
          public String getRemoteUser() {
      
              Authentication auth = getAuthentication();
      
              if (auth == null)
                  return null;
      
              return ((net.sf.acegisecurity.providers.dao.User) auth.getPrincipal()).getUsername();
          }
      
          private Authentication getAuthentication() {
      
              if (ContextHolder.getContext() != null && ContextHolder.getContext() instanceof SecureContext) {
                  return ((SecureContext) ContextHolder.getContext()).getAuthentication();
              }
      
              return null;
          }
      
          private boolean isGranted(String role) {
      
              Authentication auth = getAuthentication();
      
              if (auth == null)
                  return false;
      
              for &#40;int i=0; i < auth.getAuthorities&#40;&#41;.length; i++&#41; &#123;
                  if &#40;role.equals&#40;auth.getAuthorities&#40;&#41;&#91;i&#93;.getAuthority&#40;&#41;&#41;&#41;
                      return true;
              &#125;
      
              return false;
          &#125;
      &#125;
      Here is the filter

      Code:
      public class AcegiHttpServletRequestFilter implements Filter &#123;
      
          public void init&#40;FilterConfig filterConfig&#41; throws ServletException &#123;&#125;
      
          public void doFilter&#40;ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain&#41; throws IOException, ServletException &#123;
      
              HttpServletRequest request = &#40;HttpServletRequest&#41; servletRequest;
      
              if &#40;!&#40;request instanceof AcegiHttpServletRequestWrapper&#41;&#41; &#123;
                  request = new AcegiHttpServletRequestWrapper&#40;request&#41;;
              &#125;
      
              filterChain.doFilter&#40;request, servletResponse&#41;;
          &#125;
      
          public void destroy&#40;&#41; &#123;&#125;
      &#125;
      And here is the web.xml:

      <filter>
      <filter-name>Acegi Http Servlet Request Filter</filter-name>
      <filter-class>packagename.AcegiHttpServletRequestFilter</filter-class>
      </filter>

      <filter-mapping>
      <filter-name>Acegi Http Servlet Request Filter</filter-name>
      <url-pattern>/*</url-pattern>
      </filter-mapping>

      Comment


      • #4
        Thanks Sanjiv, this is a really useful integration. I'll add it to Acegi Security CVS later on today.

        Comment


        • #5
          Ben,
          Actually I just asked the question and never got to implement it.

          Thank 'paramosyermos' for the implementation.

          Looking forward to using this feature.

          Regards,
          Sanjiv

          Comment


          • #6
            Ooops, thanks paramosyermos (could you send me a real name via email, so I can add you to the contributors?).

            Comment


            • #7
              I've now added this to CVS (renamed a little), along with unit tests. See the net.sf.acegisecurity.ui.wrapper package.

              Comment


              • #8
                Is this implemented in Acegi by default now? I don't see the "net.sf.acegisecurity.ui.wrapper" package.

                Comment


                • #9
                  Matt, it's still in CVS. You'll need to checkout. We really need to get a version 0.7.0 out sometime soon....

                  Comment


                  • #10
                    I was looking CVS - then I discovered there's more than one src tree: src and core/main/src. I'm guessing the "src" tree is deprecated? Thanks for the help, I'll try using the ContextHolderAwareRequestFilter to get request.getRemoteUser() to work.

                    Comment


                    • #11
                      Yes, the old "/src" tree was used with Ant, we've now moved to Maven style directories thus "/core/src/main/java" is used.

                      Comment


                      • #12
                        getting NullPointerException using the code from CVS

                        Hi all.

                        I'm getting a NullPointerException using this code. It only happens when I try to log in using an non-existant username/password. Everything works fine otherwise, so I'm not sure where to start troubleshooting.

                        The exception occurs when I submit my login form to j_security_check:
                        Code:
                        java.lang.NullPointerException
                        net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider.authenticate&#40;DaoAuthenticationProvider.java&#58;237&#41;
                        net.sf.acegisecurity.providers.ProviderManager.doAuthentication&#40;ProviderManager.java&#58;128&#41;
                        net.sf.acegisecurity.AbstractAuthenticationManager.authenticate&#40;AbstractAuthenticationManager.java&#58;49&#41;
                        net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter.attemptAuthentication&#40;AuthenticationProcessingFilter.java&#58;82&#41;
                        net.sf.acegisecurity.ui.AbstractProcessingFilter.doFilter&#40;AbstractProcessingFilter.java&#58;296&#41;
                        net.sf.acegisecurity.util.FilterToBeanProxy.doFilter&#40;FilterToBeanProxy.java&#58;105&#41;
                        net.sf.acegisecurity.ui.wrapper.ContextHolderAwareRequestFilter.doFilter&#40;ContextHolderAwareRequestFilter.java&#58;50&#41;
                        I'm using the filter and wrapper from:
                        http://acegisecurity.sourceforge.net...estFilter.html
                        http://acegisecurity.sourceforge.net...stWrapper.html

                        Here's the relevant part of my web.xml:
                        Code:
                        <filter>
                            <filter-name>Acegi Http Servlet Request Filter</filter-name>            
                            <filter-class>net.sf.acegisecurity.ui.wrapper.ContextHolderAwareRequestFilter</filter-class>
                        </filter>
                        ...
                        <filter-mapping>
                            <filter-name>Acegi Http Servlet Request Filter</filter-name>
                            <url-pattern>/*</url-pattern>
                        </filter-mapping>
                        And my securityContext.xml:
                        Code:
                        <beans>
                        	
                        	<bean id="authenticationDao" 
                        	    class="com.briankuhn.birthdays.web.acegi.AccountAuthenticationDAO">
                        	    <property name="accountDAO"><ref bean="accountDAO"/></property>
                        	</bean>
                        
                        	<bean id="filterInvocationInterceptor" 
                        	    class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
                            	<property name="authenticationManager">
                            	    <ref local="authenticationManager"/>
                            	</property>
                            	<property name="accessDecisionManager">
                            	    <ref local="accessDecisionManager"/>
                            	</property>
                         		<property name="objectDefinitionSource">
                        			<value>
                        			    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                        			    PATTERN_TYPE_APACHE_ANT
                        				/secure/**=ROLE_USER
                        			</value>
                        		</property>
                        	</bean>
                        	
                        	<bean id="daoAuthenticationProvider" 
                        	    class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
                             	<property name="authenticationDao">
                             	    <ref local="authenticationDao"/>
                             	</property>
                             	<property name="userCache">
                             	    <ref local="userCache"/>
                             	</property>
                        	</bean>
                        	
                        	<bean id="userCache" 
                        	    class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
                        		<property name="minutesToIdle"><value>5</value></property>
                        	</bean>
                        
                        	<bean id="authenticationManager" 
                        	    class="net.sf.acegisecurity.providers.ProviderManager">
                        		<property name="providers">
                        		  <list>
                        		    <ref local="daoAuthenticationProvider"/>
                        		  </list>
                        		</property>
                        	</bean>
                        
                        	<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
                        
                        	<bean id="accessDecisionManager" 
                        	    class="net.sf.acegisecurity.vote.AffirmativeBased">
                           		<property name="allowIfAllAbstainDecisions">
                           		    <value>false</value>
                           		</property>
                        		<property name="decisionVoters">
                        		  <list>
                        		    <ref local="roleVoter"/>
                        		  </list>
                        		</property>
                        	</bean>
                        
                        	<bean id="authenticationProcessingFilter" 
                        	    class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
                        		<property name="authenticationManager">
                        		    <ref local="authenticationManager"/>
                        		</property>
                        		<property name="authenticationFailureUrl">
                        		    <value>/loginForm.html?denied=true</value>
                        		</property>
                        		<property name="defaultTargetUrl">
                        		    <value>/secure/birthdayList.html</value>
                        		</property>
                        		<property name="filterProcessesUrl">
                        		    <value>/j_security_check</value>
                        		</property>
                        	</bean>
                        
                        	<bean id="securityEnforcementFilter" 
                        	    class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
                        		<property name="filterSecurityInterceptor">
                        		    <ref local="filterInvocationInterceptor"/>
                        		</property>
                        		<property name="authenticationEntryPoint">
                        		    <ref local="authenticationProcessingFilterEntryPoint"/>
                        		</property>
                        	</bean>
                        
                        	<bean id="authenticationProcessingFilterEntryPoint" 
                        	    class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                        		<property name="loginFormUrl">
                        		    <value>/loginForm.html</value>
                        		</property>
                        		<property name="forceHttps">
                        		    <value>false</value>
                        		</property>
                        	</bean>
                        
                        	<bean id="autoIntegrationFilter" 
                        	    class="net.sf.acegisecurity.ui.AutoIntegrationFilter" />
                        
                        </beans>
                        Any ideas? I've done a lot of testing and have gotten no where so far...

                        Thanks,
                        Brian Kuhn

                        Comment


                        • #13
                          That line of DaoAuthenticationProvider is blank in the current CVS HEAD, so would you please checkout from CVS and try again, posting the resulting error message along with your full web.xml (in case it is web filter ordering related, which is the main source of most support issues with Acegi Security).

                          Comment


                          • #14
                            getting NullPointerException using the code from CVS

                            I'm using the 0.6.1 release + the 2 classes from cvs. I thought this would work as an independant patch. I guess I need to pull everything from CVS...

                            Comment


                            • #15
                              fixed...

                              These two classes do work as a stand alone patch to 0.6.1. My problem was that my AuthenticationDao was returning null instead of throwing a UsernameNotFoundException.

                              Comment

                              Working...
                              X