Announcement Announcement Module
Collapse
No announcement yet.
Help me understand why I am not seeing authentication Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help me understand why I am not seeing authentication

    I read through all the docs I could get my hands on, played with the sample code, and after some fighting, I finally got some stuff in and it seems like its working somewhat, but I am not seeing my custom UserDetailsService code executing on a request.

    Here are my config files
    Code:
    <?xml version="1.0"?>
    
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_4.dtd">
    
    <web-app>
    
    	<display-name>BPASS Controller</display-name>
    	<context-param>
    		<param-name>contextConfiguration</param-name>
    		<param-value>WEB-INF/applicationContext.xml</param-value>
    	</context-param>
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	
    	<!--<servlet>
    		<servlet-name>context</servlet-name>
    		<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>-->
    	
    	<servlet>
    		<servlet-name>bpass</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>2</load-on-startup>
    	</servlet>
    	
    	<servlet-mapping>
    		<servlet-name>bpass</servlet-name>
    		<url-pattern>/bpass/*</url-pattern>
    	</servlet-mapping>
    	
    	<!--<servlet-mapping>
    		<servlet-name>context</servlet-name>
    		<url-pattern>/context/*</url-pattern>
    	</servlet-mapping>-->
    	
    	<!-- Security configuration -->
    	<filter>
    		<filter-name>Acegi HTTP Session Integration</filter-name>
    		<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
    		<init-param>
    			<param-name>targetClass</param-name>
    			<param-value>org.acegisecurity.context.HttpSessionContextIntegrationFilter</param-value>
    		</init-param>
    	</filter>
    	
    	<filter-mapping>
    		<filter-name>Acegi HTTP Session Integration</filter-name>
    		<url-pattern>/bpass/*</url-pattern>
    	</filter-mapping>
    	
    	<filter>
    		<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
    		<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
    		<init-param>
    			<param-name>targetClass</param-name>
    			<param-value>org.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
    		</init-param>
    	</filter>
    	
    	<filter-mapping>
    		<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
    		<url-pattern>/bpass/*</url-pattern>
    	</filter-mapping>
    </web-app>
    Code:
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    	<bean id="bpassControllerService" class="com.bofa.esm.bpass.BpassServiceImpl">
    		<property name="userDao">
    			<ref local="UserDAO"/>
    		</property>
    		<property name="organizationDao">
    			<ref local="OrganizationDAO"/>
    		</property>
    		<property name="groupDao">
    			<ref local="GroupDAO"/>
    		</property>
    		<property name="softwarePackageDao">
    			<ref local="SoftwarePackageDAO"/>
    		</property>		
    		<property name="groupMemberDao">
    			<ref local="GroupMemberDAO"/>
    		</property>
    		<property name="roleDao">
    			<ref local="RoleDAO"/>
    		</property>
    		<property name="groupRoleDao">
    			<ref local="GroupRoleDAO"/>
    		</property>
    		<property name="eswdProfileDao">
    			<ref local="EswsProfileDAO"/>
    		</property>
    		<property name="authenticationDomainDao">
    			<ref local="AuthenticationDomainDAO"/>
    		</property>
    	</bean>
    	
    	<bean id="UserDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/userDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="OrganizationDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/organizationDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="GroupDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/groupDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="SoftwarePackageDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/softwarePackageDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>	
    	
    	<bean id="GroupMemberDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/groupMemberDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="RoleDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/roleDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="GroupRoleDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/groupRoleDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="EswsProfileDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/eswdProfileDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    	<bean id="AuthenticationDomainDAO" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:/authenticationDomainDao</value>
    		</property>
    		<property name="resourceRef">
    			<value>false</value>
    		</property>
    	</bean>
    	
    
    </beans>
    And my UserDetailsService:
    Code:
    /*
     * Created on May 10, 2006
     */
    package com.bofa.esm.auth.acegi;
    
    import org.acegisecurity.userdetails.User;
    import org.acegisecurity.userdetails.UserDetails;
    import org.acegisecurity.userdetails.UserDetailsService;
    import org.acegisecurity.userdetails.UsernameNotFoundException;
    import org.springframework.dao.DataAccessException;
    
    import com.bofa.esm.dataaccess.bpass.dao.UserDaoIfc;
    import com.bofa.esm.dataaccess.bpass.vo.UserVO;
    
    /**
     * This class implements the UserDetailsService, which is used to lookup the
     * UserDetails.  This is intended to be used with the DoaAuthenticationProvider.
     * 
     * @author Michael Bauer
     * @version 1.0
     */
    public class BpassUserDetailsService implements UserDetailsService {
    	private UserDaoIfc userDao;
    
    	
    	/* (non-Javadoc)
    	 * @see org.acegisecurity.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
    	 */
    	public UserDetails loadUserByUsername(String username)
    			throws UsernameNotFoundException, DataAccessException {
    		UserVO vo = userDao.getById(username);
    		User user = new User(username,"",false,false,false,false,null);
    		if(vo==null) {
    			throw new UsernameNotFoundException("This is bogus!");
    		}
    		
    		return user;
    	}
    	
    	/**
    	 * @param userDao The userDao to set.
    	 */
    	public void setUserDao(UserDaoIfc userDao) {
    		this.userDao = userDao;
    	}
    }
    When I execute an HttpInvoker request, I see some Acegi stuff run around the HttpSessionContextIntegrationFilter, which I thought ensured the HttpSession was there and had some Auth info in it. The code goes on to call whatever code is in the HttpInvoker request. This would be fine if I passed in a username and password, but currently I am not passing this information. What I was expecting to happen was a login failure.

    Just to be sure, I added some break points in the BpassUserDetailsService. to see what it was doing, and to my surprise it was never called! From reading, I was under the impression its ALWAYS called. Also, I was under the impression that failure to authenticate would mean a failure on the HttpInvoker call, but this is also not the case as Acegi ran the HttpInvoker request anyway, returning the results as if Acegi wasn't even there.

    I am confussed. Can someone please tell me what I am doing wrong?

  • #2
    Do you have any access restrictions defined? If there are no authorization requirements then there is no need for authentication and no reason why your user service will be called.

    I would start from the sample app configuration if I were you and get that working first to make sure you have all the necessary filters in place. Then adapt it to your needs.

    It also manages the acegi filter chain in the app context (using FilterChainProxy) rather than defining all the filters in the web.xml file.

    Comment


    • #3
      The problem I am having is that all the examples and docs I found deal primarily with a web app, which I am not. What I am dealing with is a SWT (Eclipse) fat client connecting to a Spring HttpInvoker for RPC.

      The only doc I have been able to find is this one. It is apparently missing some steps.

      If someone has a better "how-to" covering HttpInvoker, I would REALLY appreciate it. Basically, all I am looking for is authentication (who the heck are you and is your password right). The backend I am connecting too does authorization already. The only authorization I need is basically your Password and Username is right, so you can use the service.

      Comment


      • #4
        The sample app does have support for using Spring's HttpInvoker. You can see the client code here:

        http://acegisecurity.org/multiprojec...plication.html

        You will probably still need a standard set of Acegi filters on the server side (refer to the app context files in the sample app). The normal sequence of events is that the FilterSecurityInterceptor (or some other code down the pipe) throws an AccessDeniedException (or AuthenticationException). This is caught by the ExceptionTranslationFilter:

        http://acegisecurity.org/multiprojec...ionFilter.html

        which will kick-start the authentication process if the user is anonymous or hasn't been authenticated. So if your authorization code can collaborate with this then you should be OK - you could just throw an AuthenticationException if there is no authentication object present in the security context.

        Alternatively, you could add a FilterSecurityInterceptor to the Acegi filters and require a default role to access any URL within the app.

        Comment


        • #5
          One deficiency of the sample client is that it seems to be coupling the security logic with the business logic. It also doesn't use the RemoteAuthenticationManager that we've read we should use on the client side.

          Comment


          • #6
            Ok, I took a step back, removed all the security stuff, and took another look at the sample Contacts code. I now seem to have something *working*. The only problem is that I only can get access to stuff that has ROLE_ANONYMOUS. I think this is because the passwords are not being validated, but I am not sure. Withing the sample code, which class actually does the password authentication? I thought it was the DoaAuthenticationProvider, but when I look at it, its not clear how to tell it the right passwords.

            I plan of implementing a custom AuthenticationProvider anyway that will use our own code to authenticate the password and get the UserDetails. Should I just count this as a *win* and move on, or is there something I am missing?

            Comment


            • #7
              Ok, I wrote a custom AuthenticationProvider, and its working, but I am still getting a 401. What do I need to look at?

              Comment


              • #8
                Originally posted by mbabauer
                Ok, I wrote a custom AuthenticationProvider, and its working, but I am still getting a 401. What do I need to look at?
                Not sure if this helps, but I saw this in the reference doc:

                The configured AuthenticationManager processes each authentication request. If authentication fails, the configured AuthenticationEntryPoint will be used to retry the authentication process. Usually you will use the BasicProcessingFilterEntryPoint, which returns a 401 response with a suitable header to retry HTTP Basic authentication. If authentication is successful, the resulting Authentication object will be placed into the SecurityContextHolder.
                Are you configuring an AuthenticationEntryPoint?

                Comment


                • #9
                  I am stupid

                  I figured it out. I had a custom UserDetailsServices object to create me UserDetails object...well, I was creating the User object passing in all 'false', which basically said "This accound is expired, the credentials are expired, etc, etc". I should have passed 'true's instead.

                  Sometimes I can be such a ditz .

                  Comment

                  Working...
                  X