Search code examples
c#vb.netoauth-2.0webapi

How to call a web api that has Oauth 2.0


Hi so we have an external web api we want to call to get data out. It is using oauth 2.0. Can somebody please explain how we would go about doing this in .NET either vb.net or c#. I have in the past created api, however this one seems very complicated. Firstly you have to be signed into their oauth web page they have which generates some cookies, using these cookies by syncing them up in postman we can see the data, however we need this to be within our .net app. Can somebody please help how we go about this. Some code would be useful.

Thanks


Solution

  • This is how usually OAuth 2 authentication works.

    You basically log in with username and password (optional second factor) and then you receive a token, the so called Json Web Token or JWT (it holds encrypted information about your user, your access roles or groups you are member of as well as some timestamp which is the expiration time of the token).

    In every subsequent request you make to the server, you pass this token in the request header (or in your case as cookie).

    Example code:

    Login request:

    HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, new Uri(_baseUrl, "token"));
    string body = JsonConvert.SerializeObject(new
    {
        Username = _userName,
        Password = _password,
        secondFactor = secondFactor
    });
    httpRequest.Content = new StringContent(body, Encoding.UTF8, "application/json");
    var response = await client.SendAsync(httpRequest);
    var responseContent = await response.Content.ReadAsStringAsync();
    if (response.IsSuccessStatusCode)
    {
        TokenResult r = JsonConvert.DeserializeObject<TokenResult>(responseContent);
        if (!string.IsNullOrWhiteSpace(r.token))
        {
            _token = r.token;
            _tokenValidity = r.expirationDate;
            _refreshToken = r.refreshToken;
            _refreshTokenValidity = r.refreshTokenExpirationDate;
            return _token;
        }
        else
        {
            throw new Exception($"Failed to get token from server.\r\n{responseContent}");
        }
    }
    

    Now you use the _token in subsequent requests in the request header:

    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
    using HttpResponseMessage response = await client.GetAsync(new Uri(_baseUrl, relativePath));
    if (response.IsSuccessStatusCode)
    {
        using var stream = await response.Content.ReadAsStreamAsync();
        stream.Position = 0;
        using var reader = new StreamReader(stream);
        reader.ReadToEnd();
    }
    

    Please note, that usually the token has a certain lifetime after which it is basically useless. Some APIs offer a refresh token with which a new token can be requested without the user having to log in again with username and password, but that's beyond the scope of this question.

    You said you have to use the token as cookie? Well there are APIs which work like this but personally I've never seen one like this, which is why I can't you help very much, but it shouldn't be much more than putting the token you got into a cookie with a certain name.

    Hope this helps.