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

  • Login with database and Hibernate

    With InMemoryDaoImpl all works perfectly!


    The content of webhilex-security.xml is:

    Code:
    	<!-- ======================== AUTHENTICATION ======================= -->
    
    	<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
    		<property name="providers">
    			<list>
    				<ref bean="daoAuthenticationProvider" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
    		<property name="userDetailsService"> <ref local="memoryAuthenticationDao" /></property>
    	</bean>
    
    	<bean id="memoryAuthenticationDao" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
    		<property name="userMap">
    			<value>edo=pass,ROLE_SUPERVISOR anna=pass,ROLE_USER</value>
    		</property>
    	</bean>
    Now I would move the authentication on the db with a custom schema.
    In particular I have:

    Code:
    CREATE TABLE `webhilexdb`.`user`(
    	`username` VARCHAR(50) PRIMARY KEY,
    	`password` VARCHAR(50) NOT NULL,
    	`firstname` VARCHAR(50) NOT NULL,
    	`lastname` VARCHAR(50) NOT NULL,
    	`telephone` VARCHAR(50),
    	`email` VARCHAR(50) NOT NULL
    ) TYPE=INNODB;
    
    CREATE TABLE `webhilexdb`.`role` (
    	`id` SMALLINT PRIMARY KEY,
    	`name` VARCHAR(50) NOT NULL
    ) TYPE=INNODB;
    
    CREATE TABLE `webhilexdb`.`authorities` (
    	`usernameauthorities` VARCHAR(50) NOT NULL,
    	`authority` SMALLINT NOT NULL,
    	PRIMARY KEY(usernameauthorities, authority),
    	FOREIGN KEY(usernameauthorities) REFERENCES user(username) ON DELETE CASCADE ON UPDATE CASCADE,
    	FOREIGN KEY(authority) REFERENCES role(id)
    ) TYPE=INNODB;
    
    CREATE TABLE `webhilexdb`.`hilexprocess` (
    	`idprocess` VARCHAR(50) NOT NULL,
    	`ownerprocess` VARCHAR(50) NOT NULL,
    	`first` VARCHAR(50) NOT NULL,
    	`second` VARCHAR(50) NOT NULL,
    	`third` VARCHAR(50) NOT NULL,
    	PRIMARY KEY(idprocess, ownerprocess),
    	FOREIGN KEY(ownerprocess) REFERENCES user(username) ON DELETE CASCADE ON UPDATE CASCADE
    ) TYPE=INNODB;
    What I must put in webhilex-security.xml ?
    I would not implement with JdbcDaoImpl, but with Hibernate!

    I have already the hibernate mapping for all table. For "user" I have:

    Code:
    <hibernate-mapping package="it.exeura.hilex.hibernate.mapping">
    
        <class name="User" table="user">
            <id name="username" column="username" type="string">
                <generator class="assigned"/>
            </id>
     
            <property name="password" column="password" type="string"  not-null="true" />
            <property name="firstname" column="firstname" type="string"  not-null="true" />
            <property name="lastname" column="lastname" type="string"  not-null="true" />
            <property name="telephone" column="telephone" type="string" />
            <property name="email" column="email" type="string"  not-null="true" />
     
            <set name="authoritiesSet" inverse="true">
                <key column="usernameauthorities"/>
                <one-to-many class="Authorities"/>
            </set>
     
            <set name="hilexprocessSet" inverse="true">
                <key column="ownerprocess"/>
                <one-to-many class="Hilexprocess"/>
            </set>
        </class>
        
    </hibernate-mapping>
    I will need to write my AuthenticationDAO (i.e. implement AuthenticationDAO) and then extend HibernateDaoSupport. But I don't understanding how to do it!

    Can you give me an example?

    Thanks thanks tanks and sorry for my bad english !!!!!!!!!!

  • #2
    Have you looked at org.acegisecurity.userdetails.jdbc.JdbcDaoImpl
    write like somthing this class, just with Hibernate.

    Comment


    • #3
      Thank but no! In this mode I must extends MappingSqlQuery.

      I know that, in Hibernate, exists an other solution, but I don't how to implement it!

      Please, can you give me an example of that implementation ?

      Thank you very much!

      Comment


      • #4
        I can't provide you Authentication code with Hibernate, because I haven't written any, but the matter that daoAuthenticationProvider needs userDetailsService interfase and all you need is implement that interface
        where you should write your own loadUserByUsername() method.

        <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenti cationProvider">
        <property name="userDetailsService">
        <ref local="yourHibernateDaoImpl" />
        </property>
        </bean>

        Comment


        • #5
          I have implemented some classes:

          Code:
          public interface UserDao
          {
              public User findByUsername(String username);
          
              public User getByUsernameAndPassword(String username, String password);
          
              public void saveUser(User user);
          }
          and:

          Code:
          public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
              private SessionFactory sessionFactory;
          
              public User findByUsername(final String username)
              {
                  HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory);
          
                  return (User) hibernateTemplate.execute(new HibernateCallback()
                      {
                          public Object doInHibernate(Session session) throws HibernateException
                          {
                              return session.load(User.class, username);
                          }
                      });
              }
          
              public User getByUsernameAndPassword(String username, String password)
              {
                  List users = getHibernateTemplate().findByNamedParam(
                          "select u from User as u where u.username=:username and u.password=:password", new String[]
                          { "username", "password" }, new Object[]
                          { username, password });
                  if (users.size() == 1)
                  {
                      return (User) users.get(0);
                  }
                  return null;
              }
          
              public void saveUser(User user)
              {
                  getHibernateTemplate().saveOrUpdate(user);
          
              }
          In my webhilex-security.xml I have:

          Code:
          	<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
          		<property name="providers">
          			<list>
          				<ref bean="daoAuthenticationProvider" />
          			</list>
          		</property>
          	</bean>
          
          	<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
          		<property name="userDetailsService">
          			<ref local="UserDaoImpl" />
          		</property>
          	</bean>
          What's left ?
          Help me!

          Comment


          • #6
            I'm near the solution but I don't understand how to implement this!

            Can you give me a simple example?
            Thanks!

            Comment


            • #7
              Can any1 plz send me a sample code for a user to login retreiving his username and password from the database....

              I'm going crazy!

              Comment


              • #8
                Here's what I did. This should probably also work for you.

                I have a User object configured using Hibernate Synchronizer (Eclipse). I altered it to implement UserDetails. The UserDAO needs to implement UserDetailsService. Now you can write a custom daoAuthenticationProvider. What I did is copy the code from the standard Acegi DaoAuthenticationProvider. Just extending it didn't work for me, can't really remember why though. Now you can define this one in your acegi-security-context.xml (or whatever you like to call it).

                Relevant pieces of code:

                Code:
                public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { 
                 
                    private static final Logger s_logger = Logger.getLogger(DaoAuthenticationProvider.class); 
                     
                    private UserDetailsService m_userDetailsService; 
                    private PasswordEncoder m_passwordEncoder = new PlaintextPasswordEncoder(); 
                    private SaltSource m_saltSource; 
                     
                    protected final UserDetails retrieveUser(String username, 
                            UsernamePasswordAuthenticationToken authentication) 
                        throws AuthenticationException 
                    { 
                        UserDetails loadedUser; 
                         
                        try { 
                            loadedUser = UserDAO.getInstance().loadUserByUsername(username); 
                        }  
                        catch (DataAccessException repositoryProblem) { 
                            throw new AuthenticationServiceException( 
                                    repositoryProblem.getMessage(), repositoryProblem); 
                        } 
                 
                        if (loadedUser == null) { 
                            throw new AuthenticationServiceException( 
                                    "AuthenticationDao returned null, which is an interface contract violation"); 
                        } 
                         
                        s_logger.debug(loadedUser.toString()); 
                         
                        return loadedUser; 
                    } 
                     
                    protected void additionalAuthenticationChecks(UserDetails userDetails,  
                            UsernamePasswordAuthenticationToken authentication) 
                        throws AuthenticationException  
                    { 
                        Object salt = null; 
                         
                        if(m_saltSource != null) { 
                            salt = m_saltSource.getSalt(userDetails); 
                        } 
                         
                        if(!m_passwordEncoder.isPasswordValid(userDetails.getPassword(),  
                                authentication.getCredentials().toString(), salt)) { 
                            throw new BadCredentialsException(messages.getMessage( 
                                    "AbstractUserDetailsAuthenticationProvider.badCredentials", 
                                    "Bad credentials"), userDetails); 
                        } 
                    } 
                }
                Code:
                public class User extends BaseUser implements UserDetails { 
                     
                	private static final long serialVersionUID = 1L; 
                 
                    private GrantedAuthority[] m_merged_authorities = null; 
                  
                    /** 
                     * Get all granted authorities, both from the user and all 
                     * the groups it is in. Lazy init. 
                     * @return Array of unique granted authorities, used by Acegi 
                     */ 
                    public GrantedAuthority[] getAuthorities() { 
                         
                        if(m_merged_authorities == null) { 
                             
                            Set<Group> groups = getGroups(); 
                            List<AuthorityImpl> auth_buf = new LinkedList<AuthorityImpl>(); 
                             
                            // Uniquely merge authorities for the groups 
                            Iterator<Group> group_iter = groups.iterator(); 
                            while(group_iter.hasNext()) { 
                                Iterator<AuthorityImpl> auth_iter = group_iter.next().getAuthorityImpls().iterator(); 
                                while(auth_iter.hasNext()) { 
                                    AuthorityImpl cur_auth = auth_iter.next(); 
                                    if(!auth_buf.contains(cur_auth)) { 
                                        auth_buf.add(cur_auth); 
                                    } 
                                } 
                            } 
                             
                            // Uniquely merge the user's own authorities 
                            Iterator<AuthorityImpl> auth_iter = getAuthorityImpls().iterator(); 
                            while(auth_iter.hasNext()) { 
                                AuthorityImpl cur_auth = auth_iter.next(); 
                                if(!auth_buf.contains(cur_auth)) { 
                                    auth_buf.add(cur_auth); 
                                } 
                            } 
                             
                            m_merged_authorities = (GrantedAuthority[]) auth_buf.toArray(new GrantedAuthority[auth_buf.size()]); 
                        } 
                         
                        return m_merged_authorities; 
                    } 
                     
                    /** 
                     * Set authorities from array to set defined in base 
                     * @param authorities 
                     */ 
                    public void setAuthorities(GrantedAuthority[] authorities) { 
                        setAuthorityImpls(new TreeSet<AuthorityImpl>(Arrays.asList((AuthorityImpl[])authorities))); 
                    } 
                     
                    public boolean isAccountNonExpired() { 
                        return true; 
                    } 
                     
                    public boolean isAccountNonLocked() { 
                        return true; 
                    } 
                     
                    public boolean isCredentialsNonExpired() { 
                        return true; 
                    } 
                     
                    public boolean isEnabled() { 
                        return !isDisabled(); 
                    } 
                }
                Code:
                public class UserDAO extends BaseUserDAO implements UserDetailsService { 
                  
                	public Order getDefaultOrder() { 
                		return Order.asc("username"); 
                	} 
                 
                    /* 
                     *  (non-javadoc) 
                     * @see UserDetailsService#loadUserByUsername(String username) 
                     */ 
                    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
                         
                        Query q = getQuery("FROM User u WHERE u.username = :username"); 
                        q.setParameter("username", username); 
                         
                        User user = (User) q.uniqueResult(); 
                         
                        if(user == null) { 
                            throw new UsernameNotFoundException("User " + username + " not found."); 
                        } 
                         
                        return (UserDetails) user; 
                    } 
                }
                application-context-acegi-security.xml
                Code:
                <?xml version="1.0" encoding="UTF-8" ?>
                <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
                <beans>
                
                	<!-- FILTER CHAIN DEFINITION -->
                	<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
                		<property name="filterInvocationDefinitionSource">
                			<value>
                				CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                				PATTERN_TYPE_APACHE_ANT
                				/**=securityContextHolderAwareRequestFilter,httpSessionContextIntegrationFilter,authenticationProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
                			</value>
                		</property>
                	</bean>
                	
                	<!-- Filter to integrate user roles with HttpServletRequest -->
                	<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
                	
                	<!-- AUTHENTICATION -->
                	<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
                		<property name="providers">
                			<list>
                				<ref local="daoAuthenticationProvider"/>
                			</list>
                		</property>
                	</bean>
                	
                	<bean id="userDao" class="nl.graphit.npe.data.admin.dao.UserDAO"/>
                	
                	<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.ShaPasswordEncoder"/>
                	
                	<bean id="daoAuthenticationProvider" class="nl.graphit.npe.logic.security.DaoAuthenticationProvider">
                		<property name="userDetailsService"><ref local="userDao"/></property>
                		<!-- <property name="userCache"><ref local="userCache"/></property> -->
                		<property name="passwordEncoder"><ref local="passwordEncoder"/></property>
                	</bean>
                	
                	<!-- Anonymous user is used to access the login page -->
                	<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
                		<property name="key"><value>foobar</value></property> <!-- Apparently a dummy key is needed -->
                        <property name="userAttribute"><value>anonymousUser,ROLE_ANONYMOUS</value></property>
                    </bean>
                   
                    <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
                    	<property name="key"><value>foobar</value></property> <!-- Apparently a dummy key is needed -->
                    </bean>
                
                	<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
                	
                	<bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
                		<property name="authenticationManager"><ref local="authenticationManager"/></property>
                		<property name="authenticationEntryPoint"><ref local="basicProcessingFilterEntryPoint"/></property>
                	</bean>
                	
                	<bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
                        <property name="realmName"><value>User Realm</value></property>
                    </bean>
                   
                   <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
                
                	<bean id="securityEnforcementFilter" class="org.acegisecurity.intercept.web.SecurityEnforcementFilter">
                        <property name="filterSecurityInterceptor"><ref local="filterInvocationInterceptor"/></property>
                        <property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
                    </bean>
                </beans>
                I use the SecurityContextHolderAwareRequestFilter so I can use visibleOnUserRole and enabledOnUserRole attributes in my tomahawk component tags.

                Good luck! I hope you work it out.

                Comment

                Working...
                X