package
com.test.secure;
import
java.io.IOException;
import
java.security.Principal;
import
java.sql.Connection;
import
java.sql.DriverManager;
import
java.sql.PreparedStatement;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.util.ArrayList;
import
java.util.List;
import
java.util.Map;
import
javax.security.auth.Subject;
import
javax.security.auth.callback.Callback;
import
javax.security.auth.callback.CallbackHandler;
import
javax.security.auth.callback.NameCallback;
import
javax.security.auth.callback.PasswordCallback;
import
javax.security.auth.callback.UnsupportedCallbackException;
import
javax.security.auth.login.LoginException;
import
javax.security.auth.spi.LoginModule;
import
org.apache.log4j.Logger;
public
class
TestLoginModule
implements
LoginModule {
Logger logger = Logger.getLogger(TestLoginModule.
class
);
public
static
String USER_QUERY =
"select user_name from users where user_name=? and user_pass=?"
;
public
static
String ROLE_QUERY =
"select role_name from user_roles where user_name=?"
;
private
Subject subject;
private
CallbackHandler callbackHandler;
private
Map sharedState;
private
Map options;
private
boolean
debug =
false
;
private
boolean
succeeded =
false
;
private
boolean
commitSucceeded =
false
;
private
String username =
null
;
private
char
[] password =
null
;
private
TestUserPrincipal testUserPrincipal;
private
TestRolePrincipal testRolePrincipal;
private
TestPasswordPrincipal testPasswordPrincipal;
@Override
public
void
initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this
.subject = subject;
this
.callbackHandler = callbackHandler;
this
.sharedState = sharedState;
this
.options = options;
}
@Override
public
boolean
login()
throws
LoginException {
if
(callbackHandler ==
null
) {
throw
new
LoginException(
"call back handler is null"
);
}
Callback[] callbacks =
new
Callback[
2
];
callbacks[
0
] =
new
NameCallback(
"username"
);
callbacks[
1
] =
new
PasswordCallback(
"password: "
,
false
);
try
{
callbackHandler.handle(callbacks);
username = ((NameCallback) callbacks[
0
]).getName();
password = ((PasswordCallback) callbacks[
1
]).getPassword();
if
(username ==
null
|| password ==
null
) {
throw
new
LoginException(
"Callback handler does not return login data properly"
);
}
logger.info(
" username"
+ username);
logger.info(
"password"
+ password);
if
(isValidUser()) {
succeeded =
true
;
return
true
;
}
}
catch
(IOException e) {
e.printStackTrace();
}
catch
(UnsupportedCallbackException e) {
e.printStackTrace();
}
return
false
;
}
@Override
public
boolean
commit()
throws
LoginException {
logger.info(
"committing..."
);
if
(succeeded ==
false
) {
return
false
;
}
else
{
testUserPrincipal =
new
TestUserPrincipal(username);
if
(!subject.getPrincipals().contains(testUserPrincipal)) {
subject.getPrincipals().add(testUserPrincipal);
}
List roles = getRoles(testUserPrincipal);
for
(String role : roles) {
testRolePrincipal =
new
TestRolePrincipal(role);
if
(!subject.getPrincipals().contains(testRolePrincipal)) {
subject.getPrincipals().add(testRolePrincipal);
}
}
commitSucceeded =
true
;
logger.info(
"Login subject were successfully populated with principals and roles"
);
logger.info(
"--------------principals"
);
logger.info(subject.getPrincipals());
for
(Principal p: subject.getPrincipals()){
if
(p
instanceof
TestRolePrincipal){
logger.info(
" ROLE: "
+p.getName());
}
}
return
true
;
}
}
@Override
public
boolean
abort()
throws
LoginException {
if
(succeeded ==
false
) {
return
false
;
}
else
if
(succeeded ==
true
&& commitSucceeded ==
false
) {
succeeded =
false
;
username =
null
;
if
(password !=
null
) {
password =
null
;
}
testUserPrincipal =
null
;
}
else
{
logout();
}
return
true
;
}
@Override
public
boolean
logout()
throws
LoginException {
subject.getPrincipals().remove(testUserPrincipal);
succeeded =
false
;
succeeded = commitSucceeded;
username =
null
;
if
(password !=
null
) {
for
(
int
i =
0
; i < password.length; i++) {
password[i] =
' '
;
password =
null
;
}
}
testUserPrincipal =
null
;
return
true
;
}
private
boolean
isValidUser()
throws
LoginException {
Connection connection =
null
;
ResultSet rs =
null
;
PreparedStatement stmt =
null
;
try
{
connection = getConnection();
stmt = connection.prepareStatement(USER_QUERY);
stmt.setString(
1
, username);
stmt.setString(
2
,
new
String(password));
rs = stmt.executeQuery();
if
(rs.next()) {
return
true
;
}
}
catch
(Exception e) {
logger.error(
"Error when loading user from the database "
+ e);
e.printStackTrace();
}
finally
{
try
{
rs.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing result set."
+ e);
}
try
{
stmt.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing statement."
+ e);
}
try
{
connection.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing connection."
+ e);
}
}
return
false
;
}
private
List getRoles(TestUserPrincipal user) {
Connection connection =
null
;
ResultSet rs =
null
;
PreparedStatement stmt =
null
;
List roleList =
new
ArrayList();
try
{
connection = getConnection();
stmt = connection.prepareStatement(ROLE_QUERY);
stmt.setString(
1
, username);
rs = stmt.executeQuery();
while
(rs.next()) {
roleList.add(rs.getString(
"role_name"
));
user.addRole(
new
TestRolePrincipal((rs.getString(
"role_name"
))));
}
}
catch
(Exception e) {
logger.error(
"Error when loading user from the database "
+ e);
e.printStackTrace();
}
finally
{
try
{
rs.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing result set."
+ e);
}
try
{
stmt.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing statement."
+ e);
}
try
{
connection.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing connection."
+ e);
}
}
return
roleList;
}
private
Connection getConnection() {
try
{
Class.forName(
"com.mysql.jdbc.Driver"
);
return
DriverManager.getConnection(
}
catch
(Exception e) {
e.printStackTrace();
}
return
null
;
}
}