{"id":1410,"date":"2012-06-11T19:00:00","date_gmt":"2012-06-11T19:00:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/java-jaas-form-based-authentication.html"},"modified":"2012-10-22T05:39:29","modified_gmt":"2012-10-22T05:39:29","slug":"java-jaas-form-based-authentication","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html","title":{"rendered":"Java JAAS form based authentication"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">\n<div style=\"text-align: justify\">Implementing a login module using JAAS  is an of advance topic and also most of the developers have rare chance of involving with this kind of development. But the basic implementation of JAAS login module is not that much hard implementation.That is because, I intended to post this. <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">Here, I am explaining, how to implement a tomcat managed authentication module. This implementation is not container dependent one. We can use it with any container with slight configuration change. <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">As the first step, We need to create a login module class which implements                      <strong>javax.security.auth.spi.LoginModule<\/strong> interface. This interface exposes 5 methods that must be implemented by our login module class. Those are                      <strong>initialize(), login(), commit(), abort(), logout()<\/strong>.                                         <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\"><strong>initialize()<\/strong> method is passed four arguments .                    <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">The &#8216;Subject&#8217;  is what, We need to authenticate. The subject can represents the related information for a single login user. It can represent identities like &#8216;username&#8217;, &#8216;password&#8217; etc. And also, it can represents the roles assigned to the user. All these identities should be represent as                      <strong>java.security.Principal.<\/strong> So We should create separate classes to distinguish these entities by implementing                       <strong>java.security.Principal<\/strong>. In my tutorial, I have created separate classes for username, password and role as JAASUserPrincipal, JAASPasswordPrincipal and JAASRolePrincipal.                                                               Subject&#8217;s                      <strong>getPrincipals()<\/strong> method returns a set of java.security.Principal associated with the subject. To distinguish these, it is important of Creating separate classes for each identity.                                                               <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">The &#8216;                     <strong>CallbackHandler<\/strong>&#8216;  is used to communicate with the user. When authenticating the user by the login module, the login module invokes the                      <strong>handle()<\/strong> method of the CallbackHandler instance to get the user name and password. We do not want to worry about CallbackHandler instance yet. Because the container manages to provide the required callbakcs. The tomcat provides                      <strong>JAASCallbackHandler<\/strong> for this purpose. But, If We want to invoke the authentication explicitly, We need to create our own call back handler class by implementing the                      <strong>javax.security.auth.callback.CallbackHandler<\/strong>. I will explain this at the end of the tutorial.                                                               <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">The next important argument for                      <strong>initialize()<\/strong> method is &#8216;options&#8217;. These options where We declare those in &#8216;                     <strong>jass.config<\/strong>&#8216; file. With the initialisation of login module, map of options declared in &#8216;jass.config&#8217; file are provided. I will explain the &#8216;jaas.config&#8217; file of our tutorial later.                                          <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">Next, I will show the full source code for our principal classes.                    <\/div>\n<p><strong>JAASUserPrincipal.java<\/strong><\/p>\n<pre class=\"brush:java\">package com.rainyday.server.login;\r\n\r\n import java.io.Serializable;\r\n import java.security.Principal;\r\n\r\n\/**\r\n * @author semika\r\n *\r\n *\/\r\n public class JAASUserPrincipal implements Principal, Serializable {\r\n\r\n private String name;\r\n \r\n \/**\r\n  * @param name\r\n  *\/\r\n public JAASUserPrincipal(String name) {\r\n  \r\n if (name == null) {\r\n     throw new NullPointerException(\"NULL user name\");\r\n }\r\n     this.name = name;\r\n }\r\n \r\n @Override\r\n public String getName() {\r\n     return name;\r\n }\r\n\r\n @Override\r\n public String toString() {\r\n     return \"UserPrincipal [name=\" + name + \"]\";\r\n }\r\n\r\n @Override\r\n public int hashCode() {\r\n     final int prime = 31;\r\n     int result = 1;\r\n     result = prime * result + ((name == null) ? 0 : name.hashCode());\r\n     return result;\r\n }\r\n\r\n @Override\r\n public boolean equals(Object obj) {\r\n     if (this == obj)\r\n        return true;\r\n     if (obj == null)\r\n        return false;\r\n     if (getClass() != obj.getClass())\r\n        return false;\r\n     JAASUserPrincipal other = (JAASUserPrincipal) obj;\r\n     if (name == null) {\r\n        if (other.name != null)\r\n           return false;\r\n     } else if (!name.equals(other.name))\r\n        return false;\r\n  \r\n     return true;\r\n }\r\n}\r\n<\/pre>\n<p><strong>JAASRolePrincipal.java<\/strong><\/p>\n<pre class=\"brush:java\">package com.rainyday.server.login;\r\n\r\n import java.io.Serializable;\r\n import java.security.Principal;\r\n\r\n\/**\r\n * @author semika\r\n *\r\n *\/\r\n public class JAASRolePrincipal implements Principal, Serializable {\r\n\r\n private String name;\r\n \r\n \/**\r\n  * @param name\r\n  *\/\r\n public JAASRolePrincipal(String name) {\r\n     if (name == null) {\r\n        throw new NullPointerException(\"NULL role name\");\r\n     }\r\n     this.name = name;\r\n }\r\n\r\n @Override\r\n public String getName() {\r\n    return name;\r\n }\r\n\r\n @Override\r\n public String toString() {\r\n     return \"JASSRolePrincipal [name=\" + name + \"]\";\r\n }\r\n\r\n @Override\r\n public int hashCode() {\r\n     final int prime = 31;\r\n     int result = 1;\r\n     result = prime * result + ((name == null) ? 0 : name.hashCode());\r\n     return result;\r\n }\r\n\r\n @Override\r\n public boolean equals(Object obj) {\r\n     if (this == obj)\r\n        return true;\r\n     if (obj == null)\r\n        return false;\r\n     if (getClass() != obj.getClass())\r\n        return false;\r\n     JAASRolePrincipal other = (JAASRolePrincipal) obj;\r\n     if (name == null) {\r\n        if (other.name != null)\r\n           return false;\r\n     } else if (!name.equals(other.name))\r\n        return false;\r\n     \r\n     return true;\r\n }\r\n}<\/pre>\n<p><strong>JAASPasswordPrincipal.java<\/strong><\/p>\n<pre class=\"brush:java\">package com.rainyday.server.login;\r\n\r\n import java.io.Serializable;\r\n import java.security.Principal;\r\n\r\n\/**\r\n * @author semika\r\n *\r\n *\/\r\n public class JAASPasswordPrincipal implements Principal, Serializable {\r\n\r\n private String name;\r\n \r\n \/**\r\n  * @param name\r\n  *\/\r\n public JAASPasswordPrincipal(String name) {\r\n     if (name == null) {\r\n        throw new NullPointerException(\"NULL password.\");\r\n     }\r\n     this.name = name;\r\n }\r\n\r\n @Override\r\n public String getName() {\r\n     return name;\r\n }\r\n\r\n @Override\r\n public int hashCode() {\r\n     final int prime = 31;\r\n     int result = 1;\r\n     result = prime * result + ((name == null) ? 0 : name.hashCode());\r\n     return result;\r\n }\r\n\r\n @Override\r\n public boolean equals(Object obj) {\r\n     if (this == obj)\r\n         return true;\r\n     if (obj == null)\r\n         return false;\r\n     if (getClass() != obj.getClass())\r\n         return false;\r\n     JAASPasswordPrincipal other = (JAASPasswordPrincipal) obj;\r\n     if (name == null) {\r\n        if (other.name != null)\r\n           return false;\r\n     } else if (!name.equals(other.name))\r\n        return false;\r\n     \r\n     return true;\r\n }\r\n\r\n @Override\r\n public String toString() {\r\n     return \"JAASPasswordPrincipal [name=\" + name + \"]\";\r\n }\r\n\r\n}\r\n<\/pre>\n<div style=\"text-align: justify\">The above three classes are exactly similar. But, We need to create separate classes for each principal to distinguish them.                     <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">The                      <strong>login()<\/strong> method of login module performs the authentication. This validates the user entered user name and password with the database. Now, You may have a problem, How login details entered by the user comes into the login() method. As I explained earlier, the call back handler brings the login identities into the login() method. From the login() method, the login module invokes the handle() method of call back handler by passing the required call backs into it. Then handle() method populates those call backs with the required information and make available to login() method.                                         <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">The                      <strong>commit()<\/strong> method is invoked by the login module after the successful authentication. The subject can be populated with associated principals. For example, We can retrieve user assigned roles from the database and attached those to the subject.                                         <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">The next, I will explain the required configurations to work this login module.                    <\/div>\n<div style=\"text-align: left\">\n<\/div>\n<div style=\"text-align: left\">We should create &#8216;jass.config&#8217; file and should be placed that file under &#8216;<strong>$CATALINA_HOME\/conf<\/strong>&#8216;.<\/div>\n<div style=\"text-align: left\">The &#8216;jass.config&#8217; file of this tutorial is as follows.                    <\/div>\n<pre class=\"brush:java\">rainyDay {\r\n   com.rainyday.server.login.JAASLoginModule required\r\n   dbDriver=\"com.mysql.jdbc.Driver\"\r\n   dbURL=\"jdbc:mysql:\/\/localhost\/rainyday\"\r\n   dbUser=\"root\"\r\n   dbPassword=\"abc123\"\r\n   userQuery=\"select username from secu_user where secu_user.username=? and secu_user.password=?\"\r\n   roleQuery=\"select secu_user_role.rolename from secu_user, secu_user_role&nbsp;\"\r\n             + \"where secu_user.username=secu_user_role.username and secu_user.username=?\"\r\n   debug=true;\r\n};\r\n<\/pre>\n<p>&#8216;jass.config&#8217; file should have this similar format. In addition to the login module declaration, You can declare options as your wish. These options are made available by login module with &#8216;options&#8217; map in initialize() method argument.                                                                <div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>Additionally, We should tell the tomcat, Where to locate the &#8216;jaas.config&#8217; file by adding it&#8217;s path to                      <strong>JAVA_OPTS<\/strong> environment variable. I have added this into &#8216;catalina.sh&#8217; file under $CATALINA_HOME\/bin as follows.                                         <\/p>\n<p>JAVA_OPTS=&#8221;$JAVA_OPTS -Djava.security.auth.login.config==..\/conf\/jaas.config&#8221;                    <\/p>\n<p>Next, You need to declare the                     <strong>JAASRealm<\/strong> configurations. You can add a new &#8216;Realm&#8217; entry into the server.xml file under $CATALINA_HOME\/conf. In our tutorial, the &#8216;Realm&#8217; entry is as follows. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <\/p>\n<pre class=\"brush:java\">&lt;Realm className=\"org.apache.catalina.realm.JAASRealm\"\r\n appName=\"rainyDay\"\r\n userClassNames=\"com.rainyday.server.login.JASSUserPrincipal,com.rainyday.server.login.JAASPasswordPrincipal\"\r\n roleClassNames=\"com.rainyday.server.login.JASSRolePrincipal\"\/&gt;\r\n<\/pre>\n<p>For apache tomcat&#8217;s realm configuration, You can view this                     <a href=\"http:\/\/tomcat.apache.org\/tomcat-5.5-doc\/config\/realm.html\">documentation<\/a>. The complete source code for our jaas login module.<\/p>\n<p><strong>JAASLoginModule.java<\/strong><\/p>\n<pre class=\"brush:java\">package com.rainyday.server.login;\r\n\r\nimport java.io.IOException;\r\nimport java.sql.Connection;\r\nimport java.sql.DriverManager;\r\nimport java.sql.PreparedStatement;\r\nimport java.sql.ResultSet;\r\nimport java.sql.SQLException;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport javax.security.auth.Subject;\r\nimport javax.security.auth.callback.Callback;\r\nimport javax.security.auth.callback.CallbackHandler;\r\nimport javax.security.auth.callback.NameCallback;\r\nimport javax.security.auth.callback.PasswordCallback;\r\nimport javax.security.auth.callback.UnsupportedCallbackException;\r\nimport javax.security.auth.login.LoginException;\r\nimport javax.security.auth.spi.LoginModule;\r\n\r\nimport org.apache.log4j.Logger;\r\n\r\n\/**\r\n * @author semika\r\n *\r\n *\/\r\npublic class JAASLoginModule implements LoginModule { \r\n \r\n    private static Logger LOGGER = Logger.getLogger(JAASLoginModule.class); \r\n \r\n    \/\/ initial state\r\n    private Subject subject;\r\n    private CallbackHandler callbackHandler;\r\n    private Map sharedState;\r\n    private Map options;\r\n\r\n    \/\/ configurable option\r\n    private boolean debug = false;\r\n    \r\n    \/\/ the authentication status\r\n    private boolean succeeded = false;\r\n    private boolean commitSucceeded = false;\r\n    \r\n    \/\/user credentials\r\n    private String username = null;\r\n    private char[] password = null;\r\n    \r\n    \/\/user principle\r\n    private JAASUserPrincipal userPrincipal = null;\r\n    private JAASPasswordPrincipal passwordPrincipal = null;\r\n    \r\n    public JAASLoginModule() {\r\n         super();\r\n    }\r\n\r\n    @Override\r\n    public void initialize(Subject subject, CallbackHandler callbackHandler,\r\n                Map&lt;string, ?=\"\"&gt; sharedState, Map&lt;string, ?=\"\"&gt; options) {\r\n        this.subject = subject;\r\n        this.callbackHandler = callbackHandler;\r\n        this.sharedState = sharedState;\r\n        this.options = options;\r\n  \r\n        debug = \"true\".equalsIgnoreCase((String)options.get(\"debug\")); \r\n    }\r\n\r\n    @Override\r\n    public boolean login() throws LoginException {\r\n  \r\n        if (callbackHandler == null){\r\n            throw new LoginException(\"Error: no CallbackHandler available \" +\r\n            \"to garner authentication information from the user\");\r\n        }\r\n        Callback[] callbacks = new Callback[2];\r\n        callbacks[0] = new NameCallback(\"username\");\r\n        callbacks[1] = new PasswordCallback(\"password: \", false);\r\n  \r\n        try {\r\n   \r\n            callbackHandler.handle(callbacks);\r\n            username = ((NameCallback)callbacks[0]).getName();\r\n            password = ((PasswordCallback)callbacks[1]).getPassword();\r\n   \r\n            if (debug) {\r\n                LOGGER.debug(\"Username :\" + username);\r\n                LOGGER.debug(\"Password : \" + password);\r\n            }\r\n   \r\n            if (username == null || password == null) {\r\n                LOGGER.error(\"Callback handler does not return login data properly\");\r\n                throw new LoginException(\"Callback handler does not return login data properly\"); \r\n            }\r\n   \r\n            if (isValidUser()) { \/\/validate user.\r\n                succeeded = true;\r\n                return true;\r\n            } \r\n   \r\n        } catch (IOException e) { \r\n             e.printStackTrace();\r\n        } catch (UnsupportedCallbackException e) {\r\n             e.printStackTrace();\r\n        }\r\n  \r\n        return false;\r\n    }\r\n\r\n    @Override\r\n    public boolean commit() throws LoginException {\r\n        if (succeeded == false) {\r\n            return false;\r\n        } else { \r\n            userPrincipal = new JAASUserPrincipal(username);\r\n            if (!subject.getPrincipals().contains(userPrincipal)) {\r\n                subject.getPrincipals().add(userPrincipal);\r\n                LOGGER.debug(\"User principal added:\" + userPrincipal);\r\n            }\r\n            passwordPrincipal = new JAASPasswordPrincipal(new String(password)); \r\n            if (!subject.getPrincipals().contains(passwordPrincipal)) {\r\n                subject.getPrincipals().add(passwordPrincipal);\r\n                LOGGER.debug(\"Password principal added: \" + passwordPrincipal);\r\n            }\r\n      \r\n            \/\/populate subject with roles.\r\n            List&lt;string&gt; roles = getRoles();\r\n            for (String role: roles) {\r\n                JAASRolePrincipal rolePrincipal = new JAASRolePrincipal(role);\r\n                if (!subject.getPrincipals().contains(rolePrincipal)) {\r\n                    subject.getPrincipals().add(rolePrincipal); \r\n                    LOGGER.debug(\"Role principal added: \" + rolePrincipal);\r\n                }\r\n            }\r\n      \r\n            commitSucceeded = true;\r\n      \r\n            LOGGER.info(\"Login subject were successfully populated with principals and roles\"); \r\n      \r\n            return true;\r\n       }\r\n   }\r\n\r\n   @Override\r\n   public boolean abort() throws LoginException {\r\n      if (succeeded == false) {\r\n          return false;\r\n      } else if (succeeded == true &amp;&amp; commitSucceeded == false) {\r\n          succeeded = false;\r\n          username = null;\r\n          if (password != null) {\r\n              password = null;\r\n          }\r\n          userPrincipal = null;    \r\n      } else {\r\n          logout();\r\n      }\r\n      return true;\r\n   }\r\n\r\n    @Override\r\n    public boolean logout() throws LoginException {\r\n        subject.getPrincipals().remove(userPrincipal);\r\n        succeeded = false;\r\n        succeeded = commitSucceeded;\r\n        username = null;\r\n        if (password != null) {\r\n            for (int i = 0; i &lt; password.length; i++){\r\n                password[i] = ' ';\r\n                password = null;\r\n            }\r\n        }\r\n        userPrincipal = null;\r\n        return true;\r\n   }\r\n \r\n   private boolean isValidUser() throws LoginException {\r\n\r\n      String sql = (String)options.get(\"userQuery\");\r\n      Connection con = null;\r\n      ResultSet rs = null;\r\n      PreparedStatement stmt = null;\r\n  \r\n      try {\r\n          con = getConnection();\r\n          stmt = con.prepareStatement(sql);\r\n          stmt.setString(1, username);\r\n          stmt.setString(2, new String(password));\r\n   \r\n          rs = stmt.executeQuery();\r\n   \r\n          if (rs.next()) { \/\/User exist with the given user name and password.\r\n              return true;\r\n          }\r\n       } catch (Exception e) {\r\n           LOGGER.error(\"Error when loading user from the database \" + e);\r\n           e.printStackTrace();\r\n       } finally {\r\n           try {\r\n               rs.close();\r\n           } catch (SQLException e) {\r\n               LOGGER.error(\"Error when closing result set.\" + e);\r\n           }\r\n           try {\r\n               stmt.close();\r\n           } catch (SQLException e) {\r\n               LOGGER.error(\"Error when closing statement.\" + e);\r\n           }\r\n           try {\r\n               con.close();\r\n           } catch (SQLException e) {\r\n               LOGGER.error(\"Error when closing connection.\" + e);\r\n           }\r\n       }\r\n       return false;\r\n   }\r\n\r\n \/**\r\n  * Returns list of roles assigned to authenticated user.\r\n  * @return\r\n  *\/\r\n  private List&lt;string&gt; getRoles() { \r\n  \r\n      Connection con = null;\r\n      ResultSet rs = null;\r\n      PreparedStatement stmt = null;\r\n  \r\n      List&lt;string&gt; roleList = new ArrayList&lt;string&gt;(); \r\n  \r\n      try {\r\n          con = getConnection();\r\n          String sql = (String)options.get(\"roleQuery\");\r\n          stmt = con.prepareStatement(sql);\r\n          stmt.setString(1, username);\r\n   \r\n          rs = stmt.executeQuery();\r\n   \r\n          if (rs.next()) { \r\n              roleList.add(rs.getString(\"rolename\")); \r\n          }\r\n      } catch (Exception e) {\r\n          LOGGER.error(\"Error when loading user from the database \" + e);\r\n          e.printStackTrace();\r\n      } finally {\r\n           try {\r\n               rs.close();\r\n           } catch (SQLException e) {\r\n               LOGGER.error(\"Error when closing result set.\" + e);\r\n           }\r\n           try {\r\n               stmt.close();\r\n           } catch (SQLException e) {\r\n               LOGGER.error(\"Error when closing statement.\" + e);\r\n           }\r\n           try {\r\n               con.close();\r\n           } catch (SQLException e) {\r\n               LOGGER.error(\"Error when closing connection.\" + e);\r\n           }\r\n       }\r\n       return roleList;\r\n }\r\n \r\n \/**\r\n  * Returns JDBC connection\r\n  * @return\r\n  * @throws LoginException\r\n  *\/\r\n  private Connection getConnection() throws LoginException {\r\n  \r\n      String dBUser = (String)options.get(\"dbUser\");\r\n      String dBPassword = (String)options.get(\"dbPassword\");\r\n      String dBUrl = (String)options.get(\"dbURL\");\r\n      String dBDriver = (String)options.get(\"dbDriver\");\r\n\r\n      Connection con = null;\r\n      try {\r\n         \/\/loading driver\r\n         Class.forName (dBDriver).newInstance();\r\n         con = DriverManager.getConnection (dBUrl, dBUser, dBPassword);\r\n      } \r\n      catch (Exception e) {\r\n         LOGGER.error(\"Error when creating database connection\" + e);\r\n         e.printStackTrace();\r\n      } finally {\r\n      }\r\n      return con;\r\n   }\r\n}\r\n<\/pre>\n<div style=\"text-align: justify\">The                      <strong>abort()<\/strong> method of the login module will be invoked if something went wrong within the login() or commit() method execution. In this kind of situation, We can not say that the authentication process was successfully completed and the required clean up operations can be done within the abort() method, if the authentication process encountered a failure.                                         <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">We can utilise the &#8216;options&#8217; map which was initialise within the initialize() method of the login module to get the configuration information declared within the &#8216;jass.config&#8217; file. You can come up with a good technique to get JDBC connection object. I did not concentrate on that with in this tutorial and only wanted to show you the mechanism, How the things should be done.<\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">By now, We have completed the thing which are required for basic JAAS authentication module. Next, We should configure our security constraints in web.xml file.<\/div>\n<pre class=\"brush:xml\">&lt;login-config&gt;\r\n     &lt;auth-method&gt;FORM&lt;\/auth-method&gt;\r\n     &lt;realm-name&gt;rainyDay&lt;\/realm-name&gt;\r\n     &lt;form-login-config&gt;\r\n          &lt;form-login-page&gt;\/login.jsp&lt;\/form-login-page&gt;\r\n          &lt;form-error-page&gt;\/error.jsp&lt;\/form-error-page&gt;\r\n     &lt;\/form-login-config&gt;\r\n&lt;\/login-config&gt;\r\n&lt;security-role&gt;\r\n    &lt;role-name&gt;*&lt;\/role-name&gt;\r\n&lt;\/security-role&gt;\r\n&lt;security-constraint&gt;\r\n    &lt;web-resource-collection&gt;\r\n         &lt;web-resource-name&gt;Rainy day&lt;\/web-resource-name&gt;\r\n         &lt;url-pattern&gt;\/&lt;\/url-pattern&gt;\r\n         &lt;http-method&gt;POST&lt;\/http-method&gt;\r\n         &lt;http-method&gt;GET&lt;\/http-method&gt;\r\n    &lt;\/web-resource-collection&gt;\r\n    &lt;auth-constraint&gt;\r\n         &lt;role-name&gt;*&lt;\/role-name&gt;\r\n    &lt;\/auth-constraint&gt;\r\n&lt;\/security-constraint&gt;<\/pre>\n<p>With the above security constraints, if some request comes to a particular resource in the protected area of the application with out the authentication, the request will be redirected to the &#8216;login&#8217; page. Next, I will show you the simple HTML form which invokes our login module with the submission of the form.<\/p>\n<pre class=\"brush:java\"> &lt;form id=\"loginForm\" name=\"loginForm\" method=\"post\" action=\"j_security_check\"&gt;\r\n        User Name : &lt;input id=\"username\" type=\"text\" name=\"j_username\" class=\"textbox\"&gt;&lt;\/input&gt;\r\n        Password : &lt;input id=\"password\" type=\"password\" name=\"j_password\" class=\"textbox\"&gt;&lt;\/input&gt;\r\n        &lt;input name=\"login\" type=\"submit\" value=\"LOGIN\" id=\"submit\" class=\"button blue\"&gt;\r\n &lt;\/form&gt;<\/pre>\n<div style=\"text-align: justify\">So, We are done with that.This is very basic implementation of JAAS. The advantage of this kind of JAAS module is, We can switch to a different login module implementation just with a single configuration change and without doing any modification to our existing code. And also this is container independent. If You want to deploy this with jBoss server, instead of &#8216;jass.config&#8217;, You can use &#8216;login-config.xml&#8217; file in jboss conf folder. As I promised you to explain, How to invoke this kind of login module explicitly, here it is. There are some circumstances, We need to authenticate a particular user with pragmatically, but still We should use our implemented login module. In this kind of situation, the big problem is providing user identities (user name, password etc) to the our login module. In the above case, We used a &#8216;CallbackHandler&#8217; class which is &#8216;JAASCallbackHander&#8217; provided by apache catalina. But, Here We can not use and We have to implement our own call back handler class.<\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<p><strong>JAASCallbackHandler.java <\/strong>                     <\/p>\n<pre class=\"brush:java\">package com.rainyday.server.login;\r\n\r\nimport java.io.IOException;\r\n\r\nimport javax.security.auth.callback.Callback;\r\nimport javax.security.auth.callback.CallbackHandler;\r\nimport javax.security.auth.callback.NameCallback;\r\nimport javax.security.auth.callback.PasswordCallback;\r\nimport javax.security.auth.callback.UnsupportedCallbackException;\r\n\r\nimport org.apache.log4j.Logger;\r\n\r\n\/**\r\n * @author semika\r\n *\r\n *\/\r\n public class JAASCallbackHandler implements CallbackHandler {\r\n\r\n private static final Logger LOGGER = Logger.getLogger(JAASCallbackHandler.class);\r\n \r\n private String username = null;\r\n private String password = null;\r\n \r\n \/**\r\n  * @param username\r\n  * @param password\r\n  *\/\r\n public JAASCallbackHandler(String username, String password) {\r\n     this.username = username;\r\n     this.password = password;\r\n }\r\n\r\n\r\n @Override\r\n public void handle(Callback[] callbacks) throws IOException,\r\n   UnsupportedCallbackException {\r\n  \r\n     LOGGER.info(\"Callback Handler invoked \");\r\n  \r\n     for (int i = 0; i &lt; callbacks.length; i++) {\r\n        if (callbacks[i] instanceof NameCallback) {\r\n           NameCallback nameCallback = (NameCallback) callbacks[i];\r\n           nameCallback.setName(username);\r\n        } else if (callbacks[i] instanceof PasswordCallback) {\r\n           PasswordCallback passwordCallback = (PasswordCallback) callbacks[i];\r\n           passwordCallback.setPassword(password.toCharArray());\r\n        } else {\r\n           throw new UnsupportedCallbackException(callbacks[i], \"The submitted Callback is unsupported\");\r\n        }\r\n     }\r\n }\r\n}\r\n<\/pre>\n<p>Next, We have to create an instance of &#8216;                    <strong>LoginContext&#8217;<\/strong> to invoke the authentication explicitly.<\/p>\n<pre class=\"brush:java\">    LoginContext lc = null;\r\n    try {\r\n        lc = new LoginContext(\"rainyDay\", new JAASCallbackHandler(username, password));\r\n        lc.login();\r\n        \/\/get the subject.\r\n        Subject subject = lc.getSubject();\r\n        \/\/get principals\r\n        subject.getPrincipals();\r\n        LOGGER.info(\"established new logincontext\");\r\n    } catch (LoginException e) {\r\n        LOGGER.error(\"Authentication failed \" + e);\r\n    } \r\n<\/pre>\n<div style=\"text-align: justify\">If We end up with the execution of above code without any exception, that implies the authentication was succeeded. If an exception was encountered, authentication has failed.                                                                <\/div>\n<div style=\"text-align: justify\">\n<\/div>\n<div style=\"text-align: justify\">That&#8217;s all from this tutorials.                      <a href=\"http:\/\/docs.oracle.com\/javaee\/1.4\/tutorial\/doc\/Security5.html\">http:\/\/docs.oracle.com\/javaee\/1.4\/tutorial\/doc\/Security5.html<\/a> was a good tutorial for me to understand login authentication.  <\/div>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/semikas.blogspot.gr\/2012\/03\/java-form-based-authentication.html\">Java form based authentication <\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Semika loku kaluge at the <a href=\"http:\/\/semikas.blogspot.gr\/\">Code Box <\/a> blog.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development. But the basic implementation of JAAS login module is not that much hard implementation.That is because, I intended to post this. Here, I am explaining, how to implement &hellip;<\/p>\n","protected":false},"author":227,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[296,297],"class_list":["post-1410","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-jaas","tag-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Java JAAS form based authentication - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Java JAAS form based authentication - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-06-11T19:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-22T05:39:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Semika Kaluge\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Semika Kaluge\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html\"},\"author\":{\"name\":\"Semika Kaluge\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/511aa57cb783e9e45ebbdfbaeea786e1\"},\"headline\":\"Java JAAS form based authentication\",\"datePublished\":\"2012-06-11T19:00:00+00:00\",\"dateModified\":\"2012-10-22T05:39:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html\"},\"wordCount\":1199,\"commentCount\":11,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"JAAS\",\"Security\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html\",\"name\":\"Java JAAS form based authentication - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2012-06-11T19:00:00+00:00\",\"dateModified\":\"2012-10-22T05:39:29+00:00\",\"description\":\"Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/06\\\/java-jaas-form-based-authentication.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Java JAAS form based authentication\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/511aa57cb783e9e45ebbdfbaeea786e1\",\"name\":\"Semika Kaluge\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/19ddbcbcd7a71589e915a5fe88bc5478d414fb1a8b35504d927473cb74abf9a1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/19ddbcbcd7a71589e915a5fe88bc5478d414fb1a8b35504d927473cb74abf9a1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/19ddbcbcd7a71589e915a5fe88bc5478d414fb1a8b35504d927473cb74abf9a1?s=96&d=mm&r=g\",\"caption\":\"Semika Kaluge\"},\"description\":\"I am working in software engineering field for six years of time by now. Currently, I am working for Shipxpress Inc in Sri Lanka. Primarily, I love to involve with Java developments and related frameworks like Spring, Struts, Hibernate and many more, specially interested in Javascript.\",\"sameAs\":[\"http:\\\/\\\/semikas.blogspot.com\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/semika-kaluge\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Java JAAS form based authentication - Java Code Geeks","description":"Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html","og_locale":"en_US","og_type":"article","og_title":"Java JAAS form based authentication - Java Code Geeks","og_description":"Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development.","og_url":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-06-11T19:00:00+00:00","article_modified_time":"2012-10-22T05:39:29+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Semika Kaluge","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Semika Kaluge","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html"},"author":{"name":"Semika Kaluge","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/511aa57cb783e9e45ebbdfbaeea786e1"},"headline":"Java JAAS form based authentication","datePublished":"2012-06-11T19:00:00+00:00","dateModified":"2012-10-22T05:39:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html"},"wordCount":1199,"commentCount":11,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["JAAS","Security"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html","url":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html","name":"Java JAAS form based authentication - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2012-06-11T19:00:00+00:00","dateModified":"2012-10-22T05:39:29+00:00","description":"Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development.","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/06\/java-jaas-form-based-authentication.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Java JAAS form based authentication"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/511aa57cb783e9e45ebbdfbaeea786e1","name":"Semika Kaluge","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/19ddbcbcd7a71589e915a5fe88bc5478d414fb1a8b35504d927473cb74abf9a1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/19ddbcbcd7a71589e915a5fe88bc5478d414fb1a8b35504d927473cb74abf9a1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/19ddbcbcd7a71589e915a5fe88bc5478d414fb1a8b35504d927473cb74abf9a1?s=96&d=mm&r=g","caption":"Semika Kaluge"},"description":"I am working in software engineering field for six years of time by now. Currently, I am working for Shipxpress Inc in Sri Lanka. Primarily, I love to involve with Java developments and related frameworks like Spring, Struts, Hibernate and many more, specially interested in Javascript.","sameAs":["http:\/\/semikas.blogspot.com"],"url":"https:\/\/www.javacodegeeks.com\/author\/semika-kaluge"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/227"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=1410"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1410\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=1410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=1410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=1410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}