We have a Wildfly 10 JEE application and a java fat client that uses remote EJ calls to communicate with the server. Authentication is done using a custom login module in the wildfly server.
Now we have the requirement to enhance this login module with the concept of a password expiration. Whenever a password expires the user has to change its password during the login process. The login module uses JAAS callbacks and the JAAS callback handler. As far as I've understood we could use the javax.security.auth.callback.TextInputCallback in our LoginModule to request the new password from the user while performing the login.
How does this integrate with remoting. How does our fat client receive the TextInputCallback to provide the requested input? I guess we have to register a custom CallbackHandler on client side that processes the callbacks but I have not found any documentation on how to do this with Wildfly. Can anybody give me a hint on such documentation or a sample on how to solve this problem?
In my opinion you are going towards the wrong direction. Using your approach of putting the password change into the LoginModule has some issue.
TextInputCallback
to ask for a new passport is at least strange.
The TextInputCallback
is meant to ask the user for regular text not for a password for example a second authentication factor like a (timebased) PIN
A client implementing a CallbackHandler
does not know that it's a password which may has has to be masked when shown on the scren.Keep in mind that usually for a password change you need an authenticated / authorized user which has to confirm the password change by re-entering his old password
and which usually also provides a second field where the user can re-enter his new password. Just one xxxCallback
seems not be enough.
Even one should not use Exceptions
for control flows I'd suggest to use a CredentialExpiredException
to signal the client that the user has to change
the password. This is also the way Oracle does it in one of the WebLogic JAAS Examples
After all my remarks if you still want / need to put it into the custom LoginModule
then I'd suggest to define your own custom Callback
s
for example PasswordChangeCallback
or ConfirmPasswordCallback
, NewPasswordCallback
, VerifyNewPasswordCallback
You can simply add them to custom LoginModule
there is no need to register them. Keep in mind that standard clients may have problems whith these additional callbacks.
Your client then has to implement a the corresponding CallbackHandler
.
In JAAS there are two ways to customise the used CallbackHander
* by configuring a custom default CallbackHandler
From the CallbackHandler API documentaion
A default CallbackHandler class implementation may be specified in the auth.login.defaultCallbackHandler security property. The security property can be set in the Java security properties file located in the file named /lib/security/java.security. refers to the value of the java.home system property, and specifies the directory where the JRE is installed.
or by passing as argument to the constructor of the LoginContext
.
The LoginContext
provides two constructors which accept a CallbackHandler
public LoginContext(String name, CallbackHandler callbackHandler)
throws LoginException
public LoginContext(String name, Subject subject,
CallbackHandler callbackHandler) throws LoginException
see LoginContext API Documentation
How does it integrate with removing?
It should be the same way as you already do it. There is not much difference.
How does our fat client receive the
TextInputCallback
?
Via CallbackHandler
Interface similar to the PasswordCallback
. You've mentioned that the Login Module uses the CallbackHandler
.
void handle(Callback[] callbacks)
If you want to know how to implement the handle
method the CallbackHandler
API Documentation also provides an example of an implementation of the CallbackHandler
handle
method.