git clone https://github.com/byorn/glassfish4-jaas
Once cloned open the project with Netbeans 8.1
Please find below the steps to create a basic custom login module in Glassfish 4.1
Step 1: Create the login page: login.jsp
<form method=post action="j_security_check" >
<span>Username:</span>
<input type="text" name= "j_username" >
<span>Password:</span>
<input type="password" name= "j_password" >
<input type="submit" value="Login" class="btn"/>
</form>
Step 2: Configure Web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>secure</web-resource-name>
<url-pattern>/secure/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>admin</role-name>
</security-role>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>myCustomRealm</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
If you checked out the project source you can see a folder called /secure/index.jsp.
This page can be accessed only if the logged in user has the role 'admin'
Notice that, the welcome page:
<welcome-file-list><welcome-file>secure/index.jsp</welcome-file>
</welcome-file-list>
is pointing to this secure page. Once the user tries to call this page from the browser, the system
will prompt the login.jsp page, asking the user to login first.
Notice: the myCustomRealm. This will be mentioned in the next few steps. Basically, later on we create a custom Realm called myCustomRealm, which actually points to JAR file..(The login module) that you are about to create.
Step 3: configure Sun-web.xml or glassfish-web.xml
These entries need to be present in your sun-web.xml. It could be glassfish-web.xml also, depending on how you created your web module in Netbeans.
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
</security-role-mapping>
Step 4: Build the Login Module
You need to create two files.
1) A LoginModule that extends com.sun.appserv.security.AppservPasswordLoginModule
2) A Realm which extends com.sun.appserv.security.AppservRealm;
In order to get these files, you need to import the following JARS to your project
* glassfish-ee-api.jar
* security.jar
These Jars can be found in : glassfish-4.1\glassfish\modules
1) LoginModule
public class MyLoginModule extends AppservPasswordLoginModule{
public MyLoginModule() {
System.out.println("MyRealm LoginModule - Construction");
}
@Override
protected void authenticateUser() throws LoginException {
System.out.println("Going to Log In ............................");
String userString = _username;
//HERE YOU CAN GET A HANDLE TO A JDBC CONNECTION POOL IN GLASSFISH
//FROM THE JNDI NAME, AND EXECUTE A SQL TO RETRIEVE ALL THE GROUPS
//THE USER BELONGS TO
String[] groups = {"admin"};
commitUserAuthentication(groups);
}
}
In he authenticateUser() method you can get a handle to a JDBC Resource connection pool
and retrieve all the groups the user belows to.
Notice from _username and _password, you can get access to the username and password that was passed from the login page.
2) The Realm Class
public class MyRealm extends AppservRealm{
private static final String JAAS_CONTEXT="jaas-context";
@Override
public void init(Properties properties) throws BadRealmException, NoSuchRealmException {
System.out.println("Init MyRealm");
// Pass the properties declared in the console to the system
String propJaasContext=properties.getProperty(JAAS_CONTEXT);
if (propJaasContext!=null) {
setProperty(JAAS_CONTEXT, propJaasContext);
}
}
@Override
public String getAuthType() {
return "WebAuthorization";
}
@Override
public Enumeration getGroupNames(String string) throws InvalidOperationException, NoSuchUserException {
// return Collections.enumeration(getGroups());
return null;
}
}
Above is the minimal configuration needed.
Step 5 Deploy the Login Module.
The login module in \glassfish4-jaas\myjaasloginmodule\dis\myjaasloginmodule.jar should be copied to \[glassfish installation] \glassfish\domains\domain1\lib folderNote: My glassfish in netbeans is configured to run in domain1. Yours may be different.
In netbeans under services tab -> servers you can delete the galssfish server and add it again.
Here you get to specify your custom domain. If the domain you specify is 'custom_domain' then you need to put the jar file to \custom_domain\lib folder.
Step 6 Edit login.conf
Open login.conf residing in \glassfishinstallation\glassfish\domains\domain1\config
Add the below entry to the end of the file
myloginmoduleRealm {
myloginmodule.MyLoginModule required;
};
Step 7 Configure the security realm in Glassfish Admin portal
Open http://localhost:4848/
In above console, notice domain1,
notice that the security realm myCustomRealm is created under server-config and not under default-config.
Add property called jaas-context and provide the value to be myloginmoduleRealm which is actually the name mentioned in the login.conf file.
This is pretty much all you need to do. Let me know if you ran into any difficulties.
This is pretty much all you need to do. Let me know if you ran into any difficulties.
Thanks for the tutorial! However, when I try to follow get always a login failure and the following message in the server logs: "WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Invalid null input: name" Any idea what could cause the problem?
ReplyDeletehave you check the login form (step 1) the username and password fields should be j_username, and j_password?
ReplyDeleteThanks for the nice article.
DeleteI am able to do authentication successfully but not able to get j_username value in error.jsp file to display unsuccessful login attempts for a user and finally lockout the user.
Thanks for your reply! Actually I managed to solve the problem by beginning once more from scratch. But I don't know what difference made the thing now work. But well, it's working now... :-)
ReplyDeleteThanks a lot.
ReplyDeleteIt's hard to find which jar contain the AppservRealm and the login module.
In above console, notice domain1,
ReplyDeletenotice that the security realm myCustomRealm is created under server-config and not under default-config.
is the myCustomRealm created automatically???
No you have to create it by your self. myCustomRealm can be any name.
DeleteThanks Byorn this was useful
ReplyDeleteHi Byron
ReplyDeletedo you have an example of how to get the JDBC connection?
your code example does not show how....
//HERE YOU CAN GET A HANDLE TO A JDBC CONNECTION POOL IN GLASSFISH
//FROM THE JNDI NAME, AND EXECUTE A SQL TO RETRIEVE ALL THE GROUPS
//THE USER BELONGS TO
THanks, Tim
I want to get j_username value in error.jsp file
DeleteI am able to do authentication successfully but not able to get j_username value in error.jsp file to display unsuccessful login attempts for a user and finally lockout the user
ReplyDelete