spring - Overriding user injected by @CreatedBy Annotation in AuditorAware Implementation -
following implementation of auditaware.
@component public class auditorawareimpl implements auditoraware<string> { @log private logger logger; @override public string getcurrentauditor() { string user = "system"; try { final subject subject = securityutils.getsubject(); if (subject != null) { final session session = subject.getsession(false); if (session != null) { final user userobj = (user) session.getattribute("user"); if (userobj != null) { user = userobj.getusername(); } } } } catch (final exception e) { this.logger.error("getcurrentauditor", "no logged in user information found.", e); } return user; } } as know, value of user returned auditorawareimpl injected spring in attribute marked @createdby annotation below.
@createdby @column(name = "created_by", length = 150, nullable = false, updatable = false) private string createdby; there 2 problems want solve.
- i triggering separate thread saves thousands of objects in database. if session times out in between, session object becomes null , auditawareimpl throws error , hence background process errors out.
- i want run few quartz schedular related jobs in in session object not available. still want inject hard coded user in case. how do it?
one thing have tried @ individual object level, using following code is,
@transient private string overriddenuser; @prepersist public void updatecreatedby(){ if(overriddenuser!=null){ this.createdby=overriddenuser; } } i explicitly set overriddenuser="admin" whenever want override user injected spring in createdby , overwrite using prepersist method. not seem work since before overwrite value, spring tries populate created using value returned auditaware. if session expired process errors outs! how solve this?
i found solution above problems below.
step 1
i defined bean below contains hashmap. map store current thread name key , mapped username value.
public class overriddenuser { map<string,string> userthreadmap= new hashmap<>(); //add getters/setters } step 2
initialised bean on startup in class annoted @configuration.
@bean("overriddenuser") public overriddenuser overrideuser(){ overriddenuser obj = new overriddenuser(); return obj; // singleton implementation can done if required } step 3
auto wired bean in impl class want override session user.
@autowired overriddenuser overriddenuser; assigned random name running thread.
randomstring randomthreadname = new randomstring(9); thread.currentthread().setname(randomthreadname.tostring()); and put required user name current thread in hashmap below.
try { if(overriddenuser!=null){ overriddenuser.getuserthreadmap().put(thread.currentthread().getname(),"my on ridden username"); } // entire database related code here } catch (exception e){ // handle exceptions thrown code } { //perform clean here if(overriddenuser!=null){ overriddenuser.getuserthreadmap().remove(thread.currentthread().getname()); } } } step 4
then modified auditawareimpl below.
@component public class auditorawareimpl implements auditoraware<string> { @log private logger logger; @autowired overriddenuser overriddenuser; @override public string getcurrentauditor() { string user = "system"; try { if(overriddenuser!=null && overriddenuser.getuserthreadmap()!=null && overriddenuser.getuserthreadmap().get(thread.currentthread().getname())!=null){ user=overriddenuser.getuserthreadmap().get(thread.currentthread().getname()); }else{ final subject subject = securityutils.getsubject(); if (subject != null) { final session session = subject.getsession(false); if (session != null) { final user userobj = (user) session.getattribute("user"); if (userobj != null) { user = userobj.getusername(); } } } } } catch (final exception e) { this.logger.error("getcurrentauditor", "no logged in user information found.", e); } return user; } } so if running thread accesses auditawareimpl gets custom user name set thread. if null pulls username session doing earlier. hope helps.
Comments
Post a Comment