OIDC with Azure AD

Hi All,

I have been been building a POC Xamarin Forms application which utilises Couchbase Lite and the Sync Gateway. I’m trying to implement the OIDC Implicit Flow using a Bearer token and have hit a brick wall.

I’m not exactly sure what is relevant, but here are some of the versions that I am using in the solution/stack.

Docker

sync-gateway: 3.0.0-beta02-enterprise
couchbase server: enterprise-7.0.2

Nuget

Couchbase.Lite.Enterprise 3.0.0-beta02
Xamarin.Forms 5.0.0.2291
Microsoft.Identity.Client 4.39.0

As it stands, I am at a point where I am receiving the Bearer token from AAD, but when I issue a POST to _session, I am getting a 200 response with no response cookies within my application code, but do receive a 401 when I execute the POST through Postman. It’s highly likely that this is my misconfiguration or bad code. :slight_smile:

Here is my OIDC configuration.

http://localhost:4985/inflightdb/_config
{
    "bucket": "inflight",
    "name": "inflightdb",
    "oidc": {
        "providers": {
            "azuread": {
                "issuer": "https://login.microsoftonline.com/16015xxx-xxxx-xxxx-xxxx-94831594cf0a/oauth2/v2.0/authorize",
                "register": true,
                "client_id": "50aa2036-xxxx-xxxx-xxxx-xxx0405d225a",
                "username_claim": "",
                "allow_unsigned_provider_tokens": false,
                "IsDefault": false,
                "Name": "",
                "InsecureSkipVerify": false
            }
        }
    }
}

Here is the code used to create the session.

// Create session cookie
using (HttpClient httpClient = new HttpClient(handler))
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://10.0.2.2:4984/inflightdb/_session/"))
{
    var token = await SecureStorage.GetAsync("AadAccessToken");

    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
    HttpResponseMessage response = await httpClient.SendAsync(request);

    response.EnsureSuccessStatusCode();

    var responseCookies = cookies.GetCookies(new Uri("http://10.0.2.2:4984"));

    //TODO: Deal with responseCookies 
    json = await response.Content.ReadAsStringAsync();
}

VS Studio Debugging

While debugging my application, I can see that the POST call is being made and has the Bearer token included in the headers.

When I look in the GW logs shown in Docker Desktop (should I be looking elsewhere?), all I can see is this entry.

2022-01-06T11:39:59.056Z [INF] HTTP:  #001: GET /inflightdb/_session (as GUEST)

Not exactly sure why it logs a GET request? Is this correct?

The HTTP response is as follows.

{StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
  Server: Couchbase
  Server: Sync
  Server: Gateway/3.0.0
  Server: EE
  Date: Thu, 06 Jan 2022 14:06:40 GMT
  Content-Length: 96
  Content-Type: application/json
}}

When I then inspect the cookie Container, I do not see any cookies being returned, maybe they are and my c# code isn’t correct.

Postman

When I take the Bearer token and send the request through Postman, I get a slightly different behaviour. In the GW logs I see the following.

2022-01-06T13:26:11.574Z [INF] HTTP:  #004: POST /inflightdb/_session
2022-01-06T13:26:11.574Z [INF] HTTP: #004:     --> 401 Invalid login  (3123.3 ms)

With the response in Postman being.

{
    "error": "Unauthorized",
    "reason": "Invalid login"
}

Possibly Relevant Info

The following answer on another thread mentions that the Issuer in the GW configuration should match that of the token. In my case, when I enter my token into jwt.io, it gives back a different issuer.

Config:
"issuer": "https://login.microsoftonline.com/16015xxx-xxxx-xxxx-xxxx-94831594cf0a/oauth2/v2.0/authorize"

Token:
https://sts.windows.net/16015xxx-xxxx-xxxx-xxxx-94831594cf0a/

Sorry for such a long post, I just wanted to include as much relevant information as possible. I’m learning so many new things at once that my brain is frazzled and I’m probably doing something pretty silly, any help or suggestions are much appreciated.

Thanks

OK, a wee bit of an update since my initial post. I was indeed making a few errors on my side as I suspected.

  1. I was storing the access token instead of the id token when calling AAD and subsequently passing the wrong token to the _session call.
  2. I also re-read the ‘OIDC Implicit Flow’ blog post, and if I understand correctly, I think my OIDC provider/issuer was incorrect.

The blog post mentions that the OIDC discovery uses [issuer]/.well-known/openid-configuration.

Can anyone confirm whether my understanding is correct?

However, I have update the value to match the iss value in the id token, but this has not really improved my situation.

If I inspect the response content, I get the following.

{"authentication_handlers":["default","cookie"],"ok":true,"userCtx":{"channels":{},"name":null}}

I’m still not seeing any cookies and the GW logs do not show any further information.

Any help appreciated, I feel that I’m not far away.

Cheers

I think the changes I made in my previous post must have resolved my issue because I can now successfully sync with the GW.

Thanks