spring / hibernate - 按当前用户 ID 过滤
Posted
技术标签:
【中文标题】spring / hibernate - 按当前用户 ID 过滤【英文标题】:spring / hibernate - filter by current user id 【发布时间】:2011-04-22 22:34:40 【问题描述】:我的 Oracle 数据库中有一个 CompanyList 表:
CMP_ID INTEGER -- ID of company
CMP_NAME VARCHAR2 -- name of company
USR_ID INTEGER -- Foreign key to the USERS table
我的 Spring 3 MVC 应用程序全部使用注释配置,我的 POJO 以及我的 DAO 对象 (CompanyDao) 使用休眠来检索例如公司列表。
公司道:
@Transactional
public Set<Company> findAllCompanys() throws DataAccessException
return findAllCompanies(-1, -1);
@SuppressWarnings("unchecked")
@Transactional
public Set<Company> findAllCompanies(int startResult, int maxRows) throws DataAccessException
Query query = createNamedQuery("findAllCompanies", startResult, maxRows);
return new LinkedHashSet<Company>(query.getResultList());
还有我的公司域名:
@Entity
@NamedQueries(
@NamedQuery(name = "findAllCompanies", query = "select myCompany from Company myCompany"))
...
public class Company implements Serializable
...
然后我设置了 spring security,所以我的所有页面都需要标识。
使用当前登录用户会话的 USER ID 过滤 CompanyDao 返回的行的最佳方法是什么?
【问题讨论】:
【参考方案1】:简答:SecurityContextHolder。
略长一点的答案: 如果作为 user_id 外键关系的父侧的 User 实体也实现了 UserDetails 接口,则可以在 Spring 的安全上下文中直接使用 User 实体。
您可以从您的 DAO 层或它上面的层调用 SecurityContextHolder.getContext() 方法...这并不重要,因为返回的实例将被限定为请求的本地线程。
然后,您可以从上下文实例中获取 UserDetails,将其转换为您的 User 实体,并将其作为命名参数传递给 DAO 调用。
作为快速跟进,我意识到您的原始问题暗示您将运行当前存在的命名查询,然后过滤掉不匹配的公司。您仍然可以通过将与您的公司关联的用户与安全上下文中的用户进行比较来使用该方法,但总的来说,我不推荐这种方法;向数据库询问您需要什么。
【讨论】:
【参考方案2】:实际上,Spring Security 3 可以通过@PostFilter
注解过滤返回的集合,见15.3.1 @Pre and @Post Annotations。
但我认为在您的情况下,当Company
与User
具有多对一关系时,Jeff 的建议更合适-您应该在查询中添加一个条件,即将findAllCompanies()
替换为findAllCompaniesForUser()
,并在表示层或服务层传递从SecurityContextHolder
中提取的userId
作为参数。
【讨论】:
以上是关于spring / hibernate - 按当前用户 ID 过滤的主要内容,如果未能解决你的问题,请参考以下文章
Spring/Hibernate - 将当前时间戳写入数据库 [重复]
如何在当前使用 HSQLDB 的 Spring 和 Hibernate 后台使用 MySQL
如何在 Spring & Hibernate 中保存当前用户的信息?
Spring Hibernate - 无法为当前线程获取事务同步会话