Visual Studio Web Tests and OAuth: Taming the elusive Access Token

Posted on Posted in Web Tests

Visu­al Stu­dio Web Tests offer an excel­lent way to val­i­date that your application's end­points (typ­i­cal­ly API calls) are per­form­ing the way you'd expect. They also offer a quick way to sim­u­late "typ­i­cal user" sce­nar­ios which can be inte­grat­ed into Load Tests against your appli­ca­tion. How­ev­er, any appli­ca­tion that requires a user to log in (usu­al­ly with a test account for auto­mat­ed test­ing) will inevitably find that authen­ti­ca­tion is not han­dled by default in Web Tests.

The Problem

The most com­mon issue faced is Web Test Recorder not cap­tur­ing your Autho­riza­tion head­er. While this seems like a flaw, there's a very valid rea­son for it. Most OAuth access tokens are not intend­ed to last indef­i­nite­ly and will expire at some point (often in under an hour). When this hap­pens, any requests attempt­ing to use an Autho­riza­tion: Bear­er (token) head­er saved in the Web Test would be reject­ed as unau­tho­rized, ren­der­ing them useless.

Anoth­er com­pli­ca­tion that can arise is the oauth/token false flag in your record­ed test. Log­ging in and get­ting a new access token is one of the first steps that tends to hap­pen dur­ing a Web Test Record­ing ses­sion. See­ing a call to oauth/token or its equiv­a­lent in the Web Test sure looks nice and may lead you to believe that you have autho­riza­tion han­dled, but like most calls in a web test, noth­ing is done with the results. You might be suc­cess­ful­ly request­ing a new access token from the serv­er and get­ting back a response with a valid new token. How­ev­er, by default, noth­ing is hap­pen­ing with that token. The access token is request­ed (often inval­i­dat­ing pre­vi­ous access tokens in the process) and then prompt­ly discarded.

Extraction Rules To The Rescue

Search­ing around for how to solve this prob­lem gives you back sev­er­al painful or clum­sy options. The most com­mon one is to imple­ment a WebTest­Plu­g­in with cus­tom code to nego­ti­ate with the OAuth serv­er, get the access token, and set it to a Con­text Para­me­ter in your test run. If we've record­ed the oauth/token request in our Web Test and it can be reli­ably repeat­ed, the solu­tion is much sim­pler and requires noth­ing more than an Extrac­tion Rule.

Extrac­tion Rules allow you to parse infor­ma­tion com­ing back in the response and save select bits into para­me­ters. In our case, we're mak­ing a call to the OAuth token end­point already in the Web Test, we sim­ply need to cap­ture and use the access token that is returned. We'll add a new Extrac­tion Rule by right-click­ing on the request and select­ing Add Extrac­tion Rule... menu item. There are numer­ous ways to extract data from the request, but since the response will always be in JSON, we'll just use the Extract Reg­u­lar Expres­sion rule to parse out our access token from the response.

Our Reg­u­lar Expres­sion will be "access_token":"(.*?)" and we need to make sure Use Groups is enabled so we get back just the access token and not the entire JSON key-val­ue pair. We have spec­i­fied that the val­ue will be stored in the AccessTo­ken con­text para­me­ter which we set up in our web test before­hand. When this request exe­cutes now, it will parse out the access token from the OAuth response and save it into a para­me­ter for us to use in future requests as need­ed. The para­me­ter can be sub­sti­tut­ed in using the {{}}dou­ble curly braces any­where that data-bind­ing is supported.

As you can see in the screen­shot above, an Extrac­tion Rule's use­ful­ness extends beyond just OAuth tokens. In my Web Test, I mke a POST to api/sites to cre­ate a new site, which returns the new site's ID. That ID must be used in future API calls I make, so I've used an Extrac­tion Rule with a regex pat­tern to parse the SiteId para­me­ter, stored the parsed val­ue into a Con­text Para­me­ter, and changed my API call's URL from the pre­vi­ous­ly hard­cod­ed ID to api/sites/{{SiteId}}. More com­plex authen­ti­ca­tion schemes may require a WebTest­Plu­g­in, but for basic OAuth 2.0, Extrac­tion Rules is usu­al­ly all you need and they can go a long way in help­ing with oth­er sce­nar­ios where you need to extract any data from respons­es for lat­er use.

Leave a Reply

Your email address will not be published. Required fields are marked *