GWT Getting username from url only works after refresh - java

My login based application, requires to always know the username of the logged in user. (MVP) . So I'm getting the username from the url, but when the page opens after the login succeeded, I can't get the username from the url, because it does not appear to exists, but it is there. It only works after a refresh. Then I'm able to get the username.
The URL is in the form http://127.0.0.1:8888/AdministrareBloc.html#AdminPlace:admin, where I'm splitting the String to only get the admin part.
I thought this is because it downloads the code before verifying the user. So I placed a split point in my code like this: (I don't know if I placed it correctly)
loginButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
final String username = usernameBox.getText();
final String password = passwordBox.getText();
GWT.runAsync(new RunAsyncCallback() {
#Override
public void onSuccess() {
performUserConnection(username, password);
}
#Override
public void onFailure(Throwable reason) {
// TODO Auto-generated method stub
}
});
}
});
private static void performUserConnection(String username, String password) {
DBConnectionAsync rpcService = (DBConnectionAsync) GWT.create(DBConnection.class);
ServiceDefTarget target = (ServiceDefTarget) rpcService;
String moduleRelativeURL = GWT.getModuleBaseURL() + "DBConnectionImpl";
target.setServiceEntryPoint(moduleRelativeURL);
rpcService.authenticateUser(username, password, new AsyncCallback<User>() {
#Override
public void onSuccess(User user) {
if (user.getType().equals("User")) {
String username = user.getUsername();
presenter.goTo(new UserPlace(username));
} else if (user.getType().equals("Admin")) {
String username = user.getUsername();
presenter.goTo(new AdminPlace(username));
}
}
}
}
This is happening when the user clicks the login button. Is the split point placed correclty, or not ? How can I get the username without needing to refresh the page after a successful login ?
UPDATE
I've tried a trick today, placing a Window.Location.reload() inside the AdminViewImpl and UserViewImpl, and when the application starts, then the page reloads every second, so this means for me that the split point is not correclty used and the browser downloads the code before he actually needs it, and that's why I'm able to see the username after the refresh, because it redownloads the code, and I'm already logged in when I refresh.
Thanks in advance

Related

Why this if statement doesn't execute properly?

I am using Netbeans to create a login system which then gets redirected to an Account page. However I'm stuck on this if statement and need help.
private void loginBtnActionPerformed(java.awt.event.ActionEvent evt) {
String password = passWord.getText();
String username = userName.getText();
if("red".equals(password) && ("safdari".equals(username))) {
MembershipPage Account = new MembershipPage();
Account.setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "login is incorrect!");
}
}
What's expected is for another JFrame to open up after I type in the login credentials "safdari" and "red". However, for some reason that's not the case and the else statement activates instead. I'm confused new to Java btw.

Adding attributes to Wicket session

There is an implementation of WebSession, which supposed to store ID of logged user:
public class SecurityWebSession extends AuthenticatedWebSession {
public SecurityWebSession(Request request) {
super(request);
bind();
}
...
#Override
public boolean authenticate(String username, String password) {
user = usersFacadeLocal.findByEmail(username);
if (user != null) {
try {
boolean valid = PasswordHash.validatePassword(password, user.getPassword());
if (valid) {
WebSession.get().setAttribute(USER_ID, user.getId());
}
return valid;
} catch (Exception ex) {
logger.error("Authenticate ERROR", ex);
}
}
return false;
}
}
However, when I access SecurityWebSession to get ID of logged user from WebPage class, it returns null. I came across that Session does not store values which were added from its body. But it perfectly stores values if set them from classes inherited from Wicket's WebPage.
I did not find any mention in documentation about this situation. How can I add to Session attributes from Session?
Do you use Wicket 6.19.0 by chance?
If this is the case then you hit https://issues.apache.org/jira/browse/WICKET-5845. It is fixed in 6.20.0.
If this is not the case then please create a new ticket with a quickstart application showing the problem. Thanks!
I guess the problem lies within AuthenticatedWebSession.signIn(final String username, final String password).
This one calls your authenticate method and will destroy() and bind() your session again (this is done to avoid Session fixation).
You can however temporarily store the values you need by overriding replaceSession():
// this will be called *after* a successful authenticate
#Override
public void replaceSession() {
//temp store any values you want to carry over to the new session...
super.replaceSession();
//reset them to the session after super.replaceSession();
}

Parse Google plus login

I am using Parse, where are users are able to login using Facebook, Twitter, and Google+. As of now, only Facebook and Twitter is fully functional.
I have managed to login using Facebook and Twitter in the following way:
private void onLoginButtonClicked() {
LoginActivity.this.progressDialog = ProgressDialog.show(
LoginActivity.this, "", "Logging in...", true);
List<String> permissions = Arrays.asList("public_profile", "user_about_me",
"user_relationships", "user_birthday", "user_location");
ParseFacebookUtils.logIn(permissions, this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
LoginActivity.this.progressDialog.dismiss();
if (user == null) {
Log.d(IntegratingFacebookTutorialApplication.TAG,
"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d(IntegratingFacebookTutorialApplication.TAG,
"User signed up and logged in through Facebook!");
showUserDetailsActivity();
} else {
Log.d(IntegratingFacebookTutorialApplication.TAG,
"User logged in through Facebook!");
moodpage();
}
}
});
}
private void onTwitterButtonClicked() {
ParseTwitterUtils.logIn(this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
if (user == null) {
Log.d("MyApp", "Uh oh. The user cancelled the Twitter login.");
} else if (user.isNew()) {
Log.d("MyApp", "User signed up and logged in through Twitter!");
showUserDetailsActivity();
} else {
Log.d("MyApp", "User logged in through Twitter!");
moodpage(); }
}
});
}
I am trying to figure out to achieve this with Google+ through parse. Someone has suggested for me to look into Parse Rest API, however, I am not familiar with it, and need more guidance.
Any clarification will be appreciated.
as per this:
http://blog.parse.com/announcements/adding-third-party-authentication-to-your-web-app/
and this:
https://parse.com/tutorials/adding-third-party-authentication-to-your-web-app
And my understanding of them
You just need to generate a password using some algorithm in your app or your cloud/backend, after successfully logging in with Google+ / Github / Whatever
a simeple implementation (but it's not secured to have it in your app):
// given Google Plus login (Using their Api) i.e. no Parse yet at this point
int id = 12345; // assume that this is google+ id (After successfully logging in)
ParseUser user = new ParseUser();
user.setUsername("google-plus-" + String.valueOf(id));
user.setPassword(hashMyPassword(id)); // Create password based on the id
user.setEmail("email.from.google.plus.login#gmail.com");
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// Hooray! Let them use the app now.
} else {
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
One important thing about this solution:
It's not secured to just use the id / password based on the id in your app, a better solution would be to send Google+ Token / UserId to backend/cloud then the Backend/Cloud verifies that this Token/Id are valid, then create the username/password out of it and exchange it with Parse User.
I hope you got the Idea.

How to keep flash when redirecting to the login page

I'm implementing an email mechanism in Play:
User gets an email with a validation link
Clicks on it, gets to a controller that saves the "validated" bit on the user model, then redirects him to another page.
Before redirecting, that last page puts a message into the flash object ... to be displayed later in whatever page the user ends up at, via javascript. The message says "thanks for validating your email".
The target page has #With(Secure.class), so if the user is not authenticated I reach the Secure.login() method.
Now, at this point, I find that flash does not contain the message I just put in there before the redirection. What is the correct way to use flash in a way that survives this redirect?
This seems to work:
public class OurSecure extends Controller {
#Before(unless={"login", "authenticate", "logout"})
static void checkAccess() throws Throwable {
// Authent
if(!session.contains("username")) {
// __ my modification __ :
flash.keep();
flash.put("url", "GET".equals(request.method) ? request.url : "/");
// seems a good default
login();
}
...
}
hmm... well, its a slightly different use case, but thats the way how I remember which page the user wanted to access when he got redirected to the login page, so I can redirect him back there after successful authentication. maybe it helps
#Before(only = "authenticate")
public static void preserveUrl()
{
String url = request.params.get("url");
if(
"authenticate".equals(request.actionMethod) &&
url != null &&
!url.toLowerCase().contains("http") &&
!url.toLowerCase().contains("ftp")
)
{
flash.put("url", url);
}
}
static boolean authenticate(String username, String password) {
if(username == null || password == null)
return false;
String passwordHash = Codec.hexMD5(password.trim());
Member m = Member.findByEmailAddressPasswordHashAndStatus(username, passwordHash, Member.STATUS.ACTIVE);
return m != null;
}

variables in the flash scope don't stay alive in Google Chrome

When a user tries to access a page in the administration controllers (mostly CRUD stuff), he is being redirected to the login page. And, if the credentials is correct and he is indeed an administrator, he is begin redirected to the page he wanted to access in the previous request.
Whenever someone tries to access a forbidden page he is being redirected to the following controller:
public static void login(String returnUrl) throws Throwable {
Http.Cookie remember = request.cookies.get("rememberme");
flash.put("url",returnUrl);
if (remember != null && remember.value.indexOf("-") > 0) {
String sign = remember.value.substring(0, remember.value.indexOf("-"));
String username = remember.value.substring(remember.value.indexOf("-") + 1);
if (Crypto.sign(username).equals(sign)) {
session.put("username", username);
redirectToOriginalURL(returnUrl);
}
}
flash.keep();
render();
}
Which executes the authenticte(...) method:
public static void authenticate(#Required String username, String password, boolean remember, String returnUrl) throws Throwable {
// Check tokens
Boolean allowed = false;
// This is the official method name
allowed = (Boolean) Security.invoke("authenticate", username, password);
if (validation.hasErrors() || !allowed) {
flash.keep("url");
flash.error("secure.error");
params.flash();
login(returnUrl);
}
// Mark user as connected
session.put("username", username);
// Remember if needed
if (remember) {
response.setCookie("rememberme", Crypto.sign(username) + "-" + username, "30d");
}
// Redirect to the original URL (or /)
flash.keep("url");
redirectToOriginalURL(returnUrl);
}
Note the String returnUrl in the parameter list. This controller is always called in the view with the response.url value.
The redirectToOriginalURL() is a method that receives a returnUrl in the parameter or in the flash scope.
static void redirectToOriginalURL(String returnUrl) throws Throwable {
if(returnUrl==null) returnUrl = flash.get("url");
if (returnUrl == null) {
returnUrl = "/";
}
redirect(returnUrl);
}
This works fine in Firefox and Internet Explorer. But when I try to execute this in Google Chrome, the returnUrl is null. Is this a known issue, or am I doing something terribly wrong?
There are no special requests or anything. The url, when redirected from the unaccessible page (localhost:9000/admin) is http://localhost:9000/account?returnUrl=%2Fadmin. So nothing wrong there...
The error must therefore lie withing the authenticate controller, that seems to be unable to pass arguments to the redirectToOriginalURL method. But, then again, only in Google Chrome.
Suggestions?
I got it working this way:
Make sure that checkAccess method calls login method with current url:
static void checkAccess() throws Throwable {
// Authent
if (!session.contains("username")) {
login(request.method.equals("GET") ? request.url : "/");
}
}
Then in login.html view add the hidden field which is the param you already passed to login method:
#{form #authenticate()}
<input type="hidden" name="returnUrl" value="${params.returnUrl}">
...
#{/form}
Or add returnUrl param directly to form.action:
#{form #authenticate().add("returnUrl", params.returnUrl)}
That's it. And you don't need flash scope.
I noticed this line of code in login:
redirectToOriginalURL();
That calling the method with no arguments, but the redirectToOriginalURL you show has a parameter String. Could it be this is part of the issue?

Categories