Announcement Announcement Module
Collapse
No announcement yet.
Alternative of DBCP when we can't have a proxy user Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Alternative of DBCP when we can't have a proxy user

    I am using Spring roo to develop web application , the JPA code generated by Spring roo is using dbcp connection pooling .
    In our setup here we can’t have proxy users hence can’t use connection pooling here (I think) , here in any application the practice is we will get the user name and password from the login screen and will create a JDBC connection for him and will authenticate him and let him in the system if he was authenticated.
    We will keep the user name password in session or we will keep the JDBC connection in the user session and later whenever we need we will use this connection.
    The connection will be closed on user logout or on his Http session timeout.
    I need your help to guide me what is the best practice by spring community to handle such cases (when we can’t have a connection pool).
    Please note that I want to keep using ROO for all the other advantages and be able to provide my custom implementation in such cases.
    Waiting for your kind response
    Sajjad

  • #2
    I found out that the "org.springframework.jdbc.datasource.UserCredentia lsDataSourceAdapter" is the class to use in these cases and commneted the DBCP settings and configured my own data source like below

    <!--
    As suggessted in below blog
    http://affy.blogspot.com/2006/12/per...or-spring.html

    -->


    <!-- this datasource must handel per-user connection pooling -->
    <bean id="targetDataSource" class="org.springframework.jdbc.datasource.DriverM anagerDataSource" destroy-method="finalize">
    <property name="driverClassName" value="${database.driverClassName}"/>
    <property name="url" value="${database.url}"/>
    </bean>

    <!-- this object wraps the original datasource allows change of user when needed -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.UserCre dentialsDataSourceAdapter">
    <property name="targetDataSource" ref="targetDataSource"/>
    <property name="username"><value>unknown</value></property>
    <property name="password"><value>unknown</value></property>
    </bean>

    <!-- this bean does real work, inject the user adapter so it can change the user credentials -->
    <bean id="create" class="myPackage.MyAuthenticationProvider">
    <!--
    <property name="sessionFactory" ref="sessionFactory" />
    -->
    <property name="userAdapter" ref="dataSource" />
    </bean>

    <bean class="org.springframework.orm.jpa.JpaTransactionM anager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

    <bean class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean" id="entityManagerFactory">
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="dataSource" ref="dataSource"/>
    </bean>

    and below is the myPackage.MyAuthenticationProvider class


    public class MyAuthenticationProvider extends
    AbstractUserDetailsAuthenticationProvider {

    @Autowired
    private UserCredentialsDataSourceAdapter userAdapter;

    @Override
    protected void additionalAuthenticationChecks(UserDetails arg0,
    UsernamePasswordAuthenticationToken arg1)
    throws AuthenticationException {
    // TODO Auto-generated method stub
    //**We probably don't have to do anything here
    System.out.println("Sajjad Ahmed Paracha");
    }

    @Override

    /**
    * This method should have the database call where we will try to get the connection for this user , if connection is successfull this means user is authorized.
    * I think if we want to check any needed roles we should also check the roles in this method instead of doing it in additionalAutheticationChecks or we can use
    * the ThreadModel here (recomended by Haroon)
    */
    protected UserDetails retrieveUser(String username,
    UsernamePasswordAuthenticationToken authentication)
    throws AuthenticationException {
    // TODO Auto-generated method stub
    // return null;
    String password = (String) authentication.getCredentials();
    if (!StringUtils.hasText(password))
    {
    throw new BadCredentialsException("Please enter password");

    }
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    Connection conn;
    try
    {

    // Speaker speaker = Speaker.findSpeakersByEmailAndPasswordEquals(usern ame, \password).getSingleResult();
    // authorities.add(new GrantedAuthorityImpl("ROLE_USER"));
    //TODO here I should be trying to get the database connection using user name and password if connection successfully made then it means user is authenticated to use our system
    // however I should be a able to store this connection in a place like ThreadModel or something and should be able to get it whenever I want in application
    //ThreadContext.set("userName", "Sajjad");
    //UserCredentialsDataSourceAdapter adapter=new UserCredentialsDataSourceAdapter();
    getUserAdapter().setCredentialsForCurrentThread(us ername, password);
    conn= getUserAdapter().getConnection();

    }
    catch (SQLException e) {
    e.printStackTrace();
    //**This means user credentials are not correct so we should throw EmptyResultDataAccessException from here
    throw new BadCredentialsException("Invalid username or password");

    }
    catch (EmptyResultDataAccessException e)
    {
    throw new BadCredentialsException("Invalid username or password");

    } catch (EntityNotFoundException e) {
    throw new BadCredentialsException("Invalid user");

    } catch (NonUniqueResultException e) {
    throw new BadCredentialsException("Non-unique user, contact administrator");

    }
    // if(conn!=null){
    // try {
    // conn.close();
    // } catch (SQLException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
    // }
    return new User(username, password,
    true, // enabled
    true, // account not expired
    true, // credentials not expired
    true, // account not locked
    authorities);
    }

    public UserCredentialsDataSourceAdapter getUserAdapter() {
    return userAdapter;
    }

    public void setUserAdapter(UserCredentialsDataSourceAdapter userAdapter) {
    this.userAdapter = userAdapter;
    }

    }

    Comment

    Working...
    X