I have been digging through posts for too long now and getting dizzy, so I'm hoping one of the gurus here can help me with this.
I'm using Container Managed Authentication and it's working well. I have my Realm setup to authenticate against, set up protected urls in web.xml, have a login page etc.
But now I am hitting a problem...
I have JPA objects for my data model and some of these objects are 'audited' in that they track when they were created or updated and by who.
I'm using a @PrePersist
handler in my code to set the createdOn
and updatedOn
fields on persist/update respectively, like so:
@PrePersist
protected void onCreate() {
this.setCreatedOn(new Date());
}
This works great, but I am missing how I should get access to the currently logged in user from here... I need that to be able to set the createdBy
field.
I'm using Resteasy and in my endpoint I do have access to the logged in username and am able to get my Account object:
@Path("/test")
public class TestEndpoint {
@EJB
AuthorizationService authService;
@GET
@Path("path")
@Produces("application/json")
@RolesAllowed("User")
public Response test() {
Account account = authService.getLoggedInAccount();
return account == null ? Response.status(Status.NOT_FOUND).build() : Response.ok().entity(account).build();
}
}
AuthorizationService is mine and looks like this:
@Stateless
@LocalBean
public class AuthorizationService {
@Inject
HttpServletRequest request;
public Account getLoggedInAccount() {
Account result = (Account) request.getAttribute(LOGGED_IN_USER);
if (result == null) {
Principal principal = request.getUserPrincipal();
if (principal != null) {
List<Account> results = crudService.find(Account.BY_NAME, Params.of("name", principal.getName()), 0, 0);
if (results != null && results.size() > 0) {
result = results.get(0);
request.setAttribute(LOGGED_IN_USER, result);
}
}
}
return result;
}
}
This works. Notice that I cache the logged-in user on a request attribute so I don't send the query to the DB each time.
Until now I have been able to get by with this setup, but I feel I am doing this all wrong...
I would like to have one global interception point (filter?) where I populate ...something... (the request?) with the currently logged in user's Account object and then be able to inject it wherever it's needed... I would highly prefer solutions that do not create a session as I'm trying to make the app as scalable as possible.
Any tips on how to handle this? That golden link to the tutorial that explains this well maybe? Thanks for any help guys!