Evaluating Vaadin, user authentication/session management

Hi all,

I’m looking at Vaadin for the development of internal web applications, and I have a few questions that I need to answer for myself before wholly embracing Vaadin. I’ll use separate posts for these questions.

We need each application to start with a user login. I’ve been searching around and have come across the following example:
Authenticating Vaadin-based applications

But to be honest, I don’t really understand this method. Possibly to do with the ThreadLocal stuff… I’ve also seen the (little) information available on the LoginForm class, but there seem to be a lot of limitations and problems with that, judging by the posts on this forum.

Is there an better and easier to understand method for handling user login?

Once a user has logged (using whatever method), how do you handle session time-out in Vaadin? Not seen any references to that…

Kind regards

Another option for authentication would be to use the
AppFoundation add-on
. For more information, please read
the documentation
and take a look at the
live demo of the authentication module
.

To keep it simple, if you just need to have a login and nothing else, you can skip ThreadLocal. All you need is a textfield for the user name, a “secret” text field for the password and a button. On the backend you have a method like public boolean login(String user, String pass); If login returns true you do change the view, with mainWindow.setContent(new MyVerySecretApplication()) or something similiar.

Usually just saying yes/no to if the user can log in is not enough. For that reason you will probably want to return a user object (own implemented) instead of a boolean. You can pass this object all around to access it where you want, but the ThreadLocal pattern is a great way to access some session specific data in a static way, anywhere in the application. There is another article about the threadlocal pattern on the wiki, found
here
.

About session management, what do you need? Vaadin takes care about cleaning up the session when it times out. You can also end it when ever you want with calling myApplication.close() (for a log out -button or something similar). You can also override the close-method if you need to run some own code upon close.

The ThreadLocal article in the wiki is outdated, please read
Kim’s blog post
instead.

As for the class LoginForm, it exists for one single purpose: to enable browsers to remember previously entered user names and passwords for the fields. If you don’t need that functionality, it is best to skip the class and do the login UI yourself.

Of course, if e.g. integrating the application in a portal, you probably want to use user management, authentication etc. of the portal rather than implement all of it in your application - but if that would be all you would be using from the portal, it is probably not worth the added complexity.

I’m new to Vaadin and trying to do a simple authentication. The plan was to to keep things simple at first without using ThreadLocal pattern (or is that the correct name to call it anymore) or AppFoundation. Basically just what Jens mentioned above…check the given username/password and then change the view.

I’ve read the threads about authentication at the forum and checked some examples but still facing some problems.

Here are the basics of what I have now:

public class MyApplication extends Application {
	
	@Override
	public void init() {		
		Window mainWindow = new Window("MyApp");
		setMainWindow(new Login());
	}
		
	public void loadProtectedResources(Object user) {
		if (user != null) {
			removeWindow(getMainWindow());
			setMainWindow(new ProtectedApplication());			
		}
	}
}
@SuppressWarnings("serial")
public class Login extends Window {

	private Button loginButton = new Button("login");
	private TextField txtUsername = new TextField("username");
	private TextField txtPassword = new TextField("password");
	String currentUser = null;
	
	public Login() {
		setName("login");
		createLoginForm();
	}

	private void createLoginForm() {
		txtPassword.setSecret(true);
		addComponent(new Label("Login to use the application"));
		addComponent(new Label());
		addComponent(txtUsername);
		addComponent(txtPassword);
		addComponent(loginButton);
		
		loginButton.addListener(new Button.ClickListener() {
			@Override
			public void buttonClick(ClickEvent event) {
				try {
					authenticate((String)txtUsername.getValue(), (String)txtPassword.getValue());
				} catch (Exception e) {
					showNotification(e.toString());
				}
			}
		});
	}
	
	private void authenticate(String username, String password) throws Exception {
		User user = User.setUser(username, password);
		
		if (user == null) {
			throw new Exception("Login failed!");
		} else {
			getApplication().loadProtectedResources(user);
		}
	}	
}
public class User {
	String username;
	String password;

	public User(String username, String password) {
		this.username = username;
		this.password = password;
	}
	
	static public User setUser(String username, String password) {
		if ("user".equals(username) && "pass".equals(password)) {
			User u = new User(username, password);
			return u;
		}	
		return null;
	}
	
	public String getUsername(){
		return username;
	}
	
	public String getPassword(){
		return password;
	}
}

…and then ProtectedApplication-class which is shown when login succeeds. The plan was that Login.authenticate creates a new User-class instance, which checks that username/password are correct and if so returns this User-class…and then instance of ProtectedApplication-class gets created. So pretty much the same thing PaymateApplication example does.

Now there’s something wrong at my call of protectedResources-method, line 40 above; getApplication().loadProtectedResources(user). “the method loadProtectedResources(User) is undefined for the type Application”. I just can’t put my finger on the problem now and would need some help. How should I call a MyApplication.loadProtectedResources -method from the Login-class?

If the above looks stupid in other ways I’m thankful of other corrections and suggestions -_-

Cheers!

The error was because the getApplication() method returns (an instance of) the original Application class instead of your MyApplication class. Try this:

MyApplication app = (MyApplication) this.getApplication(); 
app.loadProtectedResources(user);  

Ugly casts etc etc, some people are uncomfortable with this “unsafe typecast” thing, so consider this a short-term solution. Once you get a ThreadLocal-based implementation working, you won’t see these anymore.

Thank you! That seems to help out.

I’ve been studying Paymate-application which does quite the same thing.

PaymateApplication.java

    @Override
    public void setUser(Object user) {
        super.setUser(user);

        if (user != null) {
            mainWindow.removeWindow(login);
            mainWindow.showApplicationMainScreen();
        }
    }


http://dev.vaadin.com/svn/incubator/paymate-security-demo/src/com/paymate/vaadin/PaymateApplication.java

LoginDialog.java

    private void tryToLogIn() {
        Account newUser = Account.logIn(email.toString(), password.toString());
        if (newUser == null) {
            getWindow().showNotification("Login failed", LOGIN_ERROR_MSG,
                    Notification.TYPE_WARNING_MESSAGE);
        } else {
            getApplication().setUser(newUser);
        }
    }


http://dev.vaadin.com/svn/incubator/paymate-security-demo/src/com/paymate/vaadin/LoginDialog.java

LoginDialog.tryToLogin calls PaymateApplication.setUser without casting to PaymateApplication. And I don’t see the example using ThreadLocal-pattern. What’s the difference between these two cases?

Just to make sure, you do know that the Paymate application is made to demonstrate security vulnerabilities? :slight_smile:

Good point. I wasn’t actually aware of this. I’ll keep this in my mind when looking at the Paymate. Luckily the only thing I was checking now was the above case; how to call the application method.

Hi gyus,
can you look into my security related
question
(http://vaadin.com/forum/-/message_boards/message/369286) ?

Thanks

Hi all,
I am using uri fragment for my application history. My application link can be eg: http://myserver.com/app#3400 to display the required object with the specified id 3400.
However, when putting FORM authentication to the application, after login the application lost the fragment (remain: http://myserver.com/app) hence it cannot display the needed information.
I do not want to use Vaadin way mentioned above to authenticate the application because we are not allowed to use our custom way to authenticate user apart from FORM or BASIC auth. Anyone have the solution for this pls? Is there any place in Servlet class can overridden so that we can get the fragment BEFORE the session is created?

The URI fragment is not passed to the server in the HTTP request at all, so no, you can’t get it in the servlet before the session is created. Vaadin passes the URI fragment from the browser to the server in an Ajax request, but that’s long after creating the session.

I’m not sure if I understood how you authenticate, but I assume that you use a separate servlet for authentication?

If you have a separate login page, you could read the URI fragment with some JavaScript code and copy it to a hidden form input field, which you then read in the authentication servlet. Then, after the Vaadin application has started, set the URI fragment to that one.

PS. You can make external form authentication using URIHandler, as is done
here
.

Based on the limited information in the post, this looks very much like Spring security authentication with one of its servlet filters producing the authentication page.
While it does not directly answer the question, see what I wrote a few minutes ago
here
about replacing that servlet filter and another one in Spring Security.