How to obtain getUserPrincipal().getUserName() while implementing Spring Data JPA AuditorAware interface

841 Views Asked by At

I'm trying to use Spring Data JPA (1.6.2) in my current project. All seems to work well, but I got stuck while implementing the AuditorAware interface.

My application will be deployed to an old Apache Jetspeed JSR168 compliant portal. This portal takes care of user authentication/authorisation. As such, I don't have to use a security framework like Spring Security or Shiro. The other frameworks in my application are:

  1. Struts 1.2.4 (with a Struts-Portal-Bridge)
  2. Spring 3.2.10
  3. JPA (Hibernate 3.6.10 as ORM provider)

I'd like to use @CreatedBy and @LastModifiedBy annotated fields in my entities (I got @CreatedDate and @LastModifiedDate working). In my application I usually obtain the username using request.getUserPrincipal().getUserName().

But how can I get hold of the username while implementing the AuditorAware interface?

The example implementation from the 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();
    }
}

Somehow I want to implement AuditorAware like this:

class MyAuditorAware implements AuditorAware<String> {
    public String getCurrentAuditor() {
        return <<principal from servlet- or portletcontext>>.getUserName();
    }
}

How can I accomplish this without adding an additional framework?

1

There are 1 best solutions below

0
On BEST ANSWER

As Konstantin already mentioned in his comment, you probably want to save the principal name in a scope suitable for a request. This may very well be a ThreadLocal. This allows you to get it easily later on in your AuditorAware implementation.

To stay with Spring's naming call it PrincipalContextHolder. As a starting point you may look at the source of JodaTimeContextHolder for a simple implementation of a ContextHolder.