【发布时间】: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)
这种情况的最佳解决方案是什么?我正在考虑两种可能的解决方案:
- 首先实例化
AccessDeniedException,然后将其传递给BeforeEvent中的重载方法:public void rerouteToError(Exception exception, String customMessage)应该跳过通过反射创建异常对象 - 创建专用
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