Mock Custom User in Spring Security Test -


we using spring 4.3.9.release , spring security 4.2.3.release, these of latest versions have seen. have restful (spring-mvc) backend using spring web security roles-based access api's.

we have controller looks this:

@requestmapping(value = "/create", method = requestmethod.post, produces = "application/json", headers = "content-type=application/json") public @responsebody myobjectentity createmyobject(@requestbody myobjectentity myobj) throws myobjectexception {     userdetails userdetails = (userdetails) securitycontextholder.getcontext().getauthentication().getprincipal();     customuser user = null;     if (userdetails instanceof customuser)     {         user = ((customuser) userdetails);     }     string email = user.getemail();     myobjectentity myobj = myobjectservice.createmyobject(myobj, email);     if (securitycontextholder.getcontext().getauthentication() != null)     {         securitycontextholder.getcontext().setauthentication(null);     }     return myobj; } 

we know user has logged in web-site username , password. know ui has token, , pass along in header. our security uses siteminder example, means have userdetailsservice goes third-party, passes along token, , have username, password, , roles user has. working well. did create customuserdetailsservice follows:

public class customuserdetailsservice implements userdetailsservice {      @override      public userdetails loaduserbyusername(string accesstoken) throws         usernamenotfoundexception,         preauthenticatedcredentialsnotfoundexception        {             // goto third-party service verify token             // custom user , user roles             // data, custom user        } } 

so, once established token valid, , have gotten additional user information third-party, , have valid role authorized api ... can execute controller itself. , see code traditional getting existing user out of spring security context.

 userdetails userdetails = (userdetails) securitycontextholder.getcontext().getauthentication().getprincipal();     customuser user = null;     if (userdetails instanceof customuser)     {         user = ((customuser) userdetails);     } 

actually, have read, way when have custom user , customuserdetails. code, want email of user. , works when test api advanced rest client. our qa has authenticate against web-site, , tokens passed ui, access tokens, , put in headers of advanced rest client (or postman) , works.

we have code invalidate security context when api over.

if (securitycontextholder.getcontext().getauthentication() != null) {      securitycontextholder.getcontext().setauthentication(null); } 

against, real api, real progress, works great. now, when comes testing, of tests work against our secured controllers , not. so, here have controller test:

@requestmapping(value = "/{productid}", method = requestmethod.get, headers = "accept=application/json") public @responsebody productentity getproductbyid(@pathvariable("productid") long productid) {     logger.debug("productcontroller: getproductbyid: productid=" + productid);     customuser user = authenticate();     productentity productentity = service.getbyid(productid);     logger.debug("productcontroller: getproductbyid: productentity=" + productentity);     invalidateuser();     return productentity; } 

and here test:

@test public void testmockgetproductbyproductid() throws exception {     mockhttpservletrequestbuilder requestbuilder = mockmvcrequestbuilders.get(base_url + "/1").with(user("testuser").roles("regular_user"));     this.mockmvc.perform(requestbuilder).anddo(print()).andexpect(status().isok()); } 

this works because when controller, don't need customeruser set, works. if role correct role ("regular_user"), works, if role not correct, 403 error expecting.

but if @ controller first posted @ top, need customuser set, , if isn't set, when try email, fail. so, have been looking @ multiple ways of setting mock user in authentication, when controller can customuser in security context.

i've done before, when using standard spring security user, , not custom user.

we can establish customuser in security context, when gets controller, , code run ....

// works userdetails userdetails = (userdetails) securitycontextholder.getcontext().getauthentication().getprincipal();     customuser user = null;      // if fails because;     // userdetails of instance user (spring security user)     // , not customuser.     if (userdetails instanceof customuser)     {         user = ((customuser) userdetails);     } 

let me add code have our customuser:

public class customuser implements userdetails {  private static final long serialversionuid = -6650061185298405641l; private string username; private arraylist<grantedauthority> authorities;  private string firstname; private string middlename; private string lastname; private string email; private string phone; private string externaluserid;    // getters/setters   // tostring  } 

i hope put enough information here can answer question. have spent day or 2 scouring internet can answer question no avail. of answers little older spring 3 , older spring security 3.x. if more information needed, please let me know. thanks!

i wonder ... if need customuserdetails implments userdetails?

thanks again!

this easier think.

customuser userdetails = new customuser(); /* todo: set username, authorities etc */ mockhttpservletrequestbuilder requestbuilder = mockmvcrequestbuilders.get(base_url + "/1").with(user(userdetails)); 

this allowed long customuser implements userdetails interface.


Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -