J2EE Form-based Authentication
Implementing security for Web applications is a mandatory task for architects and Web application developers. In J2EE, the Web containers have support for built-in security mechanisms for their applications.
There are two major components of Web application security: authentication and authorization. J2EE-based Web containers offer three types of authentication mechanisms: basic, form-based, and mutual authentication. Most Web applications use the form-based authentication mechanism, since it allows applications to customize the authentication user interface. Web containers implement authorization on Web resources of applications, using security roles defined in the deployment descriptor of the Web application.
There are three issues that software architects and software developers come across using the form-based authentication mechanism:
• How the form-based authentication works with other security realms, such as database and LDAP (this is necessary because most organizations may already have authentication information in database or LDAP form).
• How to add or delete authorization roles declared in the deployment descriptor (web.xml) of the Web application.
• Web containers enforce authorization at Web resource level; however, an application needs to enforce authorization at its functionality level within a single Web resource.
Despite the fact that there is plenty of documentation and many examples available for form-based authentication, none of them clarifies these issues. Hence, most applications have implemented security in their own way.
This article demonstrates how the form-based authentication mechanism works with other security realms, especially the database. It also explains how Web containers use the security roles to implement authorization, and how applications can extend these security roles to protect functionalities within single resource.
Form-Based Authentication
Form-based authentication lets developers customize the authentication user interface. The login-config section of web.xml defines the type of authentication mechanism, and the URIs to login and error pages.
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>
The login form must contain fields for entering username and password. These fields must be named j_username and j_password, respectively. This form should post these values to j_security_check logical name.
Here is an example showing how the form should be coded into an HTML page:
<form method="POST" action="j_security_check">
<input name="j_username">
<input name="j_password">
</form>
This form of authentication, which uses base64 encoding, can expose username and password unless all connections are over SSL.
The Web containers activate the authentication mechanism that has been configured for that resource, when protected Web resources are accessed.
Web containers perform the following steps to implement security of a Web application.
1. Determines whether the user has been authenticated when the protected Web resources are accessed.
2. If the user has not been authenticated yet, requests that the user provide security credentials by redirecting to the login page defined in the deployment descriptor.
3. Validates the user's credentials against the security realm configured for the container.
4. Determines whether the authenticated user is authorized to access Web resources defined in the deployment descriptor (web.xml).
In the deployment descriptor of a Web application, form-based authentication does not specify the security realm, as the basic authentication mechanism does. In other words, it does not explicitly declare the type of security realm it should use to authenticate a user. This causes some confusion as to what security realm it actually uses to authenticate the user.
Web containers perform the following steps to validate a user:
1. Determines the configured security realm for the container.
2. Uses that security realm for authentication.
Since database and LDAP provide greater flexibility in maintaining information, most organizations may want this persistence for security authentication and authorization information.
Many Web containers have support for different types of security realms: database, LDAP, and custom realm.
For example, in the Tomcat Web container, server.xml configures database as its security realm.
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
The <Realm> tag of Tomcat's server.xml defines the type of security realm that the container should use to authenticate a user. Note that the container uses this realm for Web applications whose authentication mechanism is form-based.
Note: Please see the sections on deploying database security realm support for Tomcat and WebLogic below.
Authorization
Once the user has been authenticated, the container retrieves security roles for the authenticated user and checks to see if the user belongs to one of the roles defined in the <auth-constraint> tag of the deployment descriptor. The Web container displays an error message if the user does not belong to one of roles.
The <security-constraint> tag of the deployment descriptor (web.xml) defines protected Web resources and a list of roles that have access to these Web resources.
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPages</web-resource-name>
<description> accessible by authorised users </description>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>These are the roles who have access</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
Web containers enforce authorization at a page level. However, commercial applications may also want to enforce authorization on functionalities within a single page. This may require that some additional new application-specific security roles be defined in the application. To control access to functionalities, the application needs to understand the notion of privileges for a role. The Web container specification does not address privileges.
Since authorization roles are dynamic, developers often get confused as to whether these security roles need to be added to the deployment descriptor. Web containers just need one role defined in the deployment descriptor for the application to take advantage of security support. So, the application can define one high-level role and assign all users to this role. This allows all users in this role to have access to the Web resources.
In addition, the application can define additional roles to enforce authorization on low-level functionalities within a single Web resource. These low-level security roles do not need to be in the deployment descriptor, since the application has been configured with a high-level security role that contains all of the users in the application. This allows Web applications to take advantage of container authorization support, and to implement application-specific authorization.
For example, you can define an administrator role for all of the users at a high level in the deployment descriptor to protect administration Web resources. This allows all of the users in the administrator role to access the administration pages. To control other functionalities within the administration pages, you can create new roles, such as sysadmin or appadmin, within the application.
The application can extend these security roles to have privileges. Then, the application can use these privileges to control access to its functionalities.
Despite the fact that application-specific security roles are not defined in the deployment descriptors, these roles can still be used in the isUserInRole method to determine whether the user in these security roles.
Advantages
• Web applications do not need to implement the authentication mechanism by themselves. It is simply a matter of configuring the Web application.
• Web applications can implement programmatic security using getRemoteUser, IsUserInRole, and getUserPrincipal methods.
• The Web container is capable of propagating authentication information to EJB containers.
Configuring the Database Security Realm in Tomcat
Create User Table
This table needs the username and password columns.
create table users (username varchar(20) not null, password(20) not null)
Create Role Table
This table maintains the list of roles in application. It just needs role name column in the table.
create table roles (rolename varchar(20) not null)
Create User-Role Association Table
This table maintains association between a user and roles. A user can belong to one or more roles.
create table user_roles (username varchar(20) not null, rolename varchar(20) not null)
Insert data into tables
insert into users values('user1', 'password')
insert into role values('manager')
insert into user_roles values('user1', 'manager')
Create User Table
This table needs the username and password columns.
create table users (username varchar(20) not null, password(20) not null)
Create Role Table
This table maintains the list of roles in the application. It just needs the role name column in the table.
create table roles (rolename varchar(20) not null)
Create User-Role Association Table
This table maintains association between a user and roles. A user can belong to one or more roles.
create table user_roles (username varchar(20) not null, rolename varchar(20) not null)
Insert data into tables
insert into users values('user1', 'password')
insert into role values('manager')
insert into user_roles values('user1', 'manager')
Configure Tomcat (This example uses the Oracle thin driver) by copying this information in server.xml in the {tomcat}\conf\ folder. (Tomcat uses memory realm as default realm. Comment the memory realm.)
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IP address}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
Replace the following values with environment values
{IP Address} - IP address of database server
{Port} - Port number
{Servicename} - Service name
{DB Username} - database login
{Password} - password to database login
Note: You need to have the JDBC driver for your database. (The Oracle thin driver is used in this example.)
Copy the Oracle thin driver JAR file or JDBC driver for your database (oracle_thin_driver.jar) into the {tomcat_home}/server/lib directory.
Configure the Web application deployment descriptor with security constraints.
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint><transport-guarantee>
NONE</transport-guarantee></user-data-constraint>
</security-constraint>
<!-- Default login configuration uses form-based authentication -->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/jsp/login.jsp</form-login-page>
<form-error-page>/jsp/error.jsp</form-error-page>
</form-login-config>
</login-config>
Note that the <role-name> value of this tag in <auth-constraint> should be one of the role names in the user-roles table.
Deploying The Sample Program Into Tomcat
1. Configure Tomcat using the instructions defined in the previous section.
2. Download the security-form-based.war file and copy it into Tomcat's webapps directory.
3. Start the Tomcat server.
4. Open a Web browser and go to http://{ip address:port no}/security-form-based/protected/index.jsp.
5. Type in the username and the password (user1, password).
Configuring the Database Security Realm in WebLogic
There is very good documentation on configuring the database security realm. Please refer to this link.
Configure your Web application deployment descriptor, similar to the one shown in the configuration steps for Tomcat.
One difference between Tomcat and WebLogic deployment descriptors is that the deployment descriptor for WebLogic requires the following section, while Tomcat does not require this section.
<security-role>
<description>
Manager security role
</description>
<role-name>
manager
</role-name>
</security-role>
Conclusion
This article has provided in-depth understanding of the form-based mechanism and how it works with database security realms to handle authentication. Web applications can take advantage of the form-based mechanism to protect their resources while at the same time using legacy security realms for authentication information.
In addition, this article has described the level of authorization support provided by J2EE Web containers and how you can define new security roles without modifying the deployment descriptor of a Web application
Import javax.naming .*;
Import javax.naming.directory .*;
Import java.util.Hashtable;
Class UsePool
Public static void main (String [] args) (
Hashtable env = new Hashtable (11);
Env.put (Context.INITIAL_CONTEXT_FACTORY,
"Com.sun.jndi.ldap.LdapCtxFactory");
Env.put (Context.PROVIDER_URL, "ldap: / / localhost: 389 / o = JNDITutorial");
Env.put ( "com.sun.jndi.ldap.connect.pool", "true");
Try (
DirContext ctx = new InitialDirContext (env);
System.out.println (ctx.getAttributes ( "ou = NewHires"));
/ / Do something useful with ctx
Ctx.close (); / / Return connection to pool
DirContext ctx2 = new InitialDirContext (env);
System.out.println (ctx2.getAttributes ( "ou = People"));
/ / Do something useful with ctx2
Ctx2.close (); / / Return connection to pool
) Catch (NamingException e) (
E.printStackTrace ();
)
)
)
Creation Timeout
The pool of connections maintained by the LDAP service provider may be limited in size; this is described in detail in the Connection Pooling Configuration section. When connection pooling has been enabled and no pooled connection is available, the client application will block, waiting for an available connection. You can use the"com.sun.jndi.ldap.connect.timeout" environment property to specify how long to wait for a pooled connection. If you omit this property, the application will wait indefinitely.
This same property is also used to specify a timeout period for establishment of the LDAP connection, as described in the Connection Creation section.
When Not to Use Pooling
Pooled connections are intended to be reused. Therefore, if you plan to perform operations on a Context instance that might alter the underlying connection's state, then you should not use connection pooling for that Context instance. For example, if you plan to invoke the Start TLS extended operation on a Context instance, or plan to change security-related properties (such as "java.naming.security.principal" or"java.naming.security.protocol") after the initial context has been created, you should not use connection pooling for that Context instance because the LDAP provider does not track any such state changes. If you use connection pooling in such situations, you might be compromising the security of your application
Declarative Security
Servlet containers implement declarative security. The administration is done through the deployment descriptor web.xml file. With declarative security the Servlets and JSP pages will be free from any security aware code.You can protect your URLs through web.xml as shown below:
web-app>
<security-constraint>
<web-resource-collection>
<web-resource-name>PrivateAndSensitive</web-resource-name>
<url-pattern>/private/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>executive</role-name>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<!-- form based authorization -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
</web-app>
The user will be prompted for the configured login.jsp when restricted resources are accessed. The container also keeps track of which users have been previously authenticated.
Benefits: Very little coding is required and developers can concentrate on the application they are building and system administrators can administer the security settings without or with minimal developer intervention. Let’slook at a sample programmatic security in a Web module like a servlet:
User user = new User();
Principal principal = request.getUserPrincipal();
if (request.isUserInRole("boss"))
user.setRole(user.BOSS_ROLE);
Design Pattern: JDBC architecture decouples an abstraction from its implementation so that the implementation can vary independent of the abstraction. This is an example of the bridge design pattern. The JDBC API provides the abstraction and the JDBC drivers provide the implementation. New drivers can be plugged-in to the JDBC API without changing the client code..
-----------------------------------------------------------------------------------------------------------------------------------------------Discuss EJB container security?
EJB components operate inside a container environment and rely heavily on the container to provide security. The four key services required for the security are:
• Identification: In Java security APIs this identifier is known as a principal.
• Authentication: To prove the identity one must present the credentials in the form of password, swipe card, digital certificate, finger prints etc.
• Authorisation (Access Control): Every secure system should limit access to particular users. The common way to enforce access control is by maintaining security roles and privileges.
• Data Confidentiality: This is maintained by encryption of some sort. It is no good to protect your data by authentication if someone can read the password.
The EJB specification concerns itself exclusively with authorisation (access control). An application using EJB can specify in an abstract (declarative) and portable way that is allowed to access business methods. The EJB container handles the following actions:
• Find out the Identity of the caller of a business method.
• Check the EJB deployment descriptor to see if the identity is a member of a security role that has been granted the right to call this business method.
• Throw java.rmi.RemoteException if the access is illegal.
• Make the identity and the security role information available for a fine grained programmatic security check.
public void closeAccount() {
if (ejbContext.getCallerPrincipal().getName() = “SMITH”) {
//…
}
if (!ejbContext .isCallerInRole(CORPORATE_ACCOUNT_MANAGER)) {
throw new SecurityException(“Not authorized to close this account”);
}
}
• Optionally log any illegal access.
There are two types of information the EJB developer has to provide through the deployment descriptor.
• Security roles
• Method permissions
Example:
<security-role>
<description>
Allowed to open and close accounts
</description>
<role-name>account_manager</role-name>
</security-role>
<security-role>
<description>
Allowed to read only
</description>
<role-name>teller</role-name>
</security-role>
There is a many-to-many relationship between the security roles and the method permissions.
<method-permission>
<role-name>teller</role-name>
<method>
<ejb-name>AccountProcessor</ejb-name>
<method-name>findByPrimaryKey</method-name>
</method>
</method-permission>
Just as we must declare the resources accessed in our code for other EJBs that we reference in our code we
should also declare the security role we access programmatically to have a fine grained control as shown below.
<security-role-ref>
<description>
Allowed to open and close accounts
</description>
<role-name>account_manager</role-name>
<role-link>executive</role-link>
</security-role-ref>
There is also many-to-many relationship between the EJB specific security roles that are in the deployment descriptor and the application based target security system like LDAP etc. For example there might be more than one group users and individual users that need to be mapped
to a particular EJB security role ‘account_manager’.
-----------------------------------------------------------------------------------------------------------------------------------------------J2EE Form-based Authentication
Implementing security for Web applications is a mandatory task for architects and Web application developers. In J2EE, the Web containers have support for built-in security mechanisms for their applications.
There are two major components of Web application security: authentication and authorization. J2EE-based Web containers offer three types of authentication mechanisms: basic, form-based, and mutual authentication. Most Web applications use the form-based authentication mechanism, since it allows applications to customize the authentication user interface. Web containers implement authorization on Web resources of applications, using security roles defined in the deployment descriptor of the Web application.
There are three issues that software architects and software developers come across using the form-based authentication mechanism:
• How the form-based authentication works with other security realms, such as database and LDAP (this is necessary because most organizations may already have authentication information in database or LDAP form).
• How to add or delete authorization roles declared in the deployment descriptor (web.xml) of the Web application.
• Web containers enforce authorization at Web resource level; however, an application needs to enforce authorization at its functionality level within a single Web resource.
Despite the fact that there is plenty of documentation and many examples available for form-based authentication, none of them clarifies these issues. Hence, most applications have implemented security in their own way.
This article demonstrates how the form-based authentication mechanism works with other security realms, especially the database. It also explains how Web containers use the security roles to implement authorization, and how applications can extend these security roles to protect functionalities within single resource.
Form-Based Authentication
Form-based authentication lets developers customize the authentication user interface. The login-config section of web.xml defines the type of authentication mechanism, and the URIs to login and error pages.
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>
The login form must contain fields for entering username and password. These fields must be named j_username and j_password, respectively. This form should post these values to j_security_check logical name.
Here is an example showing how the form should be coded into an HTML page:
<form method="POST" action="j_security_check">
<input name="j_username">
<input name="j_password">
</form>
This form of authentication, which uses base64 encoding, can expose username and password unless all connections are over SSL.
The Web containers activate the authentication mechanism that has been configured for that resource, when protected Web resources are accessed.
Web containers perform the following steps to implement security of a Web application.
1. Determines whether the user has been authenticated when the protected Web resources are accessed.
2. If the user has not been authenticated yet, requests that the user provide security credentials by redirecting to the login page defined in the deployment descriptor.
3. Validates the user's credentials against the security realm configured for the container.
4. Determines whether the authenticated user is authorized to access Web resources defined in the deployment descriptor (web.xml).
In the deployment descriptor of a Web application, form-based authentication does not specify the security realm, as the basic authentication mechanism does. In other words, it does not explicitly declare the type of security realm it should use to authenticate a user. This causes some confusion as to what security realm it actually uses to authenticate the user.
Web containers perform the following steps to validate a user:
1. Determines the configured security realm for the container.
2. Uses that security realm for authentication.
Since database and LDAP provide greater flexibility in maintaining information, most organizations may want this persistence for security authentication and authorization information.
Many Web containers have support for different types of security realms: database, LDAP, and custom realm.
For example, in the Tomcat Web container, server.xml configures database as its security realm.
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
The <Realm> tag of Tomcat's server.xml defines the type of security realm that the container should use to authenticate a user. Note that the container uses this realm for Web applications whose authentication mechanism is form-based.
Note: Please see the sections on deploying database security realm support for Tomcat and WebLogic below.
Authorization
Once the user has been authenticated, the container retrieves security roles for the authenticated user and checks to see if the user belongs to one of the roles defined in the <auth-constraint> tag of the deployment descriptor. The Web container displays an error message if the user does not belong to one of roles.
There are two major components of Web application security: authentication and authorization. J2EE-based Web containers offer three types of authentication mechanisms: basic, form-based, and mutual authentication. Most Web applications use the form-based authentication mechanism, since it allows applications to customize the authentication user interface. Web containers implement authorization on Web resources of applications, using security roles defined in the deployment descriptor of the Web application.
There are three issues that software architects and software developers come across using the form-based authentication mechanism:
• How the form-based authentication works with other security realms, such as database and LDAP (this is necessary because most organizations may already have authentication information in database or LDAP form).
• How to add or delete authorization roles declared in the deployment descriptor (web.xml) of the Web application.
• Web containers enforce authorization at Web resource level; however, an application needs to enforce authorization at its functionality level within a single Web resource.
Despite the fact that there is plenty of documentation and many examples available for form-based authentication, none of them clarifies these issues. Hence, most applications have implemented security in their own way.
This article demonstrates how the form-based authentication mechanism works with other security realms, especially the database. It also explains how Web containers use the security roles to implement authorization, and how applications can extend these security roles to protect functionalities within single resource.
Form-Based Authentication
Form-based authentication lets developers customize the authentication user interface. The login-config section of web.xml defines the type of authentication mechanism, and the URIs to login and error pages.
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>
The login form must contain fields for entering username and password. These fields must be named j_username and j_password, respectively. This form should post these values to j_security_check logical name.
Here is an example showing how the form should be coded into an HTML page:
<form method="POST" action="j_security_check">
<input name="j_username">
<input name="j_password">
</form>
This form of authentication, which uses base64 encoding, can expose username and password unless all connections are over SSL.
The Web containers activate the authentication mechanism that has been configured for that resource, when protected Web resources are accessed.
Web containers perform the following steps to implement security of a Web application.
1. Determines whether the user has been authenticated when the protected Web resources are accessed.
2. If the user has not been authenticated yet, requests that the user provide security credentials by redirecting to the login page defined in the deployment descriptor.
3. Validates the user's credentials against the security realm configured for the container.
4. Determines whether the authenticated user is authorized to access Web resources defined in the deployment descriptor (web.xml).
In the deployment descriptor of a Web application, form-based authentication does not specify the security realm, as the basic authentication mechanism does. In other words, it does not explicitly declare the type of security realm it should use to authenticate a user. This causes some confusion as to what security realm it actually uses to authenticate the user.
Web containers perform the following steps to validate a user:
1. Determines the configured security realm for the container.
2. Uses that security realm for authentication.
Since database and LDAP provide greater flexibility in maintaining information, most organizations may want this persistence for security authentication and authorization information.
Many Web containers have support for different types of security realms: database, LDAP, and custom realm.
For example, in the Tomcat Web container, server.xml configures database as its security realm.
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
The <Realm> tag of Tomcat's server.xml defines the type of security realm that the container should use to authenticate a user. Note that the container uses this realm for Web applications whose authentication mechanism is form-based.
Note: Please see the sections on deploying database security realm support for Tomcat and WebLogic below.
Authorization
Once the user has been authenticated, the container retrieves security roles for the authenticated user and checks to see if the user belongs to one of the roles defined in the <auth-constraint> tag of the deployment descriptor. The Web container displays an error message if the user does not belong to one of roles.
The <security-constraint> tag of the deployment descriptor (web.xml) defines protected Web resources and a list of roles that have access to these Web resources.
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPages</web-resource-name>
<description> accessible by authorised users </description>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>These are the roles who have access</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
Web containers enforce authorization at a page level. However, commercial applications may also want to enforce authorization on functionalities within a single page. This may require that some additional new application-specific security roles be defined in the application. To control access to functionalities, the application needs to understand the notion of privileges for a role. The Web container specification does not address privileges.
Since authorization roles are dynamic, developers often get confused as to whether these security roles need to be added to the deployment descriptor. Web containers just need one role defined in the deployment descriptor for the application to take advantage of security support. So, the application can define one high-level role and assign all users to this role. This allows all users in this role to have access to the Web resources.
In addition, the application can define additional roles to enforce authorization on low-level functionalities within a single Web resource. These low-level security roles do not need to be in the deployment descriptor, since the application has been configured with a high-level security role that contains all of the users in the application. This allows Web applications to take advantage of container authorization support, and to implement application-specific authorization.
For example, you can define an administrator role for all of the users at a high level in the deployment descriptor to protect administration Web resources. This allows all of the users in the administrator role to access the administration pages. To control other functionalities within the administration pages, you can create new roles, such as sysadmin or appadmin, within the application.
The application can extend these security roles to have privileges. Then, the application can use these privileges to control access to its functionalities.
Despite the fact that application-specific security roles are not defined in the deployment descriptors, these roles can still be used in the isUserInRole method to determine whether the user in these security roles.
Advantages
• Web applications do not need to implement the authentication mechanism by themselves. It is simply a matter of configuring the Web application.
• Web applications can implement programmatic security using getRemoteUser, IsUserInRole, and getUserPrincipal methods.
• The Web container is capable of propagating authentication information to EJB containers.
Configuring the Database Security Realm in Tomcat
Create User Table
This table needs the username and password columns.
create table users (username varchar(20) not null, password(20) not null)
Create Role Table
This table maintains the list of roles in application. It just needs role name column in the table.
create table roles (rolename varchar(20) not null)
Create User-Role Association Table
This table maintains association between a user and roles. A user can belong to one or more roles.
create table user_roles (username varchar(20) not null, rolename varchar(20) not null)
Insert data into tables
insert into users values('user1', 'password')
insert into role values('manager')
insert into user_roles values('user1', 'manager')
Create User Table
This table needs the username and password columns.
create table users (username varchar(20) not null, password(20) not null)
Create Role Table
This table maintains the list of roles in the application. It just needs the role name column in the table.
create table roles (rolename varchar(20) not null)
Create User-Role Association Table
This table maintains association between a user and roles. A user can belong to one or more roles.
create table user_roles (username varchar(20) not null, rolename varchar(20) not null)
Insert data into tables
insert into users values('user1', 'password')
insert into role values('manager')
insert into user_roles values('user1', 'manager')
Configure Tomcat (This example uses the Oracle thin driver) by copying this information in server.xml in the {tomcat}\conf\ folder. (Tomcat uses memory realm as default realm. Comment the memory realm.)
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IP address}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
Replace the following values with environment values
{IP Address} - IP address of database server
{Port} - Port number
{Servicename} - Service name
{DB Username} - database login
{Password} - password to database login
Note: You need to have the JDBC driver for your database. (The Oracle thin driver is used in this example.)
Copy the Oracle thin driver JAR file or JDBC driver for your database (oracle_thin_driver.jar) into the {tomcat_home}/server/lib directory.
Configure the Web application deployment descriptor with security constraints.
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint><transport-guarantee>
NONE</transport-guarantee></user-data-constraint>
</security-constraint>
<!-- Default login configuration uses form-based authentication -->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/jsp/login.jsp</form-login-page>
<form-error-page>/jsp/error.jsp</form-error-page>
</form-login-config>
</login-config>
Note that the <role-name> value of this tag in <auth-constraint> should be one of the role names in the user-roles table.
Deploying The Sample Program Into Tomcat
1. Configure Tomcat using the instructions defined in the previous section.
2. Download the security-form-based.war file and copy it into Tomcat's webapps directory.
3. Start the Tomcat server.
4. Open a Web browser and go to http://{ip address:port no}/security-form-based/protected/index.jsp.
5. Type in the username and the password (user1, password).
Configuring the Database Security Realm in WebLogic
There is very good documentation on configuring the database security realm. Please refer to this link.
Configure your Web application deployment descriptor, similar to the one shown in the configuration steps for Tomcat.
One difference between Tomcat and WebLogic deployment descriptors is that the deployment descriptor for WebLogic requires the following section, while Tomcat does not require this section.
<security-role>
<description>
Manager security role
</description>
<role-name>
manager
</role-name>
</security-role>
Conclusion
This article has provided in-depth understanding of the form-based mechanism and how it works with database security realms to handle authentication. Web applications can take advantage of the form-based mechanism to protect their resources while at the same time using legacy security realms for authentication information.
In addition, this article has described the level of authorization support provided by J2EE Web containers and how you can define new security roles without modifying the deployment descriptor of a Web application
Import javax.naming .*;
Import javax.naming.directory .*;
Import java.util.Hashtable;
Class UsePool
Public static void main (String [] args) (
Hashtable env = new Hashtable (11);
Env.put (Context.INITIAL_CONTEXT_FACTORY,
"Com.sun.jndi.ldap.LdapCtxFactory");
Env.put (Context.PROVIDER_URL, "ldap: / / localhost: 389 / o = JNDITutorial");
Env.put ( "com.sun.jndi.ldap.connect.pool", "true");
Try (
DirContext ctx = new InitialDirContext (env);
System.out.println (ctx.getAttributes ( "ou = NewHires"));
/ / Do something useful with ctx
Ctx.close (); / / Return connection to pool
DirContext ctx2 = new InitialDirContext (env);
System.out.println (ctx2.getAttributes ( "ou = People"));
/ / Do something useful with ctx2
Ctx2.close (); / / Return connection to pool
) Catch (NamingException e) (
E.printStackTrace ();
)
)
)
Creation Timeout
The pool of connections maintained by the LDAP service provider may be limited in size; this is described in detail in the Connection Pooling Configuration section. When connection pooling has been enabled and no pooled connection is available, the client application will block, waiting for an available connection. You can use the"com.sun.jndi.ldap.connect.timeout" environment property to specify how long to wait for a pooled connection. If you omit this property, the application will wait indefinitely.
This same property is also used to specify a timeout period for establishment of the LDAP connection, as described in the Connection Creation section.
When Not to Use Pooling
Pooled connections are intended to be reused. Therefore, if you plan to perform operations on a Context instance that might alter the underlying connection's state, then you should not use connection pooling for that Context instance. For example, if you plan to invoke the Start TLS extended operation on a Context instance, or plan to change security-related properties (such as "java.naming.security.principal" or"java.naming.security.protocol") after the initial context has been created, you should not use connection pooling for that Context instance because the LDAP provider does not track any such state changes. If you use connection pooling in such situations, you might be compromising the security of your application
Declarative Security
Servlet containers implement declarative security. The administration is done through the deployment descriptor web.xml file. With declarative security the Servlets and JSP pages will be free from any security aware code.You can protect your URLs through web.xml as shown below:
web-app>
<security-constraint>
<web-resource-collection>
<web-resource-name>PrivateAndSensitive</web-resource-name>
<url-pattern>/private/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>executive</role-name>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<!-- form based authorization -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
</web-app>
The user will be prompted for the configured login.jsp when restricted resources are accessed. The container also keeps track of which users have been previously authenticated.
Benefits: Very little coding is required and developers can concentrate on the application they are building and system administrators can administer the security settings without or with minimal developer intervention. Let’slook at a sample programmatic security in a Web module like a servlet:
User user = new User();
Principal principal = request.getUserPrincipal();
if (request.isUserInRole("boss"))
user.setRole(user.BOSS_ROLE);
Design Pattern: JDBC architecture decouples an abstraction from its implementation so that the implementation can vary independent of the abstraction. This is an example of the bridge design pattern. The JDBC API provides the abstraction and the JDBC drivers provide the implementation. New drivers can be plugged-in to the JDBC API without changing the client code..
-----------------------------------------------------------------------------------------------------------------------------------------------Discuss EJB container security?
EJB components operate inside a container environment and rely heavily on the container to provide security. The four key services required for the security are:
• Identification: In Java security APIs this identifier is known as a principal.
• Authentication: To prove the identity one must present the credentials in the form of password, swipe card, digital certificate, finger prints etc.
• Authorisation (Access Control): Every secure system should limit access to particular users. The common way to enforce access control is by maintaining security roles and privileges.
• Data Confidentiality: This is maintained by encryption of some sort. It is no good to protect your data by authentication if someone can read the password.
The EJB specification concerns itself exclusively with authorisation (access control). An application using EJB can specify in an abstract (declarative) and portable way that is allowed to access business methods. The EJB container handles the following actions:
• Find out the Identity of the caller of a business method.
• Check the EJB deployment descriptor to see if the identity is a member of a security role that has been granted the right to call this business method.
• Throw java.rmi.RemoteException if the access is illegal.
• Make the identity and the security role information available for a fine grained programmatic security check.
public void closeAccount() {
if (ejbContext.getCallerPrincipal().getName() = “SMITH”) {
//…
}
if (!ejbContext .isCallerInRole(CORPORATE_ACCOUNT_MANAGER)) {
throw new SecurityException(“Not authorized to close this account”);
}
}
• Optionally log any illegal access.
There are two types of information the EJB developer has to provide through the deployment descriptor.
• Security roles
• Method permissions
Example:
<security-role>
<description>
Allowed to open and close accounts
</description>
<role-name>account_manager</role-name>
</security-role>
<security-role>
<description>
Allowed to read only
</description>
<role-name>teller</role-name>
</security-role>
There is a many-to-many relationship between the security roles and the method permissions.
<method-permission>
<role-name>teller</role-name>
<method>
<ejb-name>AccountProcessor</ejb-name>
<method-name>findByPrimaryKey</method-name>
</method>
</method-permission>
Just as we must declare the resources accessed in our code for other EJBs that we reference in our code we
should also declare the security role we access programmatically to have a fine grained control as shown below.
<security-role-ref>
<description>
Allowed to open and close accounts
</description>
<role-name>account_manager</role-name>
<role-link>executive</role-link>
</security-role-ref>
There is also many-to-many relationship between the EJB specific security roles that are in the deployment descriptor and the application based target security system like LDAP etc. For example there might be more than one group users and individual users that need to be mapped
to a particular EJB security role ‘account_manager’.
-----------------------------------------------------------------------------------------------------------------------------------------------J2EE Form-based Authentication
Implementing security for Web applications is a mandatory task for architects and Web application developers. In J2EE, the Web containers have support for built-in security mechanisms for their applications.
There are two major components of Web application security: authentication and authorization. J2EE-based Web containers offer three types of authentication mechanisms: basic, form-based, and mutual authentication. Most Web applications use the form-based authentication mechanism, since it allows applications to customize the authentication user interface. Web containers implement authorization on Web resources of applications, using security roles defined in the deployment descriptor of the Web application.
There are three issues that software architects and software developers come across using the form-based authentication mechanism:
• How the form-based authentication works with other security realms, such as database and LDAP (this is necessary because most organizations may already have authentication information in database or LDAP form).
• How to add or delete authorization roles declared in the deployment descriptor (web.xml) of the Web application.
• Web containers enforce authorization at Web resource level; however, an application needs to enforce authorization at its functionality level within a single Web resource.
Despite the fact that there is plenty of documentation and many examples available for form-based authentication, none of them clarifies these issues. Hence, most applications have implemented security in their own way.
This article demonstrates how the form-based authentication mechanism works with other security realms, especially the database. It also explains how Web containers use the security roles to implement authorization, and how applications can extend these security roles to protect functionalities within single resource.
Form-Based Authentication
Form-based authentication lets developers customize the authentication user interface. The login-config section of web.xml defines the type of authentication mechanism, and the URIs to login and error pages.
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>
The login form must contain fields for entering username and password. These fields must be named j_username and j_password, respectively. This form should post these values to j_security_check logical name.
Here is an example showing how the form should be coded into an HTML page:
<form method="POST" action="j_security_check">
<input name="j_username">
<input name="j_password">
</form>
This form of authentication, which uses base64 encoding, can expose username and password unless all connections are over SSL.
The Web containers activate the authentication mechanism that has been configured for that resource, when protected Web resources are accessed.
Web containers perform the following steps to implement security of a Web application.
1. Determines whether the user has been authenticated when the protected Web resources are accessed.
2. If the user has not been authenticated yet, requests that the user provide security credentials by redirecting to the login page defined in the deployment descriptor.
3. Validates the user's credentials against the security realm configured for the container.
4. Determines whether the authenticated user is authorized to access Web resources defined in the deployment descriptor (web.xml).
In the deployment descriptor of a Web application, form-based authentication does not specify the security realm, as the basic authentication mechanism does. In other words, it does not explicitly declare the type of security realm it should use to authenticate a user. This causes some confusion as to what security realm it actually uses to authenticate the user.
Web containers perform the following steps to validate a user:
1. Determines the configured security realm for the container.
2. Uses that security realm for authentication.
Since database and LDAP provide greater flexibility in maintaining information, most organizations may want this persistence for security authentication and authorization information.
Many Web containers have support for different types of security realms: database, LDAP, and custom realm.
For example, in the Tomcat Web container, server.xml configures database as its security realm.
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
The <Realm> tag of Tomcat's server.xml defines the type of security realm that the container should use to authenticate a user. Note that the container uses this realm for Web applications whose authentication mechanism is form-based.
Note: Please see the sections on deploying database security realm support for Tomcat and WebLogic below.
Authorization
Once the user has been authenticated, the container retrieves security roles for the authenticated user and checks to see if the user belongs to one of the roles defined in the <auth-constraint> tag of the deployment descriptor. The Web container displays an error message if the user does not belong to one of roles.