【问题标题】:How to set authorization on View level in Vaadin如何在 Vaadin 中设置视图级别的授权
【发布时间】:2014-04-19 15:09:22
【问题描述】:

我正在使用 Vaadin 7、Spring Security 和 Spring-Vaadin-Integration 插件,并配置了身份验证位,因此它的工作原理就像一个魅力。 当我到达授权部分时,我遇到了一些麻烦。 我想为每个视图设置授权而不必在导航级别检查授权(就像在 AppFoundation 插件中一样)。

所以,我想要的是这样的

@Component
@Scope("prototype")
@VaadinView(value = ASecuredView.NAME, cached = true)
@Secured("ROLE_ADMIN_PROD")
public class ASecuredView extends GridLayout implements View {
    ...
}

当未经授权的用户尝试进入此视图时,我想处理 AccessDeniedException 并向用户显示一条通知消息,其中解释了“该视图只能由管理员访问”行中的内容。

当我调用视图时,我确实拥有正确的用户角色,并且当我尝试使用授权用户导航到那里时没有引发异常,因此注释本身似乎可以正常工作。

问题是我无法捕获 AccessDeniedException。

我尝试了几种不同的方法来解决这个问题,但都无济于事。以下是其中一些:

  • 我创建了一个CustomAccessDeniedHandler,没有发现异常。
  • 我尝试了简单的access-denied-handler 标签,但仍然没有捕获到异常。
  • 我尝试使用 org.springframework.web.servlet.handler.SimpleMappingExceptionResolver“重新抛出”异常,但行为仍然相同。
  • 我尝试了@PreFilter 注释,但没有成功。
  • 我尝试使用handleSecuredAnnotations (around) Aspect,但即使这样也没有用!

我是否以错误的方式处理这个问题?

也许有更简单/更好的方法来实现这一点?怎么样?

这是我的 spring-security.xml。我会提供整个shabang。请注意,我也分别尝试了不同的方法:

<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>

【问题讨论】:

    标签: java spring-security authorization vaadin vaadin7


    【解决方案1】:

    我最终在 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 2018-07-05
      • 2018-11-29
      • 2011-08-01
      相关资源
      最近更新 更多