This getting started guide will show you how to get a JWT token, which then you will use to query the API. Examples are provided in C# .NET using a helper library, using C# .NET HttpClient, a PHP helper library, and in Ruby. The examples are a guideline for the steps, and not necessarily the complete or best practice for the platform.
Examples by platform
An example from the token server provider can be found here: https://identityserver4.readthedocs.io/en/release/quickstarts/1_client_credentials.html#creating-the-client
C# using helper library
- You want to install the IdentityModel package from the NuGet feed into your client project.
This will enable you to shortcut some of the URL mapping and discovery in the OAuth workflow. The following will do this work for you
// discover endpoints from metadata
var disco = await DiscoveryClient.GetAsync("https://warden.data.uwaterloo.ca");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
Next you'll pass your credentials to the token server and receive back a JSON response that will include your authorization token.
var tokenClient = new TokenClient(disco.TokenEndpoint, "your_client_id", "your_client_password");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("sourceapi");
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
- Now with your valid token you'll be able to make calls against the API to get data.
To send the access token to the API you typically use the HTTP Authorization header. This is done using the SetBearerToken extension method.
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var response = await client.GetAsync("https://api.data.uwaterloo.ca/api/v1/terms");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
C# using HttpClient
- Get a JSON response from Identity Server, that includes a JWT bearer token property.
- Include the JWT token in the authorization header.
- Query the API
static void Main(string[] args)
{
// Create client to get Identity Server Response
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Add required information to retrieve token (you will need to use your credentials)
var content = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("scope", "sourceapi"),
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", "your_client_id"),
new KeyValuePair<string, string>("client_secret", "your_client_secret")
});
// Get response from a POST
var response = client.PostAsync("https://warden.data.uwaterloo.ca/connect/token", content).Result;
response.EnsureSuccessStatusCode();
// For our purposes we'll get the return as string (that is valid JSON) and then deserialize into an object
var jsonResponseString = response.Content.ReadAsStringAsync().Result;
var jsonObject = JsonConvert.DeserializeObject<JwtResponseBlock>(jsonResponseString);
client.Dispose();
// Query the API by setting the Authorization header value with the token we got
client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jsonObject.access_token);
// Retrieve Term informatino from API as an example
var termsJsonString = client.GetStringAsync("https://api.data.uwaterloo.ca/api/v1/terms").Result;
}
private class JwtResponseBlock
{
public string access_token { get; set; }
}
PHP with helper library
Ruby
Thank you to James from FEDS for this contribution.
require 'json'
require 'net/http'
require 'openssl'
client_id = 'your_client_id'
client_pwd = 'your_client_secret'
class MissingAccessTokenError < StandardError; end
def retrieve_jwt_token(client_id, client_pwd)
token_url = 'https://warden.data.uwaterloo.ca'
# get JWT token
token_uri = URI("#{token_url}/connect/token")
req = Net::HTTP::Post.new(token_uri)
req.set_form_data(client_id: client_id, client_secret: client_pwd,
grant_type: 'client_credentials', scope: 'sourceapi')
http = Net::HTTP.new(token_uri.host, token_uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.request(req)
json = JSON.parse response.body
raise MissingAccessTokenError, 'Access Token is missing in response' unless json.key? 'access_token'
json['access_token']
end
def terms(access_token)
uri = URI.parse('https://api.data.uwaterloo.ca/api/v1/terms')
request = Net::HTTP::Get.new(uri, {'Authorization' => "Bearer #{access_token}"})
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request(request)
end
puts response.body
end
access_token = retrieve_jwt_token client_id, client_pwd
terms(access_token)