Allowing users to log on with changable credentials

I wanted to allow users to connect to OpenFire (formerly Wildfire) with a username that is changeable. In my use case, users are not supposed to be exposed to their JID. My application presents users with a box for email and password. Email is then mapped to a valid JID node. For example, user@domain.com is mapped to something like user%domain.com and then the client tries to authenticate with OpenFire as user%domain.com@xmpp.server.domain with the password provided.

Now the issue is that the user can change the email associated with her Account at will. The primary key for the account is a simple number. So my goal was for a user authenticating as user%domain.com@xmpp.server.domain whose account number is 1234 to then be connected as 1234@xmpp.server.domain so that there is a constant jid that never changes even when the user’'s email is changed.

I use a custom AuthProvider and custom UserProvider. The UserProvider.loadUser() method is implemented so that it will load a user either by the variable credential (ie. the mapped email address) or the constant primary key (the account number). The Users it returns alway return the primary key (the account number) for calls to getUsername().

The issue I had was that OpenFire’'s AuthFactory.authenticate(String username, String password) function assumes that the username a user authenticates with is the JID node as which he should be connected.

Original

Wildfire 3.2.2 AuthFactory.authenticate(String username, String password) :

public static AuthToken authenticate(String username, String password)

throws UnauthorizedException

{

authProvider.authenticate(username, password);

return new AuthToken(username);

}


I modified the authenticate() method so that it returns an AuthToken with the results of the authenticated User’'s

getUsername() method instead of returning the AuthToken with the original username argument.

New:

public static AuthToken authenticate(String username, String password)

throws UnauthorizedException

{

authProvider.authenticate(username, password);

User user;

try {

user = UserManager.getInstance().getUser(username);

} catch (UserNotFoundException ex) {

throw new UnauthorizedException(“Authentication succeed, but failed to load user”);

}

return new AuthToken(user.getUsername());

}


I’‘m not familiar enough with XMPP specs to know if this behavior breaks the spec. Assuming it doesn’‘t, such a change would enable users to gain the behavior I’'ve described, allowing users to login with some sort of identifier not necessarily static or with any relationship to their JID by simply implementing an AuthProvider and UserProvider with the appropriate behavior.

Your thoughts, comments and criticism would be most appreciated!