1. I?m redirected from my application to the synapse auth endpoint. https://signin.synapse.org/?client_id=100059&scope=openid&response_type=code&redirect_uri=https%3A%2F%2Flocal.exaptive.dev%2Fcnapi%2Flogin%2Fredirect%2Fsynapse%2Flocal&state=NNSF-RK27tQT_JLhgtN3JcDzRS7QQZrgCxX6Yr2ul30&nonce=CbVwu6vWs6_Qw_9e_2NrlRyDS5ma9Cat_zJoVdUwoNo
2. I log in, then am redirected back to my application. https://local.exaptive.dev/cnapi/login/redirect/synapse/local?state=NNSF-RK27tQT_JLhgtN3JcDzRS7QQZrgCxX6Yr2ul30&code=AQICAHgHZPmM9m5Ih-56EHjZ6UCFV3T2xKjwP7o8AVF_zxfCngFOCb26QQvG1qW093f7J-xaAAABkjCCAY4GCSqGSIb3DQEHBqCCAX8wggF7AgEAMIIBdAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAzdlwbmeUyb2akdWK8CARCAggFFJbL58_Ml4esCMz-WoTIFjOHXVwntjA3APc8zxTNsGfyTvZau50KvqBbH6j7S5iWDZKTa92iBg3fTSmDPnN7eyAKBVh7o9QcaugnWOaHfENIyfgLN7EzLuMjkamC1ku76ax_g--H3Wdo26wFsug4TRQwanQU0HFUUkCkvrEtHtnQx4tOLkGlAir-N_f1WuitLl5kj5Oct7WwgCLMlGS2p3LKKOjVFXwifk84Lgjmv3dhJNHKvOwolsEqc-4m5RSfn8Ut-IJrWJrTV8FdahOs1MG8iNN_bUULubvNMRbzkz98A2dkfc85dFvOLApTxQPrP8WwAt-HM_MGYfGwqR2fsPrbNSha-7UsSvNOGo2iTg26eHZBZw6xooZMEM9RQc_xTLlrX1_OLtcn7yWHkijs_SaW-qL4sf-X1em0SZ1_I5c_dKUSlRw
This is an internal url, I?m pasting it in case there?s an obvious encoding error or something.
3. I?m logging a few variables from my application's oidc controller which is throwing an error in the _handleLogin call.
```
return passport.authenticate(
service.getPassportOidcStrategyId({ provider, entity, subdomain }),
(err, user, info) => {
console.log(err, user, info);
_handleLogin({ ctx, err, user, info, onSuccess })
}
)(ctx);
```
The above is the same code that handles azure AD, and Google auth oidc integrations. In both those cases, err, user, info look like?
```
err: null
user: {
_id: myid,
email: 'mark.wissler@exaptive.com',
firstname: 'Mark',
lastname: 'Wissler',
enabled: true,
pending: false,
uuid: ?biguuidhere',
createdAt: timestamp,
updatedAt: othertimestamp,
activationCode: ?activationcodehere'
}
info: {}
```
When I try to log in with synapse, I see:
```
err: null
user: false
info: OPError: expected 200 OK, got: 401 Unauthorized
at processResponse (/opt/exaptive/cognet2/node_modules/openid-client/lib/helpers/process_response.js:48:11)
at Client.grant (/opt/exaptive/cognet2/node_modules/openid-client/lib/client.js:1208:26)
at runMicrotasks ()
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Client.callback (/opt/exaptive/cognet2/node_modules/openid-client/lib/client.js:458:24)
at async /opt/exaptive/cognet2/node_modules/openid-client/lib/passport_strategy.js:150:22 {
error: 'expected 200 OK, got: 401 Unauthorized'
}
```
I?m now putting debug statements in the oidc node module to see if I might find something wrong with the return from synapse, but I'm mostly just stuck.
Created by Mark Wissler MarkWissler Any luck, @MarkWissler ? > Getting firstname/lastname with the token. Should I do that via claims?
Yes, you can specify the 'given_name' and 'family_name' claims. For the complete list of available claims, see https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/oauth/OIDCClaimName.html
Users are not required to provide their first or last name, so these fields may be blank.
On a related note, Synapse provides a service in which a user can have their profile _validated_. (To learn more about the process, see https://docs.synapse.org/articles/accounts_certified_users_and_profile_validation.html.) While the 'given_name' and 'family_name' information can contain whatever a user chooses, the validated information has been checked by the Synapse Access and Compliance team, so you can take it as factual. Not every user goes through the validation process. If they do, then the 'is_validated' claim will come back 'true' and you can trust that the values that start with 'validated_*' , including 'validated_given_name' and 'validated_family_name', are factual. If 'is_validated' is 'false' then there will be no information in the 'validated_*' fields.
Hey Bruce! Yep! I had a few misconfigurations of our internal config things (sets of endpoints, etc.) to sort out.
So it's working for sure, but there's a lingering issue I'm running into that would be nice to sort out: Getting firstname/lastname with the token. Should I do that via claims? Any luck, @MarkWissler ? Thanks for your patience with me. Also the links. I'm learning more about oidc than I ever hoped to. Mark:
This is an easy fix. As explained [here](https://docs.synapse.org/articles/using_synapse_as_an_oauth_server.html), Synapse supports the claims request parameter, a JSON document containing the details of the user identity information you would like returned
You say above that this is the signin URL you specify:
```
https://signin.synapse.org/?client_id=100059&scope=openid&response_type=code&redirect_uri=https%3A%2F%2Flocal.exaptive.dev%2Fcnapi%2Flogin%2Fredirect%2Fsynapse%2Flocal&state=NNSF-RK27tQT_JLhgtN3JcDzRS7QQZrgCxX6Yr2ul30&nonce=CbVwu6vWs6_Qw_9e_2NrlRyDS5ma9Cat_zJoVdUwoNo
```
This URL has no claims request parameter. If you want to receive the 'email' claim in the ID token and in the subsequent userinfo responses, you would add this parameter to the URL:
```
claims=%7B%22id_token%22%3A%7B%22email%22%3Anull%7D%2C%22userinfo%22%3A%7B%22email%22%3Anull%7D%7D
```
There are many other claims you can request. See https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/oauth/OIDCClaimName.html for the complete list.
To understand the 'claims' parameter in OpenID Connect, see https://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter Thanks a ton for the fast turnaround! I've gotten several steps further (mostly configuring endpoints and updating the client in synapse.) I've got to be on the last handful of issues here.
Error: Failed to find email in login provider data.
I'm trying to play a bit with our configs and debug on this side of course. Is there anything about the error message above that jumps out at you? (i.e. is it possible to get the user's email from the userinfo endpoint? Mark:
We have changed the Synapse token endpoint to return 200 status code instead of 201. Will you please try your Node.js openid client again and let me know the outcome?
Bruce Bruce,
That would be awesome. In the meantime we're still going to see if there's something I'm missing. Perhaps the library accepts a configuration of some sort. I'll report back, and will stay tuned for developments on your side as well.
Mark it has just been brought to my attention that the OAuth 2.0 spec' ([Sect. 5.1](https://tools.ietf.org/html/rfc6749#section-5.1)) indeed specifies a 200 status response. So I am inclined to change Synapse to bring it in spec'. I'm going to run one of our better engineers through what I'm seeing and make sure there's nothing we can do in terms of transforming the response and checking out other openid clients. I expect I'll check back in near the middle of next week, but will let you know if I have luck either way. Thanks! Brian, a quick search shows hundreds of openid clients. Unfortunately I don't known anyone who has used any of them, so I can't point to a specific one that I know will work. @brucehoff, is there another openid client that @MarkWissler should investigate using instead? Seems like the client should be flexible re: the 2xx level response returned? Thanks for all of the help here! I'm thinking the edit I made to https://github.com/panva/node-openid-client/blob/e4ecaf08b8ab92efac4e0d754c6ea4744562f00a/lib/client.js#L1251 must be affecting more requests than just the synapse return. I'm going to see if I might be able to re-encode the response in our application before it touches the library or something. Mark:
The error you report seems to say that your code received an unexpected 200 status. Below I list all the requests made by oauth client id 100057 or100059 in the past 24 hours:
Date|user agent|client id|Http Method|URI|Response code
2020-08-19|openid-client/3.12.2 (https://github.com/panva/node-openid-client)|100059|POST|/auth/v1/oauth2/token|201
2020-08-19|openid-client/3.12.2 (https://github.com/panva/node-openid-client)|100059|POST|/auth/v1/oauth2/token|201
2020-08-19|openid-client/3.12.2 (https://github.com/panva/node-openid-client)|100059|POST|/auth/v1/oauth2/token|201
The token endpoint returns 201, not 200. I wonder to what endpoint your code was making a request when this error occurred. Bruce,
I'm not sure what to do here, really. That's an open source library that we rely on and it's openid certified. I set up to edit that library and have everything linked to test the solution anyway.
Now I get the error:
```
{"status":"fail","statusCode":101,"city":"uuidhere","message":{"error":"expected 201 Created, got: 200 OK"},"stack":null}
```
Is there a different openid client I need to investigate replacing this one with? Even if I do find a solution by editing this library, my options are to: put in a PR and hope no one takes issue with it, or fork the library and maintain our own copy. Am I missing anything?
Mark,
Our records show that you made two valid requests to the Synapse token endpoint today, https://rest-docs.synapse.org/rest/POST/oauth2/token.html. This service returns an HTTP status 201 to indicate success. While the OAuth 2.0 spec' (https://tools.ietf.org/html/rfc6749#page-30) does not specify what status must be returned, we feel that 201 is the correct status when responding to a POST request since it indicates the creation of a new resource (the token), https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success. Further we have worked with other OAuth / OIDC clients which accept the 201 response.
Can you adapt your client to accept the 201 response status? I took just a quick look but I think the change would be here:
https://github.com/panva/node-openid-client/blob/e4ecaf08b8ab92efac4e0d754c6ea4744562f00a/lib/client.js#L1251
(which calls https://github.com/panva/node-openid-client/blob/e4ecaf08b8ab92efac4e0d754c6ea4744562f00a/lib/helpers/process_response.js#L38)
from
```
processResponse(response);
```
to
```
processResponse(response, { statusCode: 201});
```
Bruce,
As I debugged I realized I had a trailing quote from grabbing the secret out of postman. That didn't get me further, but was a nice sanity check. Now the error on redirect is:
{"status":"fail","statusCode":101,"city":"uuidhere","message":{"error":"expected 200 OK, got: 201 Created"},"stack":null}
Bruce,
I do have client id and secret set for the app. I'll work on double checking that something isn't going wrong, but it looks configured properly (i.e. the same as how we configured google/ad.)
Mark,
You say you got:
```
'expected 200 OK, got: 401 Unauthorized'
```
This probably means you have not configured your Ouath client id (100059) and secret in your code. Instructions for getting a client secret are here: https://docs.synapse.org/articles/using_synapse_as_an_oauth_server.html I'm in over my head, I think so I'm going to do my best to describe my understanding of the flow and situation, hopefully this will address your question. Let me know if it doesn't.
We use an OIDC library that manages the finer points of calling the endpoint. Here's the rough flow as I understand it:
1. We have a route like /cnapi/login/synapse/local that resolves to a library call that triggers a redirect to the Synapse signin url , so that looks like a redirect with some query params on what/where to return (which must be one of our client?s redirect_uris) e.g. https://signin.synapse.org/?client_id=100059&scope=openid&response_type=code&redirect_uri=https%3A%2F%2Flocal.exaptive.dev%2Fcnapi%2Flogin%2Fredirect%2Fsynapse%2Flocal&state=bigstring&nonce=bigstring
2. The user logs in and is then redirected to the redirect uri from the query param above and they return to our app with a url like this:
Synapse version of this: https://local.exaptive.dev/cnapi/login/redirect/synapse/local?state=bigstring&code=bigstring
Google version of this: https://local.exaptive.dev/cnapi/login/redirect/google/exaptive?state=bigstring&code=bigstring&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20openid%20https://www.googleapis.com/auth/userinfo.email&authuser=1&hd=exaptive.com&prompt=none
The error is thrown from the OIDC library we use to handle the redirect and auth, so I'm wondering if this is a misconfigured client or if there's something bigger like our api eating some of the query params.
The library we are using is here: https://www.npmjs.com/package/openid-client Mark, does your code call Synapse's userinfo endpoint and, if so, in what format are you expecting the response?