在我的 之前的简短抱怨 中,我向您展示了如何使用@Alternative以及替代元数据来轻松更改基于部署场景的Bean实现。但这并不是故事的结束。在部署时,我有时还希望更改两样东西

  • 拦截器
  • 装饰器

让我们考虑安全问题。假设我有一个拦截器,该拦截器为“业务层”中的Beans实现了方法级别的基于角色的安全。

@Secure @Interceptor
class SecurityInterceptor {
    @Inject User user;

    @AroundInvoke
    Object checkRole(InvocationContext ctx) throws Exception {
        String[] roles = ctx.getMethod().getAnnotation(Secure.class).value();
        for (String role: role) {
            if ( !user.getRoles().contains(role) ) throw new AuthorizationException(role);
        }
        return ctx.proceed();
    }
}

我还有一个独立的数据访问层,由以下接口实现的Beans组成

public interface DataAccess<T, V> {
    public V getId(T object);
    public T load(V id); 
    public void save(T object); 
    public void delete(T object);
    public Class<T> getDataType();
    ...
}

并且我有一个装饰器,它为我的数据访问层添加了行级安全。

@Decorator
class DataSecurityDecorator<T, V> implements DataAccess<T, V> {
    @Inject @Delegate DataAccess<T, V> delegate;
    @Inject User user;

    public void save(T object) { 
        authorize(SecureAction.SAVE, object); 
        delegate.save(object);
    }

    public void delete(T object) { 
        authorize(SecureAction.DELETE, object); 
        delegate.delete(object);
    }

    private void authorize(SecureAction action, T object) { 
        V id = delegate.getId(object); 
        Class<T> type = delegate.getDataType(); 
        if ( !user.getPermissions().contains( new Permission(action, type, id) ) ) {
            throw new AuthorizationException(action);
        }
    }
}

这一切都很不错,但在我的测试环境中,我不想启用这些拦截器和装饰器。这就是为什么默认情况下,它们没有被启用。

我们需要显式地启用拦截器和装饰器,以便为所有需要安全访问控制的部署声明它们beans.xml.

<beans>
    <interceptors>
        <class>org.mycompany.security.SecurityInterceptor</class>
    </interceptors>
    <decorators>
        <class>org.mycompany.security.DataSecurityDecorator</class>
    </decorators>
</beans>

返回顶部