Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

November 19, 2016

LDAP User Authentication

What is LDAP and LDAP Authentication ?

To get started on what and how LDAP works, take a look at [1].

Quoting from the above article, following is about how LDAP Authentication works :
To perform any of these LDAP operations, an LDAP client needs to establish a connection with an LDAP server. The LDAP protocol specifies the use of TCP/IP port number 389, although servers may run on other ports.
The LDAP protocol also defines a simple method for authentication. LDAP servers can be set up to restrict permissions to the directory. Before an LDAP client can perform an operation on an LDAP server, the client must authenticate itself to the server by supplying a distinguished name and password. If the user identified by the distinguished name does not have permission to perform the operation, the server does not execute the operation.
In order write a simple LDAP Authenticator using Java, refer to the article [2] first to get an idea.

As per the above quote and explanations, in order to perform an LDAP based user authentication, we validate the user's permission by trying to execute an operation on LDAP.

Java LDAP Authenticator

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;
/**
 * Open a connection to the LDAP server with uid and password and authenticate the user.
 */
public class LDAPAuthenticator {
    private static String UID_FORMAT_STRING = "uid=%1s,%2s";
    private static String VDS_SERVER = "LDAPS://localhost:389";
    private static final String PEOPLE_OU = "ou=people,dc=local,dc=com";
    public static void main(String[] args) {
        Hashtable<String, String> authEnv = new Hashtable<String, String>();
        authEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        authEnv.put(Context.PROVIDER_URL, VDS_SERVER);
        authEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); //default authentication
        authEnv.put(Context.SECURITY_PRINCIPAL, String.format(UID_FORMAT_STRING, "uidName", PEOPLE_OU));
        authEnv.put(Context.SECURITY_CREDENTIALS, "password");
        try {
            DirContext ctx = new InitialDirContext(authEnv);
            ctx.close();
            System.out.println("User Authentication Successful");
        } catch (Exception e) {
            System.out.println("User Authentication Failed");
            e.printStackTrace();
        }
    }
}

In addition if you need perform attribute matching along with authentication use the following code as an example :

Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
matchAttrs.put(new BasicAttribute("uid", "AARSupport"));

// Search for objects with those matching attributes
NamingEnumeration answer = ctx.search(PEOPLE_OU, matchAttrs);

WSO2 LDAP Connector

If you are using WSO2 ESB, you can use the WSO2 LDAP connector to perform LDAP authentication. You can download the connector from [6]. Documentation on using the LDAP connector for authentication can be found at [7].

Use the following configurations to call the Authenticate operation.

Create a local entry with authentication details as below.

<ldap.init xmlns="http://ws.apache.org/ns/synapse">
      <providerurl>LDAPS://localhost:389</providerurl>
      <securityprincipal>uid=UIDName,ou=people,dc=local,dc=com</securityprincipal>
      <securitycredentials>password</securitycredentials>
      <secureconnection>false</secureconnection>
      <disablesslcertificatechecking>false</disablesslcertificatechecking>
</ldap.init>


Or you can also create local entry as below without authentication details since they are again later provided at the authenticate operation.

<ldap.init xmlns="http://ws.apache.org/ns/synapse">
      <providerurl>LDAPS://localhost:389</providerurl>
      <securityprincipal></securityprincipal>
      <securitycredentials></securitycredentials>
      <secureconnection>false</secureconnection>
      <disablesslcertificatechecking>false</disablesslcertificatechecking>
</ldap.init>

In the mediation, you can call the LDAP connector's authenticate operation to perform authentication.

<ldap.authenticate configkey="LDAPConfig">
        <dn>uid=UIDName,ou=people,dc=local,dc=com</dn>
        <password>password</password>
</ldap.authenticate>


If the authentication is successful, you would be getting a Success response back.

References : 

  1. https://docs.oracle.com/cd/E19957-01/816-6402-10/ldap.htm
  2. http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html
  3. https://tools.ietf.org/html/rfc4519#section-2.39
  4. http://stackoverflow.com/questions/2522770/how-to-check-user-password-in-ldap-whith-java-with-given-ldapcontext
  5. http://stackoverflow.com/questions/7813868/whats-the-difference-in-using-distinguished-name-with-cn-or-uid-when-logging-in
  6. https://store.wso2.com/store/assets/esbconnector/details/4ecf8dde-60f3-4e91-ba22-5f49a4e302f4
  7. https://docs.wso2.com/display/ESBCONNECTORS/Working+with+User+Authentication+in+LDAP

November 10, 2014

Building WSO2 ESB 4.8.1 from source in OSX

WSO2 products are all built on top of WSO2 Carbon Kernel. This is the common ground for all products. Turing is the platform release name for WSO2 Carbon 4.2.0 and WSO2 ESB 4.8.1 is based on turing. Not all products of the WSO2 platform does not get released at the same time. Therefore, these products are released in chunks. ESB 4.8.1 comes under chunk 7 of the turing platform. Refer the release matrix to get more info on this [2].
Prerequisites : 
1. Install Java 1.6 and Maven 3
       If you have only 1.7 installed, you will have to install 1.6 on OSX. Unfortunately, there is no direct installation for 1.6. But this sorted out for me  since jdk 1.6 was automatically installed when I installed IntellijIdea
       At the moment, all WSO2 products are compiled on Java 1.6 and is supported up to 1.7. This is why we need to build the source on 1.6.
2. Checkout Source (Orbit, Kernel, Platform)

Building the Source : 


Start building in order Orbit > Kernel > Platform (chunk 07) repos respectively.


To build ESB 4.8.1, you need to build wso2carbon-platform/product-releases/chunk-07 as Platform in above.


The distribution will be created in :

wso2carbon-platform/products/esb/4.8.1/modules/distribution/target/(esb.zip)

When building, since it will take a lot of time, and to avoid unit test failures from building the product, skip unit tests when building.


mvn clean install -Dmaven.test.skip=true


Build ESB only :

If you need to build only ESB, build at wso2carbon-platform/products/esb with mvn clean install -Dmaven.test.skip=true


Another option is to comment out other product modules in platform/trunk/pom.xml and rebuilding in Orbit > Kernel > Platform in order.


Encountered Errors : 
  1. WSS4 maven install fails > You need to compile in Java 1.6
  2. [WARNING] Error injecting: org.apache.maven.reporting.exec.DefaultMavenReportExecutor > Set maven-site plugin version to 3.3 in all places [4]
Environment : 

August 16, 2012

Access outer class members from inner class

The following example shows how to access outer class members from inner class
public class OuterClass{

   public void method() {
      //do something
   }

   class InnerClass {

      public void innerMethod() {
          OuterClass.this.method();
         //do something
      }
   }
}

August 8, 2012

Right align tabs in JTabbedPane

Some useful tips for aligning tabs in JTabbedPane :-

Align tabs to right
pnlMainTabbedPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
Place tabs on right of the JTabbedPane

pnlMainTabbedPane.setTabPlacement(JTabbedPane.RIGHT)

August 7, 2012

Java Swing UI Settings

To set global UI settings in Java Swing, use UIManager and set the properties as needed. All components have their respective keys and default values. For a complete list of properties, refer http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/_nimbusDefaults.html

These settings should be done before creating the JFrame where all these components are put into.

Example :
UIManager.put("Button.background", Color.RED);
UIManager.put("Button.font", new FontUIResource(new Font("Arial", Font.BOLD, 12)));

June 29, 2012

Java Varargs - Unlimited parameters to a Java method

When you cannot decide the number of parameters you need for a method, varargs becomes the solution. Earlier, if we couldn't determine such, we had to use a collection as a parameter to help with this scenario. But varargs simplifies this.

Varargs does use an array underneath, but using varargs syntax hides the process.

public static String format(String pattern,
                                Object... arguments);

Example :

If you need to write a file name extension filter for a number of extensions, you can use this method of defining the method.

public FileNameExtensionFilter(String description, String... extensions) {

Read more on varargs at :
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html

JFileChooser - Useful Tips

Set Starting Directory
JFileChooser fileSaver = new JFileChooser();
String cpath = "C:/MWork/Test1/script/";
File f1 = new File(cpath);
fileSaver.setCurrentDirectory(f1);

File Filter
FileNameExtensionFilter filter = new FileNameExtensionFilter("eXtensible Markup Language file (*.xml) ", "xml");
fileSaver .setFileFilter(filter);

Default File Save Name
jFileChooser.setSelectedFile(new File("untitled.xml"));

June 22, 2012

Get Frame of a Component


In order to find the frame that contains a component, it is necessary to walk up the component's parents until the frame is encountered. SwingUtilities.getRoot() is a convenience method that finds the frame.

This example implements an action that finds and hides the frame of the component that triggered the action. See also Creating a JButton Component.

// Create an action
Action action = new AbstractAction("Action Label") {
  
    // This method is called when the action is triggered
    public void actionPerformed(ActionEvent evt) {
        
        Component c = (Component)evt.getSource();

        // Get the frame
        Component frame = SwingUtilities.getRoot(c);

        // Hide the frame
        frame.setVisible(false);
    }
};

http://www.exampledepot.com/egs/javax.swing/frame_FrameFind.html

June 19, 2012

Focus to newly added JComponent in Frame

int h = (int) pnlPrerequisites.getBounds().getHeight();
Component frame = SwingUtilities.getRoot(pnlPrerequisites);
System.out.println(h + "=" + frame.getHeight());
if (h > frame.getHeight()) {
    scrollPnlPre.setViewportView(p);
    // scrollPnlPre.getViewport().setView(p);
}

Problem : this removes the scroll

June 18, 2012

Get the string that matches the regex

If you want to get the string that matches the regex pattern you have defined, you might have noticed there isn't any direct method. As a solution a simple code as below can be used.

I wanted to read the number within the brackets in str.
(Note: The numbers always appear within brackets)
String str = "CLor (23)";
String search = "\\(\\d*\\)";
Pattern pattern = Pattern.compile(search);
Matcher matcher = pattern.matcher(str);
boolean matchFound = matcher.find();
if (matchFound) {
   int start = matcher.start();
   int end = matcher.end();
   String num = str.substring(start + 1, end - 1);
   System.out.println(num);
}

Above, in substring method I used
(start + 1, end -1)
because I needed to omit the brackets. If the whole string that matches the regex was needed method needs to have parameters
(start,end)

May 25, 2012

JTextBox Select all on Click

Following code will select all the content from the text box at click on it, if the textbox content is "<comment>".

Use focus listener - JTextArea does not have ActionListener like JTextField

public static JScrollPane getCommentBox() {

    final JTextArea txtComment = new JTextArea();
    txtComment.setText("<comments>");
    txtComment.setForeground(Color.GRAY);
    txtComment.setColumns(50);
    txtComment.setRows(3);

    FocusListener fl = new FocusListener() {
    
       @Override
       public void focusLost(FocusEvent arg0) {
          System.out.println("not typing....");
       }

       @Override
       public void focusGained(FocusEvent arg0) {
          if (txtComment.getText().equals(Constants.COMMENTS)) {
              txtComment.selectAll();
              txtComment.setForeground(Color.BLACK);
          }
       }
    };

    txtComment.addFocusListener(fl);
    JScrollPane jScrollPane1 = new JScrollPane();
    jScrollPane1.setViewportView(txtComment);

    return jScrollPane1;
}

Fixed size text area with scroll

JTextArea txtArea = new JTextArea();
txtArea.setColumns(50);
txtArea.setRows(2);
JScrollPane jScrollPane1 = new JScrollPane();
jScrollPane1.setViewportView(txtArea);

May 15, 2012

ArrayList and Array Conversions

ArrayList to Array Conversion :
List<T> list = new ArrayList<T>();
T[] array = list.toArray(new T[list.size()]);

Array to ArrayList Conversion : 
String[] array = {"a", "b", "c"};
List list = Arrays.asList(array);

Here the list is immutable. So if you want to be able to modify this list, create the list as below :
List list = new ArrayList(Arrays.asList(array));

November 27, 2011

Fixing ConcurrentModificationException

Here I am discussing the instances where, iterating over a collection throws the ConcurrentModificationException. As mentioned in the API documentation, the reason here is, "it is not generally permissible for one thread to modify a Collection while another thread is iterating over it."

Following is a code segment which can throw this exception.
Iterator itr = purchased_products.iterator();
while (itr.hasNext()) {
  if (itr.next().getProduct_id() == product_id) {
    Purchase p = itr.next();
    purchased_products.remove(p);
  }
}

There are a number of different solutions provided in forums. Almost all of them are provided as tweaks to iteration which is already happening.If you need to keep using the iterator, solution here will not work.

This solution gives up the iterator. This is a simple code which we all have being through, but may have missed out for situation as this. I found this by referring the remove method in java.util.ArrayList.

for (int index = 0; index < size; index++)
  if (elementData[index] == null) {
  fastRemove(index);

As in the above code segment from remove(Object o) method, I too used a for loop to find the index of the item to be removed and then called upon the remove(int index) method to remove the element. This will not result in any such errors and is efficient than using iterator. But it will highly depend on your requirement.

So the revision for the above code segment given earlier would be as,
for (int index = 0; index < purchased_products.size(); index++) {
  if (product_id == purchased_products.get(index).getProduct_id()) {
    purchased_products.remove(index);
    index--;
  }
}

July 22, 2011

Regex matching any sign(.) + whitespace characters

To match any sign with a regex the following simple piece of code would work just fine.

Pattern pattern = Pattern.compile(".*"); //compile the pattern
Matcher marcher = pattern.matcher(string); //assign the string to be matched
matcher.find() //find whether the pattern exists. Returns a boolean

But, if you need to include whitespace characters, that is \n,\t, etc the '.' regex will not do the trick. (There is also "\s" regex which captures whitespace characters, but it didn't quite address my problem)

While wandering through the Java API I found a flag which addresses this problem. That is  DOTALL. It will include line terminators into the regex while compiling the pattern. Therefore the new code would be,

Pattern pattern = Pattern.compile(".*", Pattern.DOTALL); //compile the pattern with terminating characters
Matcher marcher = pattern.matcher(string); //assign the string to be matched
matcher.find() //find whether the pattern exists. Returns a boolean

Failed attempt :
  • Tried to include '\n' in the regex.
To specify any two types of characters in a regex usually it is as "[ab]*". Pattern  "[a\\n]*" also works fine. But for some reason "[.\\n]*" doesn't work. So above was the successful solution I found to deal with it.

For a very good tutorial on regex refer here.

Tips
  • Match period
    "." is the symbol used for any character. So if you want to match "." specifically, you need to define the regex as "\\."

May 20, 2011

Displaying Sinhala in JTextArea

When I first tried to display Sinhala characters in a JTextArea, I got the following result, where all the Sinhala letters were replaced by boxes.

Original text : තමා_PRP හයිටිය_NNPI අතහැර_VNF පලා_VNF ගියේ_VP කැමැත්තකින්

The reason for this is that, it does not render Sinhala fonts.It is not a problem with detection of encoding. You can simply check the system default encoding with code below.
System.out.println(System.getProperty("file.encoding"));
This produced with UTF-8 encoding, which was ok for my requirement.

Now this meant, that the problem is in using an appropriate font for the JTextArea.
 
File fontFile = new File(fontpath); //load the font file
Font newFont = Font.createFont(Font.TRUETYPE_FONT, fontFile);
txtOutput.setFont(newFont); //set the font to JTextArea

The above code will add a font to a JTextArea. Out of the many fonts I tried, only "dinamina.ttf" rendered properly. Even lklug did not provide proper results (It only rendered Sinhala and English characters were not at all displayed). Following is the final output.



Download sinhala fonts from here

Updates :

  • Found our that lklug has only Sinhala fonts
  • Also Bhashitha is another font that worked fine with me
  • May 1, 2011

    for, while and do..while

    for, while and do..while are the three types of loops available for almost all imperative languages. But the concept is same for all of them and they only carry slight variations is syntax.

    One of the concerns when writing a loop is to identify which of the above three is most suitable. It is important if efficiency is an expectation of your program.

    while
    while(condition){
      //code here
    }

    do..while
    do{
      //code here
    }while(condition)

    for
    for( i = 0; i < 10; i++){
      //code here
    }

    while vs do..while
    The while and do..while loops both loop until a condition is false. But the difference between them is that the while loop will check the condition before the first iteration and the do..while will perform the first iteration and then after check the condition. Therefore the change is in the first iteration and after it is finished, there is no difference between the two loops.

    while vs for

    A common mis-use of the while loop is using a counter within it. That is use a counter to keep track of the number of iterations of the loop and making sure to exit the loop when the counter is exceeded.

    i = 0;
    while ( i < 5){
      //code here
    i++;
    }

    The purpose of the for loop is to be used in such situations.

    for ( int i = 0; i < 5; i++){
      //code here
    }

    Therefore, the main difference between the two would be to use the for loop when the number of iterations is known and use the while or do..while when unknown. But there is no real difference in efficiency for a situation as above. Hence, I believe its more of de facto.

    April 14, 2011

    Ceylon Tea to replace Java coffee?

    I just came across a new project called "Ceylon Project", thanks to a tweet by @charithsoori. I couldn't find why it is called "Ceylon" though, I am curious to know.
    It has being a secret project for 2 years at RedHat and the first breifing of it has happened on last 9th at Beijing by Gaving King. A copy of the briefing presentation is available from here. I really didn't have time to go through what it is all about, but from what I read it seems to be a very revolutionary language and a challenge for Java. Gavin King has mentioned it as "The Ceylon Project - the next generation of Java language?" at his briefing. This is a good enough statement to give a little thought to as whether tea will replace coffee.

    The aim of the project has being to create a new programming language and SDK for business computing, to overcome the drawbacks of Java. When it is released it will run on the JVM itself. It seems to me as a little into functional programming. Any way hope I had more time to research on it and write a better post :|. The thing which interested me was the name. Why was it named "Ceylon"? Maybe I will be able to write about it some later time.