How to create custom login with Vaadin4Spring MVP structure and Spring Security

1k views Asked by At

My current project is based on the structure of peholmst's vaadin4spring MVP:

https://github.com/peholmst/vaadin4spring/tree/master/samples/mvp-sample

Im using Vaadin 7.5.3, SpringBoot 1.2.5.RELEASE and JSR-330 1.0 (@Inject).

Now i want to create a new vaadin view login page in combination with spring security... My attempt was the following:

HttpSecurityConfigurer.java

import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

[...]

void configure(Environment env, ApplicationContext appContext, HttpSecurity http) throws Exception {
   http
         .authorizeRequests()
             .antMatchers("/VAADIN/**", "/PUSH/**", "/UIDL/**", "/resources/**").permitAll()
             .anyRequest().authenticated()
             .and()
         .csrf().disable();


   http
         .formLogin()
             .loginPage("/login").defaultSuccessUrl("/", true).permitAll()
             .and()
         .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login").permitAll();
}

[...]

LoginUI.java

import javax.inject.Inject;

import org.vaadin.spring.events.EventBus;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Title;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.UI;

import my.example.application.ui.presenter.Action;
import my.example.application.ui.presenter.LoginPresenter;

@SpringUI(path = "/login")
@Theme("valo")
@Title("MyLogin")
public class MyLoginUI extends UI {

    private static final long serialVersionUID = -1746340376430847935L;

    @Inject
    LoginPresenter presenter;

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        eventBus.publish(this, Action.START);
        setContent(presenter.getView());
    }

}

LoginPresenter.java

import org.vaadin.spring.events.Event;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import org.vaadin.spring.navigator.Presenter;
import org.vaadin.spring.navigator.annotation.VaadinPresenter;

import my.example.application.ui.view.LoginView;

@VaadinPresenter(viewName = LoginView.NAME)
public class LoginPresenter extends Presenter<LoginView> {

    @EventBusListenerMethod(scope = EventScope.SESSION, filter = StartupFilter.class)
    public void onStartup(Event<Action> event) {
        getView().setBody();
    }

}

LoginView.java

import com.vaadin.spring.annotation.UIScope;
import javax.annotation.PostConstruct;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.navigator.View;
[...]

@UIScope
@SpringView(name = LoginView.NAME, ui = MyLoginUI.class)
public class LoginView extends VerticalLayout implements View {

    private static final long serialVersionUID = 8034398112492147989L;

    public static final String NAME = "loginView";

    @PostConstruct
    private void init() {
        setMargin(true);
        setSpacing(true);
        setSizeFull();
    }

    public void setBody() {
        addComponent(new Label("Heey, thats my login page! :)"));
    }

    @Override
    public void enter(ViewChangeEvent event) {

    }

}

So when i start the application my browser redirects to "http://localhost:8080/login" but its rendering only the vaadin loading animation:

Vaadin loading animation

Can someone help me?

1

There are 1 answers

1
Patrick T On

I had the same problem and it took ages to figure out a workaround:

@Override
    protected void configure(HttpSecurity http) throws Exception
    {
        // Authentication is not needed for the login page
        // Permit access to VAADIN resources explicitly
        http.authorizeRequests().antMatchers( "/vaadinServlet/**", "/login")
                .permitAll();
        // TODO: For some reason I need the "auth" URL parameter. W/o the VAADIN UI does not load
        http.formLogin().loginPage("/login?auth");

        http.logout().logoutSuccessUrl("/login");

        // Any request needs to be authenticated. If a user is not authenticated => Login Page
        http.authorizeRequests().anyRequest().authenticated();

        http.csrf().disable();
    }

Usually it should work without the ?auth in the login page URL(it can be any URL extension). Usually it should work when using permitAll() at the loginPage() method. Usually it should work without explicitly allowing /login.

If anyone has an explanation for this I would appreciate that. I debugged spring and looked into the responses of the browser. Probably it's something in the *.js files that VAADIN creates for its widgets.