【问题标题】:How to handle Access Denied properly in Vaadin 14 LTS如何在 Vaadin 14 LTS 中正确处理拒绝访问
【发布时间】:2021-05-20 11:47:17
【问题描述】:

我开始为我们用Spring Boot (2.2.6.RELEASE)Vaadin 14 LTS (14.6.1) 编写的应用程序实现身份验证和授权。

我已经关注了这些资源:

我有用于检查登录用户是否有权访问beforeEnter 方法中实现的指定资源的代码。问题在于调用event.rerouteToError(AccessDeniedException.class);。它尝试使用反射创建指定异常的实例,但由于它不包含公共无参数构造函数而失败。

private void beforeEnter(final BeforeEnterEvent event) {
    if (!AuthView.class.equals(event.getNavigationTarget()) && !AuthUtils.isUserLoggedIn()) {
        event.rerouteTo(AuthView.class);
    }

    if (!AuthUtils.isAccessGranted(event.getNavigationTarget())) {
        event.rerouteToError(AccessDeniedException.class);
    }
}
java.lang.IllegalArgumentException: Unable to create an instance of 'org.springframework.security.access.AccessDeniedException'. Make sure the class has a public no-arg constructor.
    at com.vaadin.flow.internal.ReflectTools.createProxyInstance(ReflectTools.java:519)
    at com.vaadin.flow.internal.ReflectTools.createInstance(ReflectTools.java:451)
    at com.vaadin.flow.router.BeforeEvent.rerouteToError(BeforeEvent.java:720)
    at com.vaadin.flow.router.BeforeEvent.rerouteToError(BeforeEvent.java:704)

这种情况的最佳解决方案是什么?我正在考虑两种可能的解决方案:

  1. 首先实例化AccessDeniedException,然后将其传递给BeforeEvent中的重载方法: public void rerouteToError(Exception exception, String customMessage)应该跳过通过反射创建异常对象
  2. 创建专用ErrorView并使用BeforeEvent的方法public void rerouteTo(Class<? extends Component> routeTargetType, RouteParameters parameters)

我决定关注Leif Åstrand's 的回答。我创建了自定义 AccessDeniedException 和适当的错误处理程序。这是我的实现。也许它会对某人有所帮助。

public class AccessDeniedException extends RuntimeException {
    private final int code;

    public AccessDeniedException() {
        super("common.error.403.details");
        this.code = HttpServletResponse.SC_FORBIDDEN;
    }

    public int getCode() {
        return code;
    }

}
@Tag(Tag.DIV)
@CssImport(value = "./styles/access-denied-view.css")
@CssImport(value = "./styles/access-denied-box.css", themeFor = "vaadin-details")
public class AccessDeniedExceptionHandler extends VerticalLayout implements HasErrorParameter<AccessDeniedException> {

    private final Details details;

    public AccessDeniedExceptionHandler() {
        setWidthFull();
        setHeight("100vh");
        setPadding(false);
        setDefaultHorizontalComponentAlignment(Alignment.CENTER);
        setJustifyContentMode(JustifyContentMode.CENTER);
        setClassName(ComponentConstants.ACCESS_DENIED_VIEW);

        this.details = new Details();
        this.details.setClassName(ComponentConstants.ACCESS_DENIED_BOX);
        this.details.addThemeVariants(DetailsVariant.REVERSE, DetailsVariant.FILLED);
        this.details.setOpened(true);

        add(this.details);
    }

    @Override
    public final int setErrorParameter(final BeforeEnterEvent event, final ErrorParameter<AccessDeniedException> parameter) {
        final int code = parameter.getException().getCode();

        this.details.setSummaryText(getTranslation("common.error.403.header", code));
        this.details.setContent(new Text(getTranslation(parameter.getException().getMessage())));

        return code;
    }

}

【问题讨论】:

    标签: spring-boot java-11 vaadin-flow vaadin14


    【解决方案1】:

    我建议创建自定义异常类型,而不是重用 Spring 中的 AccessDeniedException。这样,您根本不必处理所需的错误消息。

    【讨论】:

      【解决方案2】:

      正如您在第一个解决方案中提到的,您可以这样做:

      event.rerouteToError(new AccessDeniedException("Navigation target not permitted"), "");
      
      • 或者如果你愿意,也可以指定customMessage。如果您看到 rerouteToError(Class) 方法的实现,它只会传递空的 customMessage 并创建异常 - 您可以手动执行此操作,这是完全可以接受的。 我推荐这个解决方案。

      另一种解决方案是继承 AccessDeniedException 并将其与反射一起使用:

      public class RouteAccessDeniedException extends AccessDeniedException {
          public RouteAccessDeniedException() {
              super("Navigation target not permitted");
          }
      }
      

      推荐此解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 2017-08-19
        • 2018-02-05
        • 1970-01-01
        • 2020-06-08
        • 2013-10-31
        • 2011-12-26
        • 1970-01-01
        相关资源
        最近更新 更多