
In this post, we will demonstrate how to configure custom login on wildfly by using JAAS. Wildfly provides most common use for login method such as database, LDAP or even flat file. But in the practical situation, there are some requirements that need to combine or customize logic procedure, for example, using multiple source of user management systems, using NO-SQL database for user management, connecting with the legacy system to perform user authentication, etc. To meet these requirement, customize logic mechanism in application server is required. Fortunately, Wildfly also provide module to customize login. In this example, we will customize login module by using LDAP to verify the user and check the password in relational database, below I show how I have setup my environment.
![]() |
Fig 01 Authentication Scheme |
Create Custom Login Module
To customize login mechanism, first we need to create EJB project and create login class that extend UsernamePasswordLoginModule class. In our environment set up, we will use two data sources to implement user authentication. First, I will use MongoDB to maintain username and password along with roles. But you could use combination such as
- LDAP - To validate username and role.
- Mongodb - For validate associated with the user.
In order to create custom login, first we need to create custom module. Wildfly custom module is simply JAR file. So first, we need to create Java SE project for the custom login module as following.
Create Data in MongoDB
In post, I'll explain how to use MongoDB for authentication and authorization. For password encryption, we use sha-256 encryption package in WILDFLY
$java -cp $JBOSS_HOME/modules/system/layers/base/org/picketbox/main/picketbox-4.9.6.Final.jar org.jboss.security.Base64Encoder password SHA-256 [L1yCd6L0X8BZ8WJuP4P1xW+r6s6Sj1hNJmhBEMUZL48=]
Next is to create user document and collection in MongoDB. We use as below collection to maintain user document.
{
"_id": {
"$oid": "5f4526ff14eedfb847111bdf"
},
"tbl": "usrtbl",
"userid": 1,
"username": "admin01",
"passwd": "L1yCd6L0X8BZ8WJuP4P1xW+r6s6Sj1hNJmhBEMUZL48=",
"firstname": "firstname",
"lastname": "lastname",
"status": "A",
"createdate": {
"$date": "2020-08-24T17:00:00.000Z"
}
}
for Role we will use as following
{
"_id": {
"$oid": "5f452c7314eedfb847111be1"
},
"tbl": "roletbl",
"roleid": 1,
"rolename": "Operator",
"roledesc": "Operator Role",
"status": "A",
"createdate": {
"$date": "2020-08-24T17:00:00.000Z"
}
}
One more collection for role detail we need to maintain is show as below
{
"_id": {
"$oid": "5f452a2214eedfb847111be0"
},
"tbl": "usr_role_tbl",
"roleid": 1,
"userid": 1
}
Next step is to create custom module that could access those database.
Create Java Project
First, we create Java SE Project in Eclipse.
|
Fig 02 Create Java SE Project |
Fig 02 Create
Java Project |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>pro.tikkwiki.jaas</groupId> <artifactId>java-se-06-jaas</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.5.0</version> </dependency> <!-- log4j dependency --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.1</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
Then create java class for MongoDB Connection.
package pro.tikwiki.jaas.util; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import org.apache.log4j.Logger; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; public class MongoConnector { private static Logger log = Logger.getLogger(MongoConnector.class); // Mongodb initialization parameters. private static final int port_no = 1234; private static final String auth_user="admin", auth_pwd = "password", host_name = "localhost"; public static MongoClient getConnnection() { String encoded_pwd = ""; /* Imp. Note - * 1. Developers will need to encode the 'auth_user' or the 'auth_pwd' string if it contains the <code>:</code> or the <code>@</code> symbol. If not, the code will throw the <code>java.lang.IllegalArgumentException</code>. * 2. If the 'auth_user' or the 'auth_pwd' string does not contain the <code>:</code> or the <code>@</code> symbol, we can skip the encoding step. */ try { encoded_pwd = URLEncoder.encode(auth_pwd, "UTF-8"); } catch (UnsupportedEncodingException ex) { log.error(ex); } // Mongodb connection string. String client_url = "mongodb://" + auth_user + ":" + encoded_pwd + "@" + host_name + ":" + port_no; //+ "/" + db_name; MongoClientURI uri = new MongoClientURI(client_url); // Connecting to the mongodb server using the given client uri. MongoClient mongoClient = new MongoClient(uri); return mongoClient; } }
Then we need to create entity class for User and Role object.
package pro.tikwiki.jaas.entity;
public class User {
private int userid;
private String username;
private String passwd;
private String firstname;
private String lastname;
private String status;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
For Role Class, we will create as below.
package pro.tikwiki.jaas.entity;
public class Role {
private int roleId;
private String roleName;
private String roleDesc;
private String status;
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
And for user-role object, we create UserRole class as below.
package pro.tikwiki.jaas.entity;
public class UserRole {
private int userId;
private int roleId;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
}
Following step is to create data access object. In case, I have created 3 data access objects along with its interface.
package pro.tikwiki.jaas.dao;
import pro.tikwiki.jaas.entity.User;
public interface UserDao {
public User getUser(String username);
}
For UserDao implementation class
package pro.tikwiki.jaas.dao;
import org.apache.log4j.Logger;
import org.bson.Document;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import pro.tikwiki.jaas.entity.User;
import pro.tikwiki.jaas.util.MongoConnector;
public class UserDaoImp implements UserDao {
private static Logger logger = Logger.getLogger(MongoDaoImp.class);
private MongoClient mongo_client = MongoConnector.getConnnection();
@Override
public User getUser(String username) {
String db_name = "db01";
String db_col_name = "usrcol";
// Fetching the database from the mongodb.
MongoDatabase db = mongo_client.getDatabase(db_name);
// Fetching the collection from the mongodb.
MongoCollection<Document> coll = db.getCollection(db_col_name);
logger.debug("Fetching all documents from the collection");
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("tbl", "usrtbl");
whereQuery.put("username", username);
FindIterable<Document> fi = coll.find(whereQuery);
MongoCursor<Document> cursor = fi.iterator();
User user = null;
try {
while(cursor.hasNext()) {
user = new User();
Document doc = cursor.next();
user.setUserid(doc.getInteger("userid"));
user.setUsername(doc.getString("username"));
user.setFirstname(doc.getString("firstname"));
user.setLastname(doc.getString("lastname"));
user.setPasswd(doc.getString("passwd"));
user.setStatus(doc.getString("status"));
logger.info(doc.toJson());
}
} finally {
cursor.close();
}
return user;
}
}
we create the same for Role. First we create interface
package pro.tikwiki.jaas.dao;
import pro.tikwiki.jaas.entity.Role;
import pro.tikwiki.jaas.entity.UserRole;
public interface RoleDao {
public Role getRole(UserRole userRole) ;
}
Then create implementation of that interface.
package pro.tikwiki.jaas.dao;
import org.apache.log4j.Logger;
import org.bson.Document;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import pro.tikwiki.jaas.entity.Role;
import pro.tikwiki.jaas.entity.UserRole;
import pro.tikwiki.jaas.util.MongoConnector;
public class RoleDaoImp implements RoleDao {
private static Logger logger = Logger.getLogger(RoleDaoImp.class);
private MongoClient mongo_client = MongoConnector.getConnnection();
@Override
public Role getRole(UserRole userRole) {
String db_name = "db01";
String db_col_name = "usrcol";
// Fetching the database from the mongodb.
MongoDatabase db = mongo_client.getDatabase(db_name);
// Fetching the collection from the mongodb.
MongoCollection<Document> coll = db.getCollection(db_col_name);
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("tbl", "roletbl");
whereQuery.put("roleid", userRole.getRoleId());
FindIterable<Document> fi = coll.find(whereQuery);
MongoCursor<Document> cursor = fi.iterator();
Role role = null;
try {
while(cursor.hasNext()) {
Document doc = cursor.next();
role = new Role();
role.setRoleId(doc.getInteger("roleid"));
role.setRoleName(doc.getString("rolename"));
role.setRoleDesc(doc.getString("roledesc"));
role.setStatus(doc.getString("status"));
logger.info(doc.toJson());
}
} finally {
cursor.close();
}
return role;
}
}
Next is to create UserRoleDao Interface
package pro.tikwiki.jaas.dao;
import pro.tikwiki.jaas.entity.User;
import pro.tikwiki.jaas.entity.UserRole;
public interface UserRoleDao {
public UserRole getUserRole(User user);
}
Create UserRoleDaoImp.java as below.
package pro.tikwiki.jaas.dao;
import org.apache.log4j.Logger;
import org.bson.Document;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import pro.tikwiki.jaas.entity.User;
import pro.tikwiki.jaas.entity.UserRole;
import pro.tikwiki.jaas.util.MongoConnector;
public class UserRoleDaoImp implements UserRoleDao {
private static Logger logger = Logger.getLogger(UserRoleDaoImp.class);
private MongoClient mongo_client = MongoConnector.getConnnection();
@Override
public UserRole getUserRole(User user) {
String db_name = "db01";
String db_col_name = "usrcol";
// Fetching the database from the mongodb.
MongoDatabase db = mongo_client.getDatabase(db_name);
// Fetching the collection from the mongodb.
MongoCollection<Document> coll = db.getCollection(db_col_name);
logger.debug("Fetching all documents from the collection");
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("tbl", "usr_role_tbl");
whereQuery.put("userid", user.getUserid());
FindIterable<Document> fi = coll.find(whereQuery);
MongoCursor<Document> cursor = fi.iterator();
UserRole userRole = null;
try {
while(cursor.hasNext()) {
Document doc = cursor.next();
userRole = new UserRole();
userRole.setUserId(doc.getInteger("userid"));
userRole.setRoleId(doc.getInteger("roleid"));
logger.info(doc.toJson());
}
} finally {
cursor.close();
}
return userRole;
}
}
Lastly we create custom login module (CustomLoginModule.java) as
package pro.tikkwiki.jaas.login;
import java.security.acl.Group;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import org.apache.log4j.Logger;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
import org.jboss.security.auth.spi.Util;
import pro.tikwiki.jaas.dao.RoleDao;
import pro.tikwiki.jaas.dao.RoleDaoImp;
import pro.tikwiki.jaas.dao.UserDao;
import pro.tikwiki.jaas.dao.UserDaoImp;
import pro.tikwiki.jaas.dao.UserRoleDao;
import pro.tikwiki.jaas.dao.UserRoleDaoImp;
import pro.tikwiki.jaas.entity.Role;
import pro.tikwiki.jaas.entity.User;
import pro.tikwiki.jaas.entity.UserRole;
public class CustomLoginModule extends UsernamePasswordLoginModule {
private static Logger logger = Logger.getLogger(CustomLoginModule.class);
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,Map<String, ?> options) {
super.initialize(subject, callbackHandler, sharedState, options);
}
/**
* (required) The UsernamePasswordLoginModule modules compares the result of this
* method with the actual password.
*/
@Override
protected String getUsersPassword() throws LoginException {
logger.debug("MyLoginModule: authenticating user "+getUsername());
// Lets pretend we got the password from somewhere and that it's, by a chance, same as the username
//String password = super.getUsername();
// Let's also pretend that we haven't got it in plain text but encrypted
// (the encryption being very simple, namely capitalization)
UserDao userDao = new UserDaoImp();
User user = userDao.getUser(getUsername());
String password = user.getPasswd();
logger.info("MyLoginModule: password "+password);
return password;
}
@Override
protected boolean validatePassword(String inputPassword, String expectedPassword) {
// Let's encrypt the password typed by the user in the same way as the stored password
// so that they can be compared for equality.
if(inputPassword == null) return false;
String encryptedInputPassword = Util.createPasswordHash("SHA-256", "BASE64", null, null,inputPassword.trim());
System.out.format("Validating that (encrypted) input psw '%s' equals to (encrypted) '%s'\n"
, encryptedInputPassword, expectedPassword);
logger.info("Encrypted password "+encryptedInputPassword);
// Password check strategy: find the password from your storage (e.g. DB) and check that it's equal
// with inputPassword. We always return true, meaning password check will be skipped
boolean check = encryptedInputPassword.equals(expectedPassword);
return check;
}
/**
* (required) The groups of the user, there must be at least one group called
* "Roles" (though it likely can be empty) containing the roles the user has.
*/
@Override
protected Group[] getRoleSets() throws LoginException {
UserDao userDao = new UserDaoImp();
UserRoleDao userRoleDao = new UserRoleDaoImp();
RoleDao roleDao = new RoleDaoImp();
SimpleGroup group = new SimpleGroup("Roles");
try {
System.out.println("Search here group for user: "+super.getUsername());
User user = userDao.getUser(super.getUsername());
UserRole userRole = userRoleDao.getUserRole(user);
Role role = roleDao.getRole(userRole);
group.addMember(new SimplePrincipal(role.getRoleName()));
} catch (Exception e) {
throw new LoginException("Failed to create group member for " + group);
}
return new Group[] { group };
}
}
And for logging, we have create logging by using log4j and configure as below
<?xml version="1.0" encoding="UTF-8"?>
<log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<root>
<priority value ="debug"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>
Now, you should have as below
Fig 02 Project Structure |
Next is to create jar file and deplopy custom module in Wildfly.
Export Jar file and deploy custom Module into Wildlfy
After Creating all classes and configuring logging, we have to export those classes to jar files.
Fig 03 Export JAR file |
Fig 03 Export JAR Files |
Next is to coply created jar file (java-se-06-jass.jar) along with its dependency jar to $JBOSS_HOME/modules. Then create below folder.
$cd $JBOSS_HOME/modules
$mkdir -p mongologin/main$cd mongologin/main$vi module.xml
Next is to create module.xml file in the directory
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="mongologin">
<resources>
<resource-root path="java-se-06-jaas.jar"/>
<resource-root path="mongo-java-driver-3.12.6.jar" />
<resource-root path="jackson-annotations-2.11.1.jar" />
<resource-root path="jackson-core-2.11.1.jar" />
<resource-root path="jackson-databind-2.11.1.jar" />
<resource-root path="log4j-1.2.17.jar" />
</resources>
<dependencies>
<module name="org.picketbox"/>
<module name="javax.api"/>
</dependencies>
</module>
After create module and copy jar files, we would get as following.
Fig 05 directory detail |
Next is to edit standalone.xml to set up custom login by using custom login module.
......
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains> .....
<security-domain name="mongo-auth" cache-type="default">
<authentication>
<login-module code="pro.tikkwiki.jaas.login.CustomLoginModule" flag="required" module="mongologin"/>
</authentication>
</security-domain> .....
</security-domain>
</subsystem>
Now, we are ready to use custom login to authenticate web application.
Create Web Application and configure security Realm
First we create web application as below.
Fig 05 Create Web Application |
Then conversion web project into maven project and add dependencies in the pom.xml as below for JSF.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pro.itstikk.jaas</groupId>
<artifactId>java-ee-06-jaas-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.richfaces/richfaces -->
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>richfaces</artifactId>
<version>4.5.17.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<finalName>java-ee-06-jaas-web</finalName>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
Next is creating web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>java-ee-06-jaas-web</display-name>
<welcome-file-list>
<welcome-file>secure/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.skin</param-name>
<param-value>blueSky</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- Security configuration -->
<security-constraint>
<web-resource-collection>
<web-resource-name>SecurityFilter</web-resource-name>
<description>Application Security Constraints</description>
<url-pattern>/secure/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>Roles collection</description>
<role-name>Administrator</role-name>
<role-name>Operator</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>JAAS Authentication Realm</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/login-error.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>The Role for Administrator</description>
<role-name>Administrator</role-name>
</security-role>
<security-role>
<description>The Role for Operator</description>
<role-name>Operator</role-name>
</security-role>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/secure/error.xhtml</location>
</error-page>
</web-app>
And jboss-web.xml in WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<!-- <security-domain>java:/jaas/JDBCAuth</security-domain> -->
<security-domain>mongo-auth</security-domain>
</jboss-web>
After creating configure files. we need to create below test pages and manage bean.
package pro.itstikk.jaas.bean;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
@Named
@RequestScoped
public class SampleBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String action() {
return "fileName.xhtml";
}
}
Then we create pages as
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<link rel="icon" type="image/png" href="../img/logo.png"/>
<title>Hello World</title>
</h:head>
<body>
<rich:panel>
<f:facet name="header">
Write your own custom rich components with built-in AJAX support
</f:facet>
<div>
<h:form>
<rich:inplaceInput value="#{sampleBean.name}" defaultLabel="input value"/>
<h:commandButton action="#{sampleBean.action}" value="submit" />
</h:form>
</div>
</rich:panel>
</body>
</html>
Creating login.xhtml for login form.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<link rel="icon" type="image/png" href="img/logo.png"/>
<title>Hello World</title>
</h:head>
<body>
<rich:panel>
<f:facet name="header">
Write your own custom rich components with built-in AJAX support
</f:facet>
<div>
<h2>Login Form</h2>
<form name="loginForm" action="j_security_check" method="post">
<p>
<label for="j_username"><strong>User Name: </strong></label>
<input name="j_username" type="text"/>
</p>
<p>
<label for="j_password"><strong>Password: </strong></label>
<input name="j_password" type="password"/>
</p>
<p>
<input type="submit" value="Login"/>
<input type="reset" value="Reset"/>
</p>
</form>
</div>
</rich:panel>
</body>
</html>
Create login-error.xhtml to handle login error.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Login Error</title>
</h:head>
<body>
<rich:panel>
<f:facet name="header">
Write your own custom rich components with built-in AJAX support
</f:facet>
<div>
<h2>Login Error</h2>
<a href="/java-ee-06-jaas-web">Back</a>
</div>
</rich:panel>
</body>
</html>
Now, we test login by deploy war files in ear package and deploy to server as below.
Fig 07 Web application project |
Fig 09 testing longin |
Fig 10 login test error |
Fig 11 Login Error |
Fig 12 Login with correct |
Fig 13 Login -success |
No comments:
Post a Comment