弹簧安全性可防止从背景线程导航到另一个视图
我很难从瓦丁14迁移到vaadin 23。我的背景任务很长。使用Vaadin 14完成任务后,我可以通过以下代码导航到结果视图:
UI ui = UI.getCurrent();
final SecurityContext context = SecurityContextHolder.getContext();
ui.access(() -> {
SecurityContextHolder.setContext(context);
UI.navigate("work-finished-view");
});
使用Vaadin 23,我会收到此警告,
(ViewAccessChecker.java:147) Preventing navigation to com.vaadin.flow.router.RouteNotFoundError because no HTTP request is available for checking access.
这是com.vaadin.flow.server.server.auth.viewaccesschecker
中的代码。
VaadinServletRequest vaadinServletRequest = VaadinServletRequest.getCurrent();
if (vaadinServletRequest == null) {
// This is in a background thread and we cannot access the request
// to check access
getLogger().warn("Preventing navigation to " + targetView.getName()
+ " because no HTTP request is available for checking access.");
beforeEnterEvent.rerouteToError(NotFoundException.class);
return;
}
从背景线程导航到另一个视图的正确方法是什么?
I have trouble migrating from Vaadin 14 to Vaadin 23. I have a long running backgroundtask with a progress dialog. With Vaadin 14 after finishing the task i could navigate to a result-view with the following code:
UI ui = UI.getCurrent();
final SecurityContext context = SecurityContextHolder.getContext();
ui.access(() -> {
SecurityContextHolder.setContext(context);
UI.navigate("work-finished-view");
});
With Vaadin 23 i get this warning
(ViewAccessChecker.java:147) Preventing navigation to com.vaadin.flow.router.RouteNotFoundError because no HTTP request is available for checking access.
This is the code in com.vaadin.flow.server.auth.ViewAccessChecker
VaadinServletRequest vaadinServletRequest = VaadinServletRequest.getCurrent();
if (vaadinServletRequest == null) {
// This is in a background thread and we cannot access the request
// to check access
getLogger().warn("Preventing navigation to " + targetView.getName()
+ " because no HTTP request is available for checking access.");
beforeEnterEvent.rerouteToError(NotFoundException.class);
return;
}
What is the right way to navigate to another view from a background thread?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要创建一个假请求,该请求使用安全上下文持有人中的值,并使用
currentInstance.set(vaadinrequest.class,request);
设置该请求。完全可行,但不是很好。我没有在这里写一个漫长而又骇人听闻的示例以如何完成它,而是花了很多时间创建一个拉动请求,以使这项工作在将来开箱即用: https://github.com/vaadin/flow/pllow/pull/pull/13675
You would need create a fake request that uses the values from the security context holder and set that request using
CurrentInstance.set(VaadinRequest.class, request);
. Completely doable but not very nice.Instead of writing a long and hacky example here for how it could be done, I spent the time on creating a pull request to make this work out of the box in the future: https://github.com/vaadin/flow/pull/13675
如果您使用的是
vaadinwebsecurityConfigurerAdapter
Security> SecurityContext
应在UI线程中自动可用。不幸的是,viewAccesschecker
不会以任何方式使用它。它的实现方式(即以春季独立的方式)仅需要httpservletrequest
。因此,我目前看不到正确的方法(无论如何,与香草·瓦丁一起使用)。您可能应该创建一个 github上的票证,因为这似乎是一个非常重要的用例。也许您可以重定向到未受保护的视图,该视图需要用户单击按钮以导航到受保护的视图。
页面#setLocation(...)还将为安全检查创建新的请求,但这不会在Vaadin内导航,并且基本上会重新创建您的UI。
但是,老实说,这两种选择都在可接受的解决方法列表中。
如果没有其他人可以提供真正合理的解决方法,您可以查看我的附加组件: vaadin的春季启动安全性。它确实使用Spring的
SecurityContext
,因此在您的情况下可以使用。If you are using the
VaadinWebSecurityConfigurerAdapter
theSecurityContext
should automatically be available in the UI thread. Unfortunately, theViewAccessChecker
will not make use of it either way. The way it's implemented (i.e. in a Spring independent way) it simply requires aHttpServletRequest
. So I currently don't see a right way to do this (with vanilla Vaadin, anyway). You should probably create a ticket on Github because this seems like a pretty important use case.Maybe you could redirect to an unprotected view that requires the user to click a button to navigate to the protected one.
Page#setLocation(...) would also create a new request for the security check, but that will not navigate within Vaadin and basically recreate your UI.
But both options are pretty far down on the list of acceptable workarounds, honestly.
If no one else can provide an actually reasonable workaround, you could check out my add-on: Spring Boot Security for Vaadin. It does use Spring's
SecurityContext
so it would work in your case.