Delegating data redaction to the data source - Data Service Integrator

Hello,
We have a customer with the following scenario: all the real users are already mapped
and kept up-to-date as database users. The redaction rules (who can see which table fields)
are already described in the database. So it does not make any sense to replicate those rules
in ALDSP. The problem is: when ALDSP access the database it does not use
the original user's credentials. It users either a fixed login/password (as configured
in wls console) or a credential mapping (wls user -> database user), which should
be configured manually for all thousands of users (and maintained as well). So,
the question is: how do I delegate data redaction to the data source?
Thanks 

Your problem is not specific to ALDSP. WLS owns the WLS-user-to-db-user credential mapping for JDBC datasources/connection pools. They would be the ones to approach about credential mapping. It seems like an over-sight (or their is a good reason) for not providing a pass-through mapping. Obtaining the password for every user seems like it would be an issue. I would check very thoroughly with the WLS datasource/connection pool people about this before going ahead with some awkward work-around (below).
ALDSP has a SourceBindingProvider hook for physical rdb-based data services. The SourceBindingProvider is called to resolve the JDBC datasource JNDI name in an ALDSP query. You can implement a SourceBindingProvider that returns a datasource corresponding to the wls-user executing the query. Don't have a datasource for every wls-user? You can create one in your SourceBindingProvider if it does not exist. Does all this sound complicated? I've attached such a DynamicSourceBindingProvider for your viewing pleasure. See the ALDSP 2.5 documentation for using a SourceBindingProvider. Using the SourceBindingProvider in 3.x is discourage since the WLS datasource service account/credential mapping is available.
package com.bea.ld.admin;
import com.bea.ld.bindings.SourceBindingProvider;
import java.sql.*;
import java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import weblogic.jndi.Environment;
import weblogic.management.configuration.JDBCConnectionPoolMBean;
import weblogic.management.runtime.JDBCConnectionPoolRuntimeMBean;
import weblogic.management.configuration.JDBCTxDataSourceMBean;
import weblogic.management.configuration.ServerMBean;
import weblogic.management.MBeanHome;
import weblogic.management.WebLogicObjectName;
public class DynamicSourceBindingProvider implements SourceBindingProvider {
     
     public String getBinding(String locator, boolean isUpdate){      
     javax.security.auth.Subject subject = weblogic.security.Security.getCurrentSubject();
     String username=weblogic.security.SubjectUtils.getUsername(subject);
     String dataSourceName=null;
     
     try {
          dataSourceName=getDataSourceByName( locator+"_"+username, username);
     }catch( SQLException sqe){
          sqe.printStackTrace();
     }
     return dataSourceName;
     }
     static String serverUrl=null; // for testing from external client
     static String serverUsername=null; // for testing from external client
     static String serverPassword=null; // for testing from external client
     
     static String serverName=System.getProperty("weblogic.Name") != null
               ? System.getProperty("weblogic.Name")
               : "you need to set the serverName in DynamicSourceBindingProvider";
     
     static String SERVER_NAME="Server";
     static String USER="user";
     
     static Context ctx=null;
     static boolean externalClient=false;
     
     static String url="jdbc:oracle:thin:#braely:1521:LDATA";
     static String driverName="oracle.jdbc.driver.OracleDriver";
     public static String getDataSourceByName( String dataSourceName, String username ) throws SQLException
     {
          Context context=getContext();
          DataSource ds=null;
          try {
               ds=(DataSource)context.lookup(dataSourceName);
          } catch (Exception e){     }
          
          if( ds!= null)
               return dataSourceName;
          
          if ( createPool( dataSourceName+"pool", username) == null)
               return null;
          if ( createDataSource( dataSourceName, dataSourceName+"pool")== null)
               return null;
          return dataSourceName;
     
     }
     
     public static String createPool ( String poolName, String username )throws SQLException {
     try {
          Context context=getContext();
          MBeanHome mbeanHome = (MBeanHome)context.lookup(MBeanHome.ADMIN_JNDI_NAME);
          JDBCConnectionPoolMBean cpMBean = (JDBCConnectionPoolMBean)mbeanHome.createAdminMBean(poolName, "JDBCConnectionPool", mbeanHome.getDomainName());
          //Set the Connection Pool Properties
          Properties pros = new Properties();
          pros.put(USER, username);
          cpMBean.setProperties(pros);
          String password=username; // hack - I have all username==password
          cpMBean.setPassword(password);
          // Set DataSource attributes
          // TODO: get URL, Drivername from annotations
          cpMBean.setURL(url);
          cpMBean.setDriverName(driverName);
          cpMBean.setInitialCapacity(0);
          cpMBean.setMaxCapacity(5);
          cpMBean.setShrinkingEnabled(true);
          cpMBean.setShrinkFrequencySeconds(30);
          ServerMBean svrAdminMBean = (ServerMBean)mbeanHome.getAdminMBean(serverName,SERVER_NAME);
          cpMBean.addTarget(svrAdminMBean);
     
     } catch (Exception ex){
          throw new SQLException(ex.toString());
     }
     return poolName;
}
     
     // Create a DataSource
     public static String createDataSource(String dsName, String poolName) throws SQLException
     { 
          try {   
               ctx=getContext();
               MBeanHome mbeanHome = (MBeanHome)ctx.lookup(MBeanHome.ADMIN_JNDI_NAME);
               JDBCTxDataSourceMBean dsMBean = (JDBCTxDataSourceMBean)mbeanHome.createAdminMBean(dsName, "JDBCTxDataSource", mbeanHome.getDomainName());
          dsMBean.setJNDIName(dsName);
               dsMBean.setPoolName(poolName);
               ServerMBean svrAdminMBean = (ServerMBean)mbeanHome.getAdminMBean(serverName, SERVER_NAME);
               dsMBean.addTarget(svrAdminMBean);
          } catch (Exception ex) {
               ex.printStackTrace();
               throw new SQLException(ex.toString());
          }
          return dsName;
     }
     
     
     public static Context getContext(){
          if(ctx==null){
               try {
               if ( !externalClient ) {
                    ctx = new InitialContext();
                    return ctx;
               }
               Environment env = new Environment();
               env.setProviderUrl(serverUrl);
               env.setSecurityPrincipal(serverUsername);
               env.setSecurityCredentials(serverPassword);
               env.setInitialContextFactory("weblogic.jndi.WLInitialContextFactory");
               ctx = env.getInitialContext();
               } catch (javax.naming.NamingException ne){
                    ne.printStackTrace();
               }
          }
          return ctx;
     }
     
     //Removing a Dynamic Connection Pool and DataSource
     //The following code sample shows how to remove a dynamically created connection pool.
     //If you do not remove dynamically created connection pools, they will remain
     // available even after the server is stopped and restarted.
     public static void deleteConnectionPool(String poolName) throws SQLException
     { 
          try {  
               Context context=getContext();
               MBeanHome mbeanHome = (MBeanHome)context.lookup(MBeanHome.ADMIN_JNDI_NAME);
               System.err.println("removing ConnectionPool "+poolName);
               JDBCConnectionPoolMBean cpMBean = (JDBCConnectionPoolMBean)mbeanHome.findOrCreateAdminMBean(poolName, "JDBCConnectionPool", mbeanHome.getDomainName());
               // Remove dynamically created connection pool from the server
               ServerMBean svrAdminMBean = (ServerMBean)mbeanHome.getAdminMBean(serverName,SERVER_NAME);
               cpMBean.removeTarget(svrAdminMBean);
               // Remove dynamically created connection pool from the configuration
               mbeanHome.deleteMBean(cpMBean);
               } catch (Exception ex) {
                    throw new SQLException(ex.toString());
               }
     }
     public static void deleteDataSource(String dsName) throws SQLException
     {   
          try {           
               ctx=getContext();
               MBeanHome mbeanHome = (MBeanHome)ctx.lookup(MBeanHome.ADMIN_JNDI_NAME);
               System.err.println("removing DataSource "+dsName);
               JDBCTxDataSourceMBean dsMBean = (JDBCTxDataSourceMBean)mbeanHome.findOrCreateAdminMBean(dsName, "JDBCTxDataSource", mbeanHome.getDomainName());
               ServerMBean svrAdminMBean = (ServerMBean)mbeanHome.getAdminMBean(serverName, SERVER_NAME);
               // Remove dynamically created TxDataSource from the server
               dsMBean.removeTarget(svrAdminMBean);
               // Remove dynamically created TxDataSource from the configuration
               mbeanHome.deleteMBean(dsMBean);
               } catch (Exception ex) {
                    throw new SQLException(ex.toString());
               }
     }
     
     public static void main(String[] args){
          
          int pools=0;
          boolean delete=false;
          if(args.length < 2){
               System.err.println("java com.bea.ld.admin.DynamicSourceBindingProvider <prefix> <username> <server_url> <server_user> <server_password> <server_name> <driverName> <dbUrl>");
               System.err.println("java com.bea.ld.admin.DynamicSourceBindingProvider test broadband t3://localhost:7001 weblogic weblogic cgServer oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:#braely:1521:LDATA");
               return;
          }
          externalClient=true;
          if(args.length > 2) serverUrl=args[2];
          if(args.length > 3) serverUsername=args[3];
          if(args.length > 4) serverPassword=args[4];
          if(args.length > 5) serverName=args[5];
          if(args.length > 6) driverName=args[6];
          if(args.length > 7) url=args[7];
          if(args.length > 8) pools=Integer.parseInt(args[8]);
          if(args.length > 9) delete=args[9].equals("delete");
          
          String dataSourceName=args[0]+"_"+args[1];
          try {
               if(pools==0){
                    getDataSourceByName( dataSourceName, args[1]);
               } else {
                    for(int i=0; i<pools; i++){
                         if(delete){
                              try { deleteDataSource( dataSourceName+i);} catch (Exception e){ e.printStackTrace();}
                              try { deleteConnectionPool( dataSourceName+i+"pool");} catch (Exception e){ e.printStackTrace();}
                         } else {
                              getDataSourceByName( dataSourceName+i, args[1]);
                         }
                    }
               }
          } catch (Exception e){
               e.printStackTrace();
               return;
          }
          
          if(delete)
               return;
          
          Context context=getContext();
          DataSource ds=null;
          try {
               ds=(DataSource)context.lookup(pools== 0 ? dataSourceName : dataSourceName+"0");
          } catch (Exception e){
               e.printStackTrace();
               return;
          }
          
          Connection con=null;
          PreparedStatement ps=null;
          ResultSet rs=null;
          
          try {
          con=ds.getConnection();
          ps=con.prepareStatement("select SYSDATE from dual");
          rs=ps.executeQuery();
          while (rs.next()){
               System.out.println( rs.getString(1));
          }
          rs.close();
          ps.close();
          con.close();
          } catch(Exception e){
               e.printStackTrace();
          }
          finally {
               try { if(rs!=null) rs.close(); } catch (Exception e){}
               try { if(ps!=null) ps.close(); } catch (Exception e){}
               try { if(con!=null) con.close(); } catch (Exception e){}
          }
          
          
          return;
     }
     
}

Related

JSP/Class that calls MySQL

Hello folks,
I have a JSP file that I want to connect to mySQL using a class that I wrote.
try
{
   JDBCConnector mysql = new JDBCConnector();
                    
   mysql.connect();
   mysql.getStatement();
   mysql.querySQL("SELECT * FROM temp");
                                        
   ResultSet rs = mysql.getResults();
                    
   while(rs.next())
   {
      out.print(rs.getString("firstname")+" ");
      out.println(rs.getString("lastname")+"<br>");
   }
                                        
   mysql.disconnect();
               
}
               
catch(Exception e)
{
   out.println(e);
}Here is the class that I wrote:
package jdbc;
import java.sql.*;
public class JDBCConnector
{
     private final String username = "**********";
     private final String password = "**********";
          
     private Connection conn = null;
     private Statement statement = null;
     
     private String query = null;
     
     public JDBCConnector()
     {          
          try
          {
               Class.forName("com.mysql.jdbc.Driver").newInstance();      
          }
               
          catch (Exception e)
          {
               System.err.println("Unable to load driver.");
               e.printStackTrace();
          }          
          
     }
     
     public void connect(String db)
     {          
          try
          {
               String con = "jdbc:mysql://localhost/"+db+"?user="+username+
                    "&password="+password;
                    
               conn = DriverManager.getConnection(con);
               
          }
          
          catch(Exception e)
          {          
               System.out.println(e);
          }
     }
     
     public void getStatement()
     {
          try
          {
               statement = conn.createStatement();
          }
          
          catch(Exception e)
          {
          }
     }
     
     public void querySQL(String query)
     {
          try
          {
               this.query = query;
          }
          
          catch(Exception e)
          {
          }
     }
     
     public ResultSet getResults()
     {
          try
          {
               return statement.executeQuery(query);
          }
          
          catch(Exception e)
          {
               return null;
          }
     }
     
     
     public void disconnect()
     {
          try
          {               
               conn.close();
          }
          
          catch(Exception e)
          {
               System.out.println(e);
          }
     }
}Is there a reason why this wouldn't work? I get an javax.servlet.ServletException: jdbc.JDBCConnector.connect()V exception. :(
Any info would be appreciated. Thanks. 
I think you forget the port-nr in your connection URL.
The default port number for MySQL server is 3306.
String con = "jdbc:mysql://localhost:3360/"+db+"?user="+username+                    "&password="+password;
I think you forget the port-nr in your connection
URL.
The default port number for MySQL server is 3306.
String con =
"jdbc:mysql://localhost:3360/"+db+"?user="+username+               
"&password="+password;
I think if you don't put the port number, 3306 is assumed. But I tried anyway, and it's still the same problem.
correction of port-nr in the url:
String con = "jdbc:mysql://localhost:3306/"+db+"?user="+username+ "&password="+password;
By the way, it should be a semicolon ";" between user and password not a "&"
.......?user="+username+ "; password="+password" ";
correction of port-nr in the url:
String con =
"jdbc:mysql://localhost:3306/"+db+"?user="+username+
"&password="+password;
By the way, it should be a semicolon ";" between user
and password not a "&"
.......?user="+username+ "; password="+password" ";... try {
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
         
            // Do something with the Connection That's the example used in the MySQL Connector/J Documentation
http://www.mysql.com/documentation/connector-j/index.html#id2802972
Regardless, the same error is still generated. 
I think if you don't put the port number, 3306 is
assumed. But I tried anyway, and it's still the same
problem.You are right. If the port is not specified, it defaults to 3306.
Are you using Tomcat?
If yes, you should put a copy of the MySQL JDBC driver (connector jar file) in the:
TOMCAT__HOME/ common\lib directory. 
Are you using Tomcat?
If yes, you should put a copy of the MySQL JDBC driver
(connector jar file) in the:
TOMCAT__HOME/ common\lib directory.All that is already done.
If I straight up put:
Connection con = DriverManager.getConnection("yadda...");
Statement stmt = con.createStatement();
ResultSet rs = yadda...
// query codeit works fine
it just bugs like crazy when i try to use the class like that 
any other ideas? anyone? 
How about this:
// you call
  mysql.connect();
// But the method is:
public void connect(String db)It should be giving you a better error message than it is, but I think that is the root cause.
Also I suggest that you go and read this article on how to handle exceptions
http://www.javaworld.com/javaworld/jw-08-2001/jw-0803-exceptions.html?
As it is now, you are hiding half of your exceptions.
It would be better just to throw them/chain them so that you can sensible debug your code.
At least put in a e.printStackTrace() so you can see where the exception is occuring!
Good luck,
evnafets

Database Connection design question

Hello, I have a design question. Awhile back I needed to create a database connection to SQL Server, so I created a class to do it
import java.sql.*;
import java.io.*;
import java.net.MalformedURLException;
import org.w3c.dom.Document;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class SQLServerConnection
{
     private static Connection connection = null;
     
     public SQLServerConnection(String user, String password, String dbName) throws java.sql.SQLException
     {
          getDBConnection(user, password, dbName);
     }
     
     public SQLServerConnection(String configFileName) throws java.sql.SQLException
     {
          getDBConnection(configFileName);
     }
     
     private void getDBConnection(String user, String password, String dbName) throws java.sql.SQLException
     {
         DriverManager.registerDriver(new com.microsoft.jdbc.sqlserver.SQLServerDriver());
         connection = DriverManager.getConnection(
              "jdbc:microsoft:sqlserver:" + dbName, user, password);              
     }
     
     private void getDBConnection(String configFileName) throws java.sql.SQLException
     {
          String user;
          String password;
          String dbName;
          try
          {
               DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
               DocumentBuilder db = factory.newDocumentBuilder();
               Document doc = db.parse(configFileName);
               
               doc.getDocumentElement().normalize();
               
               // get the configuration information
               password = getConfigParameter("password", doc);
               user = getConfigParameter("username", doc);
               dbName = getConfigParameter("databasename", doc);
               
               getDBConnection(user, password, dbName);
          }
          catch (MalformedURLException murle)
          {
               System.out.println("Unable to connect to: " + configFileName + " -- " + murle);
               System.exit(1);
          }
          catch (FileNotFoundException fnfe)
          {
               System.out.println("Configuration file " + configFileName + " not found.");
               System.exit(1);
          }
          catch (IOException ioe)
          {
               System.out.println("IOException: " + ioe);
               System.exit(1);
          }
          catch (javax.xml.parsers.ParserConfigurationException pce)
          {
               System.out.println ("Parser Configuration Error: " + pce);
          }
          catch (SAXException saxe)
          {
               System.out.println ("SAXException: " + saxe);
          }          
     }
     
     private String getConfigParameter(String paramName, org.w3c.dom.Document doc)
     {
          NodeList nl = doc.getElementsByTagName(paramName);
          if(nl != null)
          {
               Node n = null;
               for (int i = 0; i < nl.getLength(); i++)
               {
                    n = nl.item(i);          
                    if(n.hasChildNodes())
                    {
                         NodeList children = n.getChildNodes();
                         return ((Node)children.item(0)).getNodeValue();
                    }
               
               }
          }
          else
          {
               System.out.println ("nl is null");
          }
          
          return "";          
     }     
     
     public void setCatalog(String catalogName) throws java.sql.SQLException
     {
          connection.setCatalog(catalogName);
     }
     public Connection getConnection()
     {
          return connection;
     }
     
     public void closeConnection()
     {
          try
          {
               connection.close();
          }
          catch(java.sql.SQLException sqle)
          {
               System.err.println ("SQL Server Connection failed to close: " + sqle);
          }          
     }
}Later on, I needed to do the same thing for MySQL, so I created a class for that, MySQLServerConnection which is exactly the same as above, except for:
private void getDBConnection(String user, String password, String dbName) throws java.sql.SQLException
     {
          try
          {
               Class.forName("com.mysql.jdbc.Driver").newInstance();
               connection = DriverManager.getConnection(dbName, user, password);     
          }
          catch(java.lang.ClassNotFoundException cnfe)
          {
               System.out.println (cnfe);
          }
          catch(java.lang.InstantiationException ie)
          {
               System.out.println (ie);
          }
          catch(java.lang.IllegalAccessException iae)
          {
               System.out.println (iae);
          }
     }Later, on, I did the same thing with OracleServerConnection. My question is, I know this is probably not optimal code. For example, I didn't originally have a close connection method, so I had to go in and code one for all 3. I'm assuming that an interface would be a good idea so that if I have to code another database connection class I make sure and include all of the appropriate methods. I'm also assuming that it would have been smart to have a master class, maybe something like DatabaseConnection and extended these classes from that. Am I on the right track? Totally offbase? 
Well you're wrapping the original Connection object but not providing much new functionality. How about a Factory that constructs the appropriate type of Connection object and returns it?
Connection dbConnection = ConnectionFactory.getConnection("Oracle");Or if it can be inferred from the context...
Connection dbConnection = ConnectionFactory.getConnection(); 
You could try coding something like this in one class:
Connection con = null;
/* ... */
try { // try for DB 1
  con = DriverManager.getConnection( /* ... */ );
} catch(SQLException sqle) {
  try { // try for DB 2
    con = DriverManager.getConnection( /* ... */ );
  } catch(SQLException sqle) {
    try { // try for DB 3
      con = DriverManager.getConnection( /* ... */ );
    } catch(SQLException sqle) {
      /* failed all three - now actually log the exception somehow */
    }
  }
} 
#nclow - I will work on trying the Factory Pattern for this over the weekend and post when I finish to see what you think.
#abillconsl - just to make sure I understand, you're saying that I just try to connect and it will cycle through the different database connection possibilities and connect when it finds the right one? If it fails all 3, log an appropriate message. One question I have about this is, I thought I was being object oriented by separating the different types of db connections (Oracle, SQL Server, MySql) into different classes. Am I missing the point of OOP by what I was/am trying to accomplish? Going overboard? Also, does your way try and connect to all 3 even if I connected to one already?
Thx, Grantarchy
Edited by: grantarchy on May 9, 2008 9:50 PM

example solution creating dbcp.BasicDataSource or sql.DataSource for JNDI

For all that want to write tests that must access a sql database via jndi datasource as configured e.g with tomcat can use the following code as
startingpoint:
public class ExampleTest extends TestCase {
     /**
     * set the Connection Parameters for use with this test
     */
     private String dbUrl = "jdbc:mysql://the server/databasename?autoReconnect=true";
     private String driverClassName = "com.mysql.jdbc.Driver";
     private String username = "username";
     private String password = "secret";
     
     
     /**
     * init the Database Connection using the {#link com.sun.jndi.fscontext.RefFSContextFactory}
     *
     */
     protected void setUp() throws Exception {
          super.setUp();
          
               System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
          "com.sun.jndi.fscontext.RefFSContextFactory");
// the following works for me
               String purl = "";
          if (System.getProperty("os.name").contains("Windows"))               
          purl = "file://c:/temp"; // windows tempdir
          else
               purl = "file://"+System.getProperty("user.home"); // e.g linux
          
          System.setProperty(Context.PROVIDER_URL, purl);
          
          Context initContext = new InitialContext();
          
          Reference ref = new Reference("javax.sql.DataSource",
          "org.apache.commons.dbcp.BasicDataSourceFactory", null);
          ref.add(new StringRefAddr("driverClassName", driverClassName));
          ref.add(new StringRefAddr("url", dbUrl));
          ref.add(new StringRefAddr("username", username));
          ref.add(new StringRefAddr("password", password));
               
               try
               {
                    initContext.rebind("java:comp/env/jdbc/db",ref);
                    
               }
               catch (Exception e)
               {
                    e.printStackTrace(); // you can now see what went wrong
               }
     }
// test methods follow now
}
###################################################
When working under linux you must create the directory structure for jndi underneath your user.home directory manually . (/java:comp/env/jdbc/db See stack trace message if you forgot). 
Hi i am using oracle database to connect through WebLogic8.1 by JNDI lookup i have written this code.
But i am not getting ultimate connection ,sometimes i am getting Naming exception,otherwise connection not established.
can somebody give some idea.here is the code:--
     /**
     * Open the connection.
     */
     public synchronized void open (String dataSourceName,
     String Url,
     Properties props,
     EventLog log)
     throws Exception {
System.out.println("datasourcename="+dataSourceName );
     
try {
// Hashtable env = new Hashtable(5);
// Properties env = new Properties( );
//env.put(Context.SECURITY_PRINCIPAL, "guest");
//env.put(Context.SECURITY_CREDENTIALS, "guest");
//env.put(Context.INITIAL_CONTEXT_FACTORY,
//"weblogic.jndi.WLInitialContextFactory");
//env.put(Context.PROVIDER_URL, "t3://localhost:7001");
InitialContext jndi = new InitialContext();
     DataSource ds
     = (DataSource) jndi.lookup (dataSourceName);
     
     Connection _connection= ds.getConnection();
     
System.out.println("Inside open "+ dataSourceName);
     }
     catch (NamingException e){
          
                         e.printStackTrace(); // lookup failed
     System.out.println("Inside open NamingException "+ e.getMessage());
          }
          
          catch (SQLException e) {
                         e.printStackTrace();
                    System.out.println("Inside open SQLException "+e.getMessage());
               }
               catch(Exception e){
                         e.printStackTrace();
                    System.out.println("Inside open Exception "+e.getMessage());
               }
               
               finally{
                    System.out.println("Inside finally block of open "+ dataSourceName);
               }
     
     
          if (_connection == null)
          throw new ZcException
          (ErrorCode.INTERNAL_ERROR, getClass().getName() +
          ".open: Failed to connect to database:\n");
     }
Please try if somebody can solve it.
thanks
vj

LDAP user authentication howto?

Hi,
I have no experience with LDAP, but I need to replace our standard
user authentication with LDAP user authentication for one of our
customers.
The user's credentials (user id, password) are sent to a servlet and
passed to an EJB where the check happens against the user information
in our ORACLE database.
This check must now happen against a Directory Service using LDAP.
Can anybody here give me an example on how to do user authentication
using LDAP (which classes do I need to import? Are they part of standard
JDK? Do I have to buy them somewhere?)...
Any help is welcome, I've been trying to read the manual here online,
but I can't find the quick answer I am looking for.
It's just the user authentication I need, I don't need to access the
Directory Service for anything else.
Thanks in advance,
Sven 
I don't know if you have solved this problem as yet. I have some code to authenticate username and password using LDAP and JNDI. However I this code complies and runs. I m using tomact as servlet container and apache as the web server. I know I need to some sort of configuration or mapping, but don't know how to. if you sloved the problem, could u tell me.
Here's some sample code:
//Used to authenticate user from LDAP directry.
import javax.naming.*;
import javax.naming.directory.*;
import java.util.*;
import java.lang.*;
public class AuthBean {
     private boolean attempted;
     private String userName;
     private String password;
     public AuthBean() {
          attempted = false;
          userName = "";
          password = "";
     }
     
     //Getter methods.
     public String getUserName() {
          return this.userName;
     }
     public String getPassword() {
          return this.password;
     }
     //Setter methods.
     public void setUserName (String userName) {
          this.userName = userName;
          if (!this.userName.equals("") && !this.password.equals(""))
          attempted = true;
     else
               attempted = false;
     }
     public void setPassword(String password) {
          this.password = password;
          if (!this.userName.equals("") && !this.password.equals(""))
               attempted = true;
          else
               attempted = false;
     }
     //Checks to see if attempted.
     public boolean isAttempted() {
          return this.attempted;
     }
     /**
     * Given a username and password, authenticates to the directory
     * Takes a String for username, String for password.
     * Calls getDn for the method.
     */
     public boolean ldapAuthenticate (String username, String pass) {
          if ( username == null || pass == null ) {
               System.out.println(" im here in the method");
               System.out.println(" user" + username);
               System.out.println(" pass" + pass);
               return false;
               
          }
          String dn = getDN(username);
               System.out.println(" dn" + dn);
               if ( dn == null)
               return false;
               dn = dn + ",o=hcfhe";
               //dn = dn + ",o=mu";
               System.out.println(dn);
               String ldap_url = "ldap://10.1.1.199:389/ou=it,o=hcfhe";
               //set variables for context
               Hashtable env = new Hashtable();
               env.put("com.sun.naming.ldap.trace.ber", System.err);
               env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
               env.put(Context.PROVIDER_URL, ldap_url);
               env.put(Context.SECURITY_AUTHENTICATION, "simple");
               env.put(Context.SECURITY_PRINCIPAL, dn);
               env.put(Context.SECURITY_CREDENTIALS, pass);
               DirContext ctx;
               //make connection, catch errors thrown
               try {
                    ctx = new InitialDirContext(env);
               } catch (AuthenticationException e) {
                         System.out.println("Authentication Exception");
                         return false;
               } catch (NamingException e) {
                    e.printStackTrace();
                    return false;
               }
          //close connection
          try {
               ctx.close();
          } catch (NamingException ne) {
                    System.out.println(ne);
}
          return true;
}
     /**
     * This methods cheks for the username from the LDAP directory.
     * Takes a String.
     */
     public String getDN(String username) {
          String dn = "";
          String ldap_url = "ldap://10.1.1.199:389/ou=it,o=hcfhe";
          Hashtable env = new Hashtable();
          env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
          env.put(Context.PROVIDER_URL, ldap_url);
          DirContext ctx;
          try {
               ctx = new InitialDirContext(env);
               SearchControls ctls = new SearchControls();
               ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
               String filter = "(uid=" + username + ")"; // Search for objects with these matching attributes
               NamingEnumeration results = ctx.search("",filter,ctls);
               if ( results != null && results.hasMoreElements()) {
                    SearchResult sr = (SearchResult)results.nextElement();
                    dn = sr.getName();
               } else dn = null;
                         ctx.close();
          } catch (AuthenticationException e) {
                    System.out.println("Authentication Exception");
                    return null;
          } catch (NamingException e) {
                    e.printStackTrace();
                    return null;
          }
               return dn;
          }
}
The above is a bean used in a jsp page, username and password are from the request parameters.
I hope it helps.

Problem with Monitoring JDBC Datasource through JMX NotificationListener

Hi there,
We want to monitor and log JDBC Datasource statistics, after doing a bit search, we find some codes on download.oracle.com.
the codes use jmx NotificationListener to monitor jmx object attrbute changes.
So We make some changes to monitor JDBCDataSourceRuntimeMBean,
it works without any exceptions, but can not tracking any changes of JDBCDataSourceRuntimeMBean, i don't know what the problem is.
     public ObjectName[] getDataSourceRuntimes() throws Exception {
ObjectName runtimeService = new ObjectName(
                         "com.bea:Name=RuntimeService,Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean");
          ObjectName domainRT = (ObjectName) connection
                    .getAttribute(runtimeService, "ServerRuntime");
          domainRT = (ObjectName) connection.getAttribute(domainRT, "JDBCServiceRuntime");
          return (ObjectName[]) connection.getAttribute(
                    domainRT,
                    "JDBCDataSourceRuntimeMBeans");
     }
     public void exec() {
          String hostname = "10.135.1.100";
          String portString = "7777";
          String username = "weblogic";
          String password = "welcome1";
          try {
               // Instantiating your listener class.
               MyListener listener = new MyListener();
               AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
               filter.enableAttribute("ActiveConnectionsCurrentCount");
               filter.enableAttribute("CurrCapacity");
               filter.enableAttribute("State");
               initConnection(hostname, portString, username, password);
               // Passing the name of the MBeans and your listener class to the
               // addNotificationListener method of MBeanServer.
               ObjectName[] runtimes = getDataSourceRuntimes();
               int length = (int) runtimes.length;
               for (int i = 0; i < length; i++) {
                    connection.addNotificationListener(runtimes, listener, null, null);
                    System.out.println("\n[myListener]: Listener registered with:"
                              + runtimes[i]);
               }
               // Keeping the remote client active.
               System.out.println("pausing...........");
               System.in.read();
          } catch (Exception e) {
               System.out.println("Exception: " + e);
          } finally {
               if (connector != null) {
                    try {
                         connector.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
               }
          }
     }
Any help would be appreciated.
Thanks and Regards
-Ray

Categories

Resources