Page 45 - MSDN Magazine, August 2017
P. 45

Figure 5 Expense API Controller
{
}
Bearer Token
While limited-purpose tokens make it harder for attackers to forge a request, they’re still not perfect. Ideally, a Web service should be able tell whether an HTTP POST request is coming from a Microsoft server instead of some unauthorized, potentially malicious server.
Microsoft solves this problem by including a bearer token in every HTTP POST request it sends to Web services. The bearer token is a JSON Web Token (JWT) and it’s included in the Autho- rization header of a request. When a user clicks on the Approve button, the Web service will receive a request that looks like this:
POST https://api.contoso.com/expenses/approve
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjhxZ3A4VER- CbDJINkp5RkU0WjM0ZDJoYS1rRSIsImtpZCI6IjhxZ3A4VERCbDJINkp5RkU0WjM0ZDJoYS1rRSJ9. eyJpYXQiOjE0ODQwODkyNzksInZlciI6IlNUSS5FeHRlcm5hbEFjY2Vzc1Rva2VuLlYxIiwiYXBw aWQiOiI0OGFmMDhkYy1mNmQyLTQzNWYtYjJhNy0wNjlhYmQ5OWMwODYiLCJzdWIiOiJkYXZpZEBj b250b3NvLmNvbSIsImFwcGlkYWNyIjoiMiIsImFjciI6IjAiLCJzZW5kZXIiOiJleHB- lbnNlYXBw... (truncated for brevity)
{
"id": "98432019",
"token": "d8a0bf4f-ae70-4df6-b129-5999b41f4b7f"
}
What follows “Bearer” in the Authorization header is a long base-64 encoded string that’s a JSON Web Token (JWT). You can decode the JWT at jwt.calebb.net. Figure 7 shows a sample token after it’s decoded.
Every JWT has three segments, separated by a dot (.). The first segment is the header, which describes the cryptographic oper- ations applied to the JWT. In this case, the algorithm (alg) used to sign the token is RS256, which means RSA using the SHA-256 hash algorithm. The x5t value specifies the thumbprint of the key used to sign the token.
The second segment is the payload itself. It has a list of claims that the token is asserting. Web services should use these claims to verify a request. The table in Figure
8 describes these claims.
The third segment is the digital
signature of the token. By verify- ing the signature, Web services can be confident that the token is sent by Microsoft and trust the claims in the token.
Verifying a digital signature is a complex task. Fortunately, there’s a library on NuGet that makes the verification task easy. The library is available at bit.ly/2stq90c and it’s authored by Microsoft. Microsoft also published code samples for other languages on how to verify the token. Links for these code samples are available at the end of this article.
August 2017 39
"@type": "HttpPost",
"name": "Approve",
"target": "https://api.contoso.com/expense/approve", "body": "{ \\\\"id\\\\": \\\\"98432019\\\\", \\\\"token\\\\": \\\\ "d8a0bf4f-ae70-4df6-b129-5999b41f4b7f\\\\" }"
[RoutePrefix("expense")]
public class ExpenseController : ApiController {
[HttpPost]
[Route("approve")]
public HttpResponseMessage Approve([FromBody]JObject jBody) {
string expenseId = jBody["id"].ToString();
// Process and approve the expense report.
HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK); response.Headers.Add("CARD-ACTION-STATUS", "The expense was approved.");
return response; }
[HttpPost]
[Route("reject")]
public HttpResponseMessage Reject([FromBody]JObject jBody) {
string expenseId = jBody["id"].ToString(); string comment = jBody["comment"].ToString();
// Process and reject the expense report.
HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK); response.Headers.Add("CARD-ACTION-STATUS", "The expense was rejected.");
return response; }
}
Limited-Purpose Tokens
Because the expense ID usually follows a certain format, there’s a risk that an attacker can perform an attack by posting a lot of requests with different expense IDs. If an attacker successfully guesses an expense ID, the attacker might be able to approve or reject that expense report. Microsoft recommends developers use “limited-purpose tokens” as part of the action target URL or in the body of the request. The limited- purpose token should be hard for attackers to guess. For example, I use a GUID, a 128-bit number as the limited-purpose token. This token can be used to correlate service URLs with specific requests and users. It can also be used to protect Web services from replay attacks (bit.ly/2sBQmdn). You update the markup to include a GUID in the body:
Figure 6 Expense Report with Successful Approval Notification msdnmagazine.com























































   43   44   45   46   47