Vaadin 21中@RolesAllowed权限拦截后跳转自定义错误页问题
Vaadin 21处理@RolesAllowed权限不足的自定义重定向方案
问题原因
当用户已登录但无对应角色访问带@RolesAllowed注解的Vaadin路由时,Vaadin自身的路由访问控制会先拦截请求并抛出AccessDeniedException。这个异常发生在Vaadin客户端导航流程中,不会触发Spring Security的AccessDeniedHandler或accessDeniedPage配置(未走传统Servlet请求重定向逻辑),因此会出现Vaadin默认的导航错误空白页。
解决方案:使用Vaadin NavigationErrorHandler处理导航异常
Vaadin提供NavigationErrorHandler接口,专门捕获路由导航过程中的异常,可通过实现该接口处理权限不足场景,并重定向到自定义错误页。
步骤1:创建自定义权限不足页面
先实现一个无需权限访问的AccessDeniedView作为错误页:
@Route("accessDenied") public class AccessDeniedView extends VerticalLayout { public AccessDeniedView() { setSizeFull(); setAlignItems(Alignment.CENTER); setJustifyContentMode(JustifyContentMode.CENTER); add(new H1("权限不足")); add(new Paragraph("您没有访问该页面的权限,请联系管理员。")); add(new Button("返回首页", event -> UI.getCurrent().navigate(""))); } }
步骤2:实现自定义NavigationErrorHandler
创建Spring Bean实现NavigationErrorHandler接口,捕获AccessDeniedException并导航到错误页:
@Component public class CustomNavigationErrorHandler implements NavigationErrorHandler { @Override public void handleNavigationError(Exception exception, RouterLocation location, UiContext uiContext) { if (exception instanceof AccessDeniedException) { // 导航到自定义权限不足页面 uiContext.getUI().ifPresent(ui -> ui.navigate("accessDenied")); } else { // 其他导航异常交给默认处理器处理 DefaultNavigationErrorHandler defaultHandler = new DefaultNavigationErrorHandler(); defaultHandler.handleNavigationError(exception, location, uiContext); } } }
步骤3:配置Security允许访问错误页
在继承VaadinWebSecurityConfigurerAdapter的配置类中,确保/accessDenied路由允许访问:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(jsr250Enabled = true) // 开启@RolesAllowed注解支持 public class SecurityConfig extends VaadinWebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); // 设置登录页 setLoginView(http, LoginView.class); // 允许所有用户访问权限不足错误页 http.authorizeRequests() .antMatchers("/accessDenied").permitAll(); } }
补充说明
- 必须添加
@EnableGlobalMethodSecurity(jsr250Enabled = true)才能让@RolesAllowed注解生效。 - 该方案是Vaadin单页应用的最佳实践,基于客户端导航实现,无页面刷新,体验更流畅。
- 若需兼容非Vaadin请求的权限处理,可同时配置Spring Security的
AccessDeniedHandler,但Vaadin路由导航场景下,NavigationErrorHandler是核心解决方式。
内容的提问来源于stack exchange,提问作者Robyn.D
相关产品推荐
相关产品推荐

