I've been trying to roll my own authentication as a stepping stone to doing proper authentication (via J2EE authentication or Shiro) later on. However I'm having a problem in that when my users log in, they all log into the same session. I can see the data is the same and the jsessionid matches also in Chrome dev tools.
I can't create a session if it already exists and if I invalidate it it will simply invalidate the other users session since they are the same, so I'm not sure how to get around that. Any advice would be welcome.
This is my Login view bean:
@ManagedBean
@RequestScoped
public class LoginView implements Serializable {
private static final long serialVersionUID = -2871644685227380013L;
private String username;
private String password;
@EJB
private myApp.ejb.LoginRequest request;
private static final Logger logger = Logger.getLogger("myApp.ejb.LoginView");
public String getUsername() {
return username;
}
public void setUsername(String userName) {
this.username = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes("UTF-8"));
byte byteData[] = md.digest();
//convert the byte to hex format
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
this.password = sb.toString();
}
public void login(ActionEvent event) {
RequestContext requestContext = RequestContext.getCurrentInstance();
FacesContext context = FacesContext.getCurrentInstance();
boolean loggedIn = false;
User user = request.findUser(username);
if(user.getPassword().equals(this.getPassword()))
{
loggedIn = true;
context.getExternalContext().getSession(false);
context.getExternalContext().getSessionMap().put("user", user);
logger.log(Level.INFO, "put user {0}",
new Object[]{user.getUserId()});
logger.log(Level.INFO, "session id {0}",
new Object[]{context.getExternalContext().getSessionId(false)});
requestContext.addCallbackParam("loggedIn", loggedIn);
}
}
}
And this is my login.xhtml form and callback:
<h:form>
<h:outputLink value="javascript:void(0)" onclick="PF('dlg').show();" title="login">
<p:graphicImage name="/demo/images/login.png" />
</h:outputLink>
<p:dialog header="Login" widgetVar="dlg" resizable="false">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="username" value="Username:" />
<p:inputText id="username" value="#{loginView.username}" required="true" label="username" />
<h:outputLabel for="password" value="Password:" />
<p:password id="password" value="#{loginView.password}" required="true" label="password" />
<f:facet name="footer">
<p:commandButton value="Login" actionListener="#{loginView.login}"
oncomplete="handleLoginRequest(xhr, status, args)" />
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>
<script type="text/javascript">
function handleLoginRequest(xhr, status, args) {
if(args.validationFailed || !args.loggedIn) {
PF('dlg').jq.effect("shake", {times:5}, 100);
}
else {
PF('dlg').hide();
$('#loginLink').fadeOut();
window.location = "http://localhost:8080/myapp/index.xhtml"
}
}
</script>