Java 如何在Vaadin中设置视图级别的授权
我使用的是Vaadin 7、Spring Security和Spring Vaadin集成插件,并配置了身份验证位,因此它的工作非常出色。 当我进入授权部分时,我遇到了麻烦。 我想设置每个视图的授权,而不必在导航级别检查授权(如AppFoundation插件) 所以,我想要的是这样的东西:Java 如何在Vaadin中设置视图级别的授权,java,spring-security,authorization,vaadin,vaadin7,Java,Spring Security,Authorization,Vaadin,Vaadin7,我使用的是Vaadin 7、Spring Security和Spring Vaadin集成插件,并配置了身份验证位,因此它的工作非常出色。 当我进入授权部分时,我遇到了麻烦。 我想设置每个视图的授权,而不必在导航级别检查授权(如AppFoundation插件) 所以,我想要的是这样的东西: @Component @Scope("prototype") @VaadinView(value = ASecuredView.NAME, cached = true) @Secured("ROLE_ADMI
@Component
@Scope("prototype")
@VaadinView(value = ASecuredView.NAME, cached = true)
@Secured("ROLE_ADMIN_PROD")
public class ASecuredView extends GridLayout implements View {
...
}
当未经授权的用户试图进入此视图时,我希望处理AccessDeniedException
,并向用户显示一条通知消息,解释“视图仅可由管理员访问”行中的内容
当我调用视图时,我确实拥有正确的用户角色,当我尝试使用授权用户导航视图时,不会引发任何异常,因此注释本身似乎正常工作
问题是我无法捕获AccessDeniedException
我试过几种不同的方法来解决这个问题,但都没有用。以下是其中一些:
- 我创建了一个
,没有发现异常李>CustomAccessDeniedHandler
- 我尝试了简单的
标记,但仍然没有捕获异常拒绝访问处理程序
- 我尝试用
重新抛出异常,但行为仍然相同org.springframework.web.servlet.handler.SimpleMappingExceptionResolver
- 我尝试了
注释,但没有成功@PreFilter
- 我试着使用一个
(大约)方面,但即使这样也不起作用李>handleSecuredAnnotations
<global-method-security secured-annotations="enabled" />
<!-- Spring-Security -->
<http auto-config="true" use-expressions="true" disable-url-rewriting="true">
<form-login authentication-success-handler-ref="authenticationSuccessHandler" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<logout success-handler-ref="logoutSuccessHandler" invalidate-session="true" logout-url="/logout" />
<access-denied-handler ref="customAccessDeniedHandler" />
</http>
<authentication-manager>
<authentication-provider ref="activeDirectoryAuthenticationProvider" />
</authentication-manager>
<beans:bean id="activeDirectoryAuthenticationProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="someserver.com" />
<beans:constructor-arg value="ldap://ldaplb.someserver.com:389" />
<beans:property name="userDetailsContextMapper" ref="customUserDetailsContextMapper" />
<beans:property name="convertSubErrorCodesToExceptions" value="true" />
</beans:bean>
<beans:bean id="customAccessDeniedHandler" class="com.some.path.web.CustomAccessDeniedHandler" />
<beans:bean id="customUserDetailsContextMapper" class="com.some.path.web.CustomUserDetailsContextMapper" />
<beans:bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<beans:property name="defaultErrorView" value="uncaughtException" />
<beans:property name="excludedExceptions" value="org.springframework.security.access.AccessDeniedException" />
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key=".DataAccessException">dataAccessFailure</beans:prop>
<beans:prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</beans:prop>
<beans:prop key=".TypeMismatchException">resourceNotFound</beans:prop>
<beans:prop key=".MissingServletRequestParameterException">resourceNotFound</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<aop:config>
<aop:aspect id="securedAspect" ref="securityFeedbackAspect">
<aop:around pointcut="@annotation(org.springframework.security.access.annotation.Secured)" method="handleSecuredAnnotations" />
</aop:aspect>
</aop:config>
数据访问失败
未找到资源
未找到资源
未找到资源
我最终在MainUI类中实现了一个ErrorHandler。我肯定有更好的办法解决这个问题,但我找不到任何办法
public class MainUI extends UI implements ErrorHandler {
private static final long serialVersionUID = 1L;
@Override
protected void init(VaadinRequest request) {
VaadinSession.getCurrent().setErrorHandler(this);
@SuppressWarnings("unused")
DiscoveryNavigator navigator = new DiscoveryNavigator(this, this);
}
@Override
public void error(com.vaadin.server.ErrorEvent event) {
if (event.getThrowable() instanceof AccessDeniedException) {
AccessDeniedException accessDeniedException = (AccessDeniedException) event.getThrowable();
Notification.show(accessDeniedException.getMessage(), Notification.Type.ERROR_MESSAGE);
getUI().getNavigator().navigateTo(FirstView.NAME);
return;
}
// connector event
if (event.getThrowable().getCause().getCause().getCause() instanceof AccessDeniedException) {
AccessDeniedException accessDeniedException = (AccessDeniedException) event.getThrowable().getCause().getCause().getCause();
Notification.show(accessDeniedException.getMessage(), Notification.Type.ERROR_MESSAGE);
getUI().getNavigator().navigateTo(FirstView.NAME);
return;
}
}
}