我有一个带有Vaadin的简单Spring Boot应用程序,用于UI和Spring Boot安全性。
我要实现的是从登录页面到主视图的组件之间的简单导航。
这是我的安全配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
// Not using Spring CSRF here to be able to use plain HTML for the login page
http.csrf().disable()
.authorizeRequests()
.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
.and().formLogin().loginPage(LOGIN_URL).permitAll().loginProcessingUrl(LOGIN_PROCESSING_URL)
.failureUrl(LOGIN_FAILURE_URL)
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL);
}
这是我的LoginView:
@Route("login")
@UIScope
@SpringComponent
public class LoginView extends VerticalLayout {
/**
* AuthenticationManager is already exposed in WebSecurityConfig
*/
@Autowired
private AuthenticationManager authManager;
private LoginOverlay loginOverlay;
public LoginView() {
loginOverlay = new LoginOverlay();
loginOverlay.addLoginListener(this::authenticate);
loginOverlay.setOpened(true);
LoginI18n i18n = LoginI18n.createDefault();
i18n.setAdditionalInformation("Welcome");
loginOverlay.setI18n(i18n);
add(loginOverlay);
}
private void authenticate(AbstractLogin.LoginEvent e) {
try {
Authentication auth = authManager.authenticate(
new UsernamePasswordAuthenticationToken(e.getUsername(), e.getPassword()));
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
if (auth.isAuthenticated())
getUI().ifPresent(ui -> ui.navigate(MainView.class));
} catch (Exception ex) {
loginOverlay.setError(true);
}
}}
和MainView:
@Route("main")
public class MainView extends VerticalLayout implements AfterNavigationObserver {
private final CertView certView;
private final UserView userView;
public MainView(CertView certView, UserView userView) {
this.certView = certView;
this.userView = userView;
}
private void createMain() {
Tab tab1 = new Tab("Certificates");
Tab tab2 = new Tab("Users");
Tabs tabs = new Tabs(tab1, tab2);
certView.setVisible(true);
userView.setVisible(false);
Map<Tab, Component> tabsToPages = new HashMap<>();
tabsToPages.put(tab1, certView);
tabsToPages.put(tab2, userView);
Div pages = new Div(certView, userView);
pages.setSizeFull();
Set<Component> pagesShown = Stream.of(certView)
.collect(Collectors.toSet());
tabs.addSelectedChangeListener(event -> {
pagesShown.forEach(page -> page.setVisible(false));
pagesShown.clear();
Component selectedPage = tabsToPages.get(tabs.getSelectedTab());
selectedPage.setVisible(true);
pagesShown.add(selectedPage);
});
add(tabs, pages);
}
@Override
public void afterNavigation(AfterNavigationEvent afterNavigationEvent) {
createMain();
}
}
CertView
和UserView
是@UIScope
d个@SpringComponent
,其中注入了一些DAO,并且正在数据中将其设置为正值。
现在,当登录视图的authenticate
和authManager.authenticate
被调用时会发生什么,就是将视图路由到MainView,通过看到构造函数被调用,URL更改但没有呈现任何内容,我可以看出来。奇怪的是, 当我在MainView的构造函数页面中设置断点时会成功呈现。
我对Vaadin还是很陌生,我不知道正确的导航应该是什么样子,以便您可以评论这样做的更好方法,但实际上我想保持简单。
那么,如何正确导航或在正确的生命周期事件中呈现mainView的内容?
Vaadin:13.0.1
答案 0 :(得分:1)
我有同样的问题。在导航到另一条路线之前,我通过关闭loginOverlay解决了该问题。
if (auth.isAuthenticated())
{
loginOverlay.close(); // <-- add this line!
getUI().ifPresent(ui -> ui.navigate(MainView.class));
}