如何在实现 Spring Data JPA AuditorAware 接口时获取 getUserPrincipal().getUserName()
Posted
技术标签:
【中文标题】如何在实现 Spring Data JPA AuditorAware 接口时获取 getUserPrincipal().getUserName()【英文标题】:How to obtain getUserPrincipal().getUserName() while implementing Spring Data JPA AuditorAware interface 【发布时间】:2014-10-17 16:12:36 【问题描述】:我正在尝试在我当前的项目中使用 Spring Data JPA (1.6.2)。一切似乎都运行良好,但我在实现 AuditorAware 接口时卡住了。
我的应用程序将部署到旧的 Apache Jetspeed JSR168 兼容门户。该门户负责用户身份验证/授权。因此,我不必使用像 Spring Security 或 Shiro 这样的安全框架。我的应用程序中的其他框架是:
-
Struts 1.2.4(带有 Struts-Portal-Bridge)
春季 3.2.10
JPA(Hibernate 3.6.10 作为 ORM 提供者)
我想在我的实体中使用 @CreatedBy 和 @LastModifiedBy 注释字段(我得到了 @CreatedDate 和 @LastModifiedDate 工作)。在我的应用程序中,我通常使用 request.getUserPrincipal().getUserName() 获取用户名。
但是在实现 AuditorAware 接口时如何获取用户名?
来自Spring Data JPA docs的示例实现:
class SpringSecurityAuditorAware implements AuditorAware<User>
public User getCurrentAuditor()
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated())
return null;
return ((MyUserDetails) authentication.getPrincipal()).getUser();
不知何故,我想像这样实现 AuditorAware:
class MyAuditorAware implements AuditorAware<String>
public String getCurrentAuditor()
return <<principal from servlet- or portletcontext>>.getUserName();
如何在不添加额外框架的情况下完成此操作?
【问题讨论】:
有一个肮脏的把戏——在你的 servlet/portlet 请求处理的最开始就在某种静态持有者类中捕获你的用户主体,然后在你的 auditaware 中调用持有者获取器 【参考方案1】:正如 Konstantin 在他的评论中已经提到的,您可能希望将主体名称保存在适合请求的范围内。这很可能是ThreadLocal
。这使您以后可以在 AuditorAware
实现中轻松获得它。
为了保持 Spring 的命名,将其命名为 PrincipalContextHolder
。作为起点,您可以查看JodaTimeContextHolder 的源代码,了解ContextHolder
的简单实现。
【讨论】:
以上是关于如何在实现 Spring Data JPA AuditorAware 接口时获取 getUserPrincipal().getUserName()的主要内容,如果未能解决你的问题,请参考以下文章