Complete configuration of JAAS with JBOSS using database
843811Oct 9 2003 — edited Dec 6 2003JAAS Configuration
1. Database
Create following table:
a. Principals table consists of usernames (PrincipalID) and their passwords.
CREATE TABLE Principals (PrincipalID VARCHAR (64) PRIMARY KEY,
Password VARCHAR (64))
Insert data
INSERT INTO Principals VALUES ('java', 'echoman')
INSERT INTO Principals VALUES ('duke', 'javaman')
b. Roles table consists of usernames (PrincipalID) and their Role and the
RoleGroup they belong.
CREATE TABLE Roles (PrincipalID VARCHAR (64), Role
VARCHAR (64), RoleGroup VARCHAR (64))
Insert data
INSERT INTO Roles VALUES ('java', 'Echo', 'Roles')
INSERT INTO Roles VALUES ('java', 'caller_java', 'CallerPrincipal')
INSERT INTO Roles VALUES ('duke', 'Java', 'Roles')
INSERT INTO Roles VALUES ('duke', 'Coder', 'Roles')
INSERT INTO Roles VALUES ('duke', 'caller_duke', 'CallerPrincipal')
INSERT INTO Roles VALUES ('duke', 'Echo', 'Roles')
2. login-config.xml
This file is located in jboss-3.2.1\server\default\conf
a. add the following lines
<application-policy name="example2">
<authentication>
<login-module code="org.jboss.security.ClientLoginModule" flag="required">
</login-module>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
flag="required">
<module-option name="managedConnectionFactoryName">
jboss.jca:service=LocalTxCM,name=SybaseDB
</module-option>
<module-option name="dsJndiName">
java:/SybaseDB
</module-option>
<module-option name="principalsQuery">
Select Password from Principals where PrincipalID =?
</module-option>
<module-option name="rolesQuery">
Select Role 'Roles', RoleGroup 'RoleGroups' from Roles where PrincipalID =?
</module-option>
</login-module>
</authentication>
</application-policy>
3. jboss-web.xml
Create a file jboss-web.xml and place the following code
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>java:/jaas/example2</security-domain>
</jboss-web>
example2 is the name of the security domain which we specified in application policy of login-config.xml
Copy this file in your applications WEB-INF folder
4. auth.conf
Create a file auth.conf and place it in jboss-3.2.1\client.
client-login
{
org.jboss.security.ClientLoginModule required;
};
example2
{
org.jboss.security.ClientLoginModule required;
org.jboss.security.auth.spi.DatabaseServerLoginModule required;
};
5. auth.conf
Create another auth.conf and place it in jboss-3.2.1\server\default\conf
// The JBoss server side JAAS login config file for the examples
client-login
{
org.jboss.security.ClientLoginModule required;
};
example2
{
org.jboss.security.ClientLoginModule required;
org.jboss.security.auth.spi.DatabaseServerLoginModule
required
dsJndiName="java:/SybaseDB"
principalsQuery="Select Password from Principals where PrincipalID =?"
rolesQuery="Select Role 'Roles', RoleGroup 'RoleGroups' from Roles where PrincipalID =?"
;
};
5. jndi
Path jboss-3.2.1\server\default\conf
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
# Do NOT uncomment this line as it causes in VM calls to go over
# RMI!
java.naming.provider.url=localhost:1099
#localhost
6. web.xml
Place the following code in your web.xml.(Change it according to your application requirements).
<security-constraint>
<web-resource-collection>
<web-resource-name>action</web-resource-name>
<description>Declarative security tests</description>
<url-pattern>*.do</url-pattern>
<http-method>HEAD</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
// the role which can access these resources
<auth-constraint>
<role-name>Echo</role-name>
<!--<role-name>Java</role-name>-->
</auth-constraint>
<user-data-constraint>
<description>no description</description>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
//the login page in case of Basic authentication
<!--<login-config>
<auth-method>BASIC</auth-method>
<realm-name>JAAS Tutorial Servlets</realm-name>
</login-config>-->
//the login page in case of form based authentication
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/logon.do</form-login-page> //path to login page
<form-error-page>/logoff.do</form-error-page> //path in case login fails
</form-login-config>
</login-config>
<security-role>
<description>A user allowed to invoke echo methods</description>
<role-name>Echo</role-name>
</security-role>
<!--
<security-role>
<description>A user allowed to invoke echo methods</description>
<role-name>Java</role-name>
</security-role>
-->
7. login.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page language="java" %>
<html >
<HEAD>
<TITLE></TITLE>
<!-- To prevent caching -->
<%
response.setHeader("Cache-Control","no-cache"); // HTTP 1.1
response.setHeader("Pragma","no-cache"); // HTTP 1.0
response.setDateHeader ("Expires", -1); // Prevents caching at the proxy server
%>
<SCRIPT>
function submitForm() {
var frm = document. logonForm;
// Check if all the required fields have been entered by the user before
// submitting the form
if( frm.j_username.value == "" ) {
alert("blank");
frm.j_username.focus();
return ;
}
if( frm.j_password.value == "" ) {
alert("blank");
frm.j_password.focus();
return ;
}
frm.submit();
}
</SCRIPT>
</HEAD>
<BODY>
<FORM name="logonForm" action="logon.do" METHOD=POST>
<TABLE width="100%" border="0" cellspacing="0" cellpadding=
"1" bgcolor="white">
<TABLE width="100%" border="0" cellspacing=
"0" cellpadding="5">
<TR align="center">
<TD align="right" class="Prompt"></TD>
<TD align="left">
<INPUT type="text" name="j_username" maxlength=20>
</TD>
</TR>
<TR align="center">
<TD align="right" class="Prompt"> </TD>
<TD align="left">
<INPUT type="password"
name="j_password" maxlength=20 >
<BR>
<TR align="center">
<TD align="right" class="Prompt"> </TD>
<TD align="left">
<input type="submit" onclick="javascript:submitForm();" value="Login">
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</html>
8. Your action class should contain the following code
a. Pacakages to be imported
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.callback.SecurityAssociationHandler;
try
{
SecurityAssociationHandler handler = new
SecurityAssociationHandler();
user = new SimplePrincipal(username);
handler.setSecurityInfo(user, password.toCharArray());
LoginContext loginContext = new LoginContext("example2",
(CallbackHandler)handler);
loginContext.login();
Subject subject = loginContext.getSubject();
Set principals = subject.getPrincipals();
principals.add(user);
}catch(LoginException e)
{ errors.add("loginerror", new ActionError("Wrong Username or Password")); saveErrors(request, errors);
}
//other login related code