【问题标题】:Multitenancy with Spring security JPASpring security JPA 的多租户
【发布时间】:2012-04-01 00:04:58
【问题描述】:

这是Multitenancy with Spring JPA的跟进

我选择使用“AbstractRoutingDataSource”。但是现在的问题是启动时初始化的数据源和实体管理器 bean。无论如何在春季配置它,在用户通过身份验证后它将以哪种方式初始化?

我能想到的另一个问题是如何处理并发。我把tenantId放在这个类中

public class ThreadLocalContextUtil {
 private static final ThreadLocal<String> contextHolder =
            new ThreadLocal<String>();

   public static void setTenantId(String tenantId) {
      Assert.notNull(tenantId, "customerType cannot be null");
      contextHolder.set(tenantId);
   }

   public static String getTenantId() {
      return (String) contextHolder.get();
   }

   public static void clearTenant() {
      contextHolder.remove();
   }
}

我能想到的解决方案是在数据源初始化后删除tenantId。对吗?

【问题讨论】:

    标签: spring-security multi-tenant


    【解决方案1】:

    我已经解决了类似的问题。我基于 Spring 的AbstractDataSource 实现了自己的TenantAwareDataSource。它从名为 tenantContext 的会话范围 bean 中获取 tenantId。每次处理传入请求时都会更新此 bean。它是通过使用 Spring Security 的安全过滤器完成的:

    <security:http auto-config='false' >
        <security:custom-filter before="FIRST" ref="tenantFilter" />
        <!-- ...more security stuff... -->
    </security:http>
    

    我的TenantAwareDataSource 在启动时被初始化,但这并不重要,因为它是空的 - 它包含没有租户数据源(例如池化 JDBC 数据源或 JPA 实体管理器)。它们是在第一次为所选租户调用 getConnection() 时延迟创建的。

    所以,我的TenantAwareDataSource 维护自己的动态数据源映射,而AbstractRoutingDataSource 期望在启动时完成数据源映射的静态初始化。

    article 中阅读更详细的说明。

    【讨论】:

    • 嗨实际上我试过你的解决方案。问题是“tenantfilter”是会话范围的,你得到这个错误 java.lang.IllegalStateException: No thread-bound request found: 你是指实际 Web 请求之外的请求属性,还是处理原始接收之外的请求线?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet/DispatcherPortlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。
    • 你应该添加: org.springframework.web.context.request.RequestContextListener 到 web.xml
    猜你喜欢
    • 2012-03-31
    • 2014-11-02
    • 1970-01-01
    • 2017-11-19
    • 2016-05-03
    • 2011-11-23
    • 2014-06-19
    • 2017-10-23
    • 2014-12-22
    相关资源
    最近更新 更多