Maintaining session between calls?

5,041 views
Skip to first unread message

Chris P

unread,
Feb 27, 2012, 10:26:20 AM2/27/12
to REST assured
Does anyone have an example of how to maintain the session between
rest assured calls to a RESTful spring security application?

Frédéric Camblor

unread,
Feb 27, 2012, 10:47:43 AM2/27/12
to rest-a...@googlegroups.com
Personnally, I retrieve JSESSIONID and then pass it to subsequent call.
Personnaly, I wrapped it into an in-house RestSession object.

Something like this :
    public static RestSession authenticate(FlatUser user){
        Credential c = new Credential().setLogin(user.getLogin()).setPassword(user.getPassword());
        Response response =
        given().
               contentType("application/json").body(c).
        expect().statusCode(200).
        when().
               post("/auth/login");

        String jsessionId = response.getCookie("JSESSIONID");
        return new RestSession(jsessionId);
    }

Then using RestSession object this way when calling REST services :
        RequestSpecification rs = given().
                    contentType("application/json").cookie("JSESSIONID=" + session.getJsessionId());

It works fine but heh, I admit it's really handwritten ;)

Frédéric

Johan Haleby

unread,
Feb 27, 2012, 1:36:58 PM2/27/12
to rest-a...@googlegroups.com
Hi,

I would probably write a stateful filter that extracts the jsessionid from the response and then set it transparently for each subsequent request (that uses the same filter instance). It could also perform the initial authentication if no jsessionid has been set.

Perhaps this is a filter that should be included in REST Assured? I've never needed this myself since I authenticate on each request.

Regards,
/Johan

Chris Pinto

unread,
Feb 27, 2012, 1:51:25 PM2/27/12
to rest-a...@googlegroups.com
I would vote for including it in rest-assured
For web apps that set session variables you want to get back to the same session (most) every time when testing. Because of deadlines, I need to come back to this issue later.



Chris
--
--

Regards,

Chris

"[W]hen all government, domestic and foreign, in little as in great things, shall be drawn to Washington as the center of all power, it will render powerless the checks provided of one government on another." --Thomas Jefferson, letter to Charles Hammond, 1821


Frédéric Camblor

unread,
Feb 27, 2012, 1:56:06 PM2/27/12
to rest-a...@googlegroups.com
I agree with the fact it would be a nice feature to have in Rest assured.

Nevertheless, I want it configurable and editable.
I _personnaly_ often need to log in with several users during the same test (to test security accesses for example).

Implementation shouldn't be made in a static way (like RestAssured.* things) :)

First (simple) step would be to have utility methods to get/set session id from/to request/response specifications.
With that in hand, we could be able to give this token on every requests.

WDYT ?

Frédéric Camblor  
Bordeaux JUG Board member
Jenkins community member & plugin commiter

Chris Pinto

unread,
Feb 27, 2012, 2:00:46 PM2/27/12
to rest-a...@googlegroups.com
Yes. That would be great. We would need to do similar things while testing too.



Deadlines.....

Chris



2012/2/27 Frédéric Camblor <fcam...@gmail.com>

Johan Haleby

unread,
Feb 27, 2012, 3:42:17 PM2/27/12
to rest-a...@googlegroups.com
Thanks for your suggestions, really appreciated.  I have some questions/comments below:


On 02/27/2012 07:56 PM, Frédéric Camblor wrote:
I agree with the fact it would be a nice feature to have in Rest assured.

Nevertheless, I want it configurable and editable.
I _personnaly_ often need to log in with several users during the same test (to test security accesses for example).

For curiosity, could you explain why you need to login with several users in the same test? Wouldn't it be possible (and even better) to have one test case per "security validation" (something like "userWithPrivilegeXShouldHaveAccessToY")?



Implementation shouldn't be made in a static way (like RestAssured.* things) :)

First (simple) step would be to have utility methods to get/set session id from/to request/response specifications.
With that in hand, we could be able to give this token on every requests.

I would argue that it's quite simple already. This is how you make a request and get the jsessionid:

String jsessionId = get("/x").cookie("jsessionid");

Setting cookies is not much harder:

given().cookie("jsessionid", jsessionid).when().get("/x");
I'm not sure how you could make it much simpler without making it less generic but suggestions are of course welcome :). Remember that not all sessionid's are named "jsessiond" (there's also "phpsessid" for example).

By writing your own filter (which can also be applied statically or using a RequestSpecBuilder) it should be possible to apply this more or less transparent. Theoretically it even ought to be possible to map each user to a jsessionid in a single filter which allows the filter to be applied statically as well. But I don't think it'll be possible to write a generic filter (that can be included by default in REST Assured) that solves this.

Regards,
/Johan

Chris Pinto

unread,
Feb 27, 2012, 4:05:32 PM2/27/12
to rest-a...@googlegroups.com
With the product that I am working on we have a situation where a Dealer of our products is able to log in and act as one of their customers (who is a customer of our web site) on our web site.

Perform an action
Login as a dealer
Call the RESTapi that says act as this user (after validation this gets stored in the session)
Call and api that creates a resource as that user (the user that you are acting as is retrieved from the session)

Verify the action
Login as the user that the dealer was acting on behalf of
Read and verify the resource that the dealer created above

Frédéric Camblor

unread,
Feb 27, 2012, 4:06:40 PM2/27/12
to rest-a...@googlegroups.com
Hi Johan :)

Comments coming below :

On Mon, Feb 27, 2012 at 21:42, Johan Haleby <johan....@gmail.com> wrote:
Thanks for your suggestions, really appreciated.  I have some questions/comments below:


On 02/27/2012 07:56 PM, Frédéric Camblor wrote:
I agree with the fact it would be a nice feature to have in Rest assured.

Nevertheless, I want it configurable and editable.
I _personnaly_ often need to log in with several users during the same test (to test security accesses for example).

For curiosity, could you explain why you need to login with several users in the same test? Wouldn't it be possible (and even better) to have one test case per "security validation" (something like "userWithPrivilegeXShouldHaveAccessToY")?

I agree with you _but_ I faced 2 use cases where it couldn't work :
- Use case where I need to create lots of data before executing my test. This type of test takes time to execute (and clean up), so mixing multiple users login in the same test will speed up my test execution (with the drawback that if I expect privileges X1, X2, X3 should give access to Y, if X1 fails I won't know if X2 and X3 succeeds).
- Second use case : We could imagine test data sould be initiated using rest services (instead of direct business service access). This way, we should use some sort of super user having the privilege to create everything during the test setup phase, then use a _real_ user to access/modify this data during test execution.
 
Implementation shouldn't be made in a static way (like RestAssured.* things) :)

First (simple) step would be to have utility methods to get/set session id from/to request/response specifications.
With that in hand, we could be able to give this token on every requests.

I would argue that it's quite simple already. This is how you make a request and get the jsessionid:

String jsessionId = get("/x").cookie("jsessionid");

Setting cookies is not much harder:

given().cookie("jsessionid", jsessionid).when().get("/x");
I'm not sure how you could make it much simpler without making it less generic but suggestions are of course welcome :). Remember that not all sessionid's are named "jsessiond" (there's also "phpsessid" for example).

That's what I exposed previously. But I'm not really a big fan of this (everyone, I'm the first ;), will create his own helper method wrapping these code samples).
Maybe could we use simple wrappers like this :
String jsessionid = get("/x").sessionId(); // sessionId(), not jsessionId() ;)
given().sessionId(jsessionid).when().get("/x");

Cookie key could then be configured statically (for example), in a RestAssured.sessionIdCookieKey = "jsessionid";

It should cover most of the cases, except the ones where we connect to servers having different session id implementations (for example, one with php, the other with java). This special case could be handled the way it is handled today (using manually cookie() key/value). 
I'm in favor of a "simplify for the masses" here ;)


By writing your own filter (which can also be applied statically or using a RequestSpecBuilder) it should be possible to apply this more or less transparent. Theoretically it even ought to be possible to map each user to a jsessionid in a single filter which allows the filter to be applied statically as well. But I don't think it'll be possible to write a generic filter (that can be included by default in REST Assured) that solves this.

I didn't know these parts of rest assured for re-use. This sounds really interesting (for me, and I'm sure, for everyone ! :)).
I'm ok we could use this way, but I think providing sessionId() getter/setter could be useful too.

Johan Haleby

unread,
Feb 28, 2012, 2:32:45 AM2/28/12
to rest-a...@googlegroups.com
Thank you for your comments and for describing the use cases, it's really valuable! My main concern is that I don't want to put too much stuff in the API but at the same time it should of course be easy to use. There's already an "alias method" for setting the content-type (given().contentType(..) instead of using given().header("content-type", x)) so if both of you think it'll be a good idea to add the sessionId() method and no one complains I guess it should be possible :)

I suppose that the call to sessionId() (for read purposes) could by default try to get the "jsessionid" and if not found then "phpsessid" and so on (I'd don't know more sessionid names by heart). The default session cookie name could also be configurable somewhere in the detailed config if required. What do you think?

But right now I encourage you both to take a look at the filter functionality and see what you can do with it. And if you do please tell me if you get any new ideas or what you make of it :). I'll update issue 28 to point to this thread.

Regards
/Johan

2012/2/27 Frédéric Camblor <fcam...@gmail.com>

Chris Pinto

unread,
Feb 28, 2012, 9:26:41 AM2/28/12
to rest-a...@googlegroups.com
a session id method would be great. your description of what it would do seems to cover everything that I would need.

Thank you.

Chris

Johan Haleby

unread,
Mar 18, 2012, 12:14:47 PM3/18/12
to rest-a...@googlegroups.com
Hi, 

I've now implemented support for setting a "sessionId" a bit more easy in REST Assured. You can now do: 

given().sessionId("1234"). .. 

or you can put it in each request:

RestAssured.sessionId = "1234";

It's also possible to get the sessionId easily from the response:

String sessionId = get("/something").sessionId();

The sessionId name can be configured as well (by default it's jsessionid):

RestAssured.config = newConfig().sessionConfig(sessionConfig().sessionIdName("phpsessionid"));

Please try it out and see if it works for you by depending on version 1.6.1-SNAPSHOT and adding the snapshot repo to maven:

<repositories>
        <repository>
            <id>sonatype</id>
            <snapshots />
        </repository>
</repositories>

Regards, 
/Johan
Reply all
Reply to author
Forward
0 new messages