Exclude Path from LoginView

Hi, I try to exclude a path/rout (“/test”) from the login part.

I added the following code in the SecurityConfig

protected void configure(HttpSecurity http) throws Exception {
		
		http
		.csrf().disable()

		// Register our CustomRequestCache, that saves unauthorized access attempts, so
		.requestCache().requestCache(new CustomRequestCache())
		
		.and().authorizeRequests()
		.antMatchers("/test").permitAll()
				.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()

				// Allow all requests by logged in users.
				.anyRequest()
				.authenticated()		

				// Configure the login page.
				.and().formLogin().loginPage(LOGIN_URL).permitAll().loginProcessingUrl(LOGIN_PROCESSING_URL)
				.failureUrl(LOGIN_FAILURE_URL)

				// Register the success handler that redirects users to the page they last tried
				// to access
				.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())

				// Configure logout
				.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL);

But nevertheless, the Login page pops up, when I try to open “/test”. What should I change in LoginView to get this work? I tried to change the “beforeEnter”-Method and checked for the active path (“/test”). I tried to set “setOpened(false)” but this doesn’t help the real way… and redirecting to my TestView ends up in a closed loop.

hi …

i could not solve this issue either.
how can we solve “register” process ? … i created register view but can not redirect to it.

Btw Ines , there is no other demo that has login process besides “Full Stack App” right ?

Umit KIRTIL:
Btw Ines , there is no other demo that has login process besides “Full Stack App” right ?

Yes, but I just copied the security part and the login stuff and used only the vaadin-core package instead the full vaadin.

Is there any solution for this issue?

Hi,

I don’t see anything wrong in your HttpSecurityConfiguration. Weird that it doesn’t work.
You could try another way though. In your WebSecurityConfigurerAdapter implementation class add your “/test” route to public void configure(WebSecurity web) method e.g.

//Routes configured here should be ignored by Spring Security
@Override
public void configure(WebSecurity web) {
	web.ignoring().antMatchers("/test");
}

Julius Koljonen:

//Routes configured here should be ignored by Spring Security
@Override
public void configure(WebSecurity web) {
	web.ignoring().antMatchers("/test");
}

this doesn’t work neither. But the web.ignoring.antMatchers for Vaadin and co works…
My TestViewClass extends an AbstractPageTemplate with a Route (“test”).

Hm… have you test a Vaadin-project with such a Security-Configuration?

I think there is something strange in the ConfigureUIServiceInitListener-Class in the beforeEnter-Method…

Hi,

Attempt to remove any previous workarounds you had until the websecurity method. In your first post you mentioned something about overriding beforeEnter method and a closed loop.
Some additional troubleshooting tips :

  • Are you sure you are using Vaadin’s @Route annotation and not some other library?
  • Does your AbstractPageTemplate extend Vaadin’s Component class e.g. Div or VerticalLayout?

Julius Koljonen:
Hi,

Attempt to remove any previous workarounds you had until the websecurity method. In your first post you mentioned something about overriding beforeEnter method and a closed loop.

I removed the workaround in my LoginView.

Some additional troubleshooting tips :

  • Are you sure you are using Vaadin’s @Route annotation and not some other library?
    Yes, I use import com.vaadin.flow.router.Route;
  • Does your AbstractPageTemplate extend Vaadin’s Component class e.g. Div or VerticalLayout?
    My AbstractPageTemplate looks like
@Tag("main-page-view")
@JsModule("./src/views/main-page-view.js")
@JsModule("styles/shared-styles.js")
public abstract class AbstractPageTemplate extends PolymerTemplate<TemplateModel>  {

	@Id("content")
    protected Div content;
    
    @Id("footer")
    protected Div footer;
    
    
    public AbstractPageTemplate() {
    	//this.setContent(getContentLayout());
    	this.setFooter(getFooterDiv());
    }
    
    abstract protected Component getContentLayout() throws IOException;
	
    public void setContent(Component component) {
    	this.content.removeAll();
        this.content.add(component);
    }
	...

AbstractPageTemplate looks ok. And you are sure TestViewClass uses Vaadin’s @Route(“test”) annotation?

Julius Koljonen:
AbstractPageTemplate looks ok. And you are sure TestViewClass uses Vaadin’s @Route(“test”) annotation?

Yes, here is my TestView-Class. I Use vaadin 14.0.7.

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import ....
....

@Route(value = AppConst.PAGE_TEST, layout = MainView.class)
@PageTitle("test")
public class TestView  extends AbstractPageTemplate {

	/**

	protected Grid<User> grid = new Grid<User>();
	protected UserRepository userRepository;
	
	public static final String CREATE = "CREATE";
	public static final String EDIT = "EDIT";
	
	
	@Autowired
	public TestView(UserRepository userRepository) {
		this.userRepository = userRepository;

		List<User> users = userRepository.findAll();
		
		this.grid.setItems(users);
		
		//this.setContent(this.getContentLayout());
		
		this.setContent(new Label("test"));
	}
	
	...

MainView-Class extends the AppLayout …

Seems ok as long as AppConst.PAGE_TEST = “test”. Hard to say then what is wrong since both configurations should work(the one in your first post and the websecurity workaround). What is the current behaviour without the workarounds when you try to navigate to “test”?

Yes, AppConst.PAGE_TEST = “test”.

The current behavior without any additional security-configuration is the following:

  • If I am not logged in and go to localhost:8080/test … I will be redirected to the /login
  • If I am logged in, I obtain the test-View.

Do you reroute manually to login view in your project something like this https://vaadin.com/learn/tutorials/securing-your-app-with-spring-security/setting-up-spring-security#_secure_router_navigation? If so are you sure it’s not somehow executed when you navigate to “test” when you are not logged in?

Julius Koljonen:
Do you reroute manually to login view in your project something like this https://vaadin.com/learn/tutorials/securing-your-app-with-spring-security/setting-up-spring-security#_secure_router_navigation? If so are you sure it’s not somehow executed when you navigate to “test” when you are not logged in?

This is what I mentioned 7 posts before in “I think there is something strange in the ConfigureUIServiceInitListener-Class in the beforeEnter-Method…”
So, what’s a good workaround? :slight_smile: Thank’s for your analytic help

Assuming your beforeEnter looks like this

private void beforeEnter(BeforeEnterEvent event) {
	if (!LoginView.class.equals(event.getNavigationTarget()) 
		&& !SecurityUtils.isUserLoggedIn()) {
		event.rerouteTo(LoginView.class);
	}
}

Can’t you then just do something like this?

private void beforeEnter(BeforeEnterEvent event) {
	if(TestView.class.equals(event.getNavigationTarget()){
		return;
	}
	if (!LoginView.class.equals(event.getNavigationTarget()) 
		&& !SecurityUtils.isUserLoggedIn()) {
		event.rerouteTo(LoginView.class);
	}
}

Julius Koljonen:
Assuming your beforeEnter looks like this

private void beforeEnter(BeforeEnterEvent event) {
	if (!LoginView.class.equals(event.getNavigationTarget()) 
		&& !SecurityUtils.isUserLoggedIn()) {
		event.rerouteTo(LoginView.class);
	}
}

Can’t you then just do something like this?

private void beforeEnter(BeforeEnterEvent event) {
	if(TestView.class.equals(event.getNavigationTarget()){
		return;
	}
	if (!LoginView.class.equals(event.getNavigationTarget()) 
		&& !SecurityUtils.isUserLoggedIn()) {
		event.rerouteTo(LoginView.class);
	}
}

Thanks, this works. The Code looks like

/**
	 * Reroutes the user if she is not authorized to access the view. 
	 *
	 * @param event
	 *            before navigation event with event details
	 */
	private void beforeEnter(BeforeEnterEvent event) {
		final boolean accessGranted = SecurityUtils.isAccessGranted(event.getNavigationTarget());
		if(TestView.class.equals(event.getNavigationTarget())){
			return;
		}
		
		if (!accessGranted) {
			if (SecurityUtils.isUserLoggedIn()) {
				event.rerouteToError(AccessDeniedException.class);
			} else {
				event.rerouteTo(LoginView.class);
			}
		}
	}

Ines Melzer:

Julius Koljonen:
Assuming your beforeEnter looks like this

private void beforeEnter(BeforeEnterEvent event) {
	if (!LoginView.class.equals(event.getNavigationTarget()) 
		&& !SecurityUtils.isUserLoggedIn()) {
		event.rerouteTo(LoginView.class);
	}
}

Can’t you then just do something like this?

private void beforeEnter(BeforeEnterEvent event) {
	if(TestView.class.equals(event.getNavigationTarget()){
		return;
	}
	if (!LoginView.class.equals(event.getNavigationTarget()) 
		&& !SecurityUtils.isUserLoggedIn()) {
		event.rerouteTo(LoginView.class);
	}
}

Thanks, this works. The Code looks like

/**
	 * Reroutes the user if she is not authorized to access the view. 
	 *
	 * @param event
	 *            before navigation event with event details
	 */
	private void beforeEnter(BeforeEnterEvent event) {
		final boolean accessGranted = SecurityUtils.isAccessGranted(event.getNavigationTarget());
		if(TestView.class.equals(event.getNavigationTarget())){
			return;
		}
		
		if (!accessGranted) {
			if (SecurityUtils.isUserLoggedIn()) {
				event.rerouteToError(AccessDeniedException.class);
			} else {
				event.rerouteTo(LoginView.class);
			}
		}
	}

There is still some problem with this kind of flow. I am trying to develop a forgotPasswordView which I do not want to be under authentication. by the first time of running application I can access it but in next round , No. Do you maybe have any solution?