API Authorization with lock 10 & angular 4

I have an Angular 4 SPA that needs to call my API.

I set up a client for my SPA, and an API.
I also need to add permissions from the Auth0 authorization extension to my access_token, so I set up the corresponding rule to add the permissions to the token in a unique namespace.

In my Auth0 lock configuration, I added the audience for my API. In the lock.on('authenticated', ...) callback I extract the id_token and send it to the /tokeninfo endpoint to retrieve some details to display in the SPA.

The main issue:
For users logging via a social media provider (Google, Twitter) I get back the id_token and the JWT access_token and everything works as intended. However, a user logging in using the Auth0 username-password just gets back an opaque access_token (no JWT), that can’t be validated on the API side.

I then tried to set oidcConformant: true on my Auth0 lock options object.
Now, after that, the Auth0 username-password login works. However, now for users logging in via social media providers, the lock.on('authenticated', ...) callback is not fired.

It seems I can have either Auth0 username-passwords users working, or only social media users, but not both at a time.

What do I need to change for this to work?
I am using Auth0 lock 10.14.0 from the aut0 cdn, and the source code for my authentication service is here: https://github.com/canonn-science/CanonnApi/blob/auth0-api/CanonnApi.Frontend/src/app/services/api/authentication.service.ts

Update: For the social media accounts I get an authorization error, and the message is Nonce does not match..
I thought the nonce would be handled by Auth0 lock transparently? Do I have to manage that manually now?
Additional info: The nonce that is sent with the request to the /authorize endpoint is the same that is returned within the id_token. And it is also the same as the value that Auth0 lock stores in the browsers local storage under the key com.auth0.auth./.

Update 2: I went on and tried to handle the nonce myself. I created a new nonce and set it to

lockOptions = {
    oidcConformant: true,
    autoclose: true,
    auth: {
         responseType: 'id_token token',
         params: {
            nonce: 'nonce_here',
            scope: 'openid',
        },
    },
};

I can confirm that the nonce I set there is correctly transferred to the /authorize endpoint, and again it is the same value that is returned in the id_token, however I still get the message Nonce does not match. in the error event.

Focusing on the last problem, the authenticated event not firing, I would recommend for you to always handle that event and also the authorization_error event. They are mutually exclusive so if the authenticated one is not being fired it may be due to an error response being returned. If that’s the case then please update your question with the returned error response.

Ah, thanks for that hint. I indeed get an authorization_error event for the twitter and google users, and the message says Nonce does not match..

Locally, using a similar configuration as yours I was only able to reproduce the error when I passed a nonce during the call to lock.show(). A quick look to your code suggests this is not likely to be the case, nevertheless if the current code is not exactly the same you linked to you may put a console.log to output the options object you pass to lock.show to rule out this scenario.

Okay, I put debug outputs where I create a new Auth0Lock instance, and where I call .show().

When I initialize the instance, the options are {“oidcConformant”:true,“autoclose”:true,“auth”:{“redirectUrl”:“http://localhost:4200”,“responseType”:“id_token token”,“params”:{“scope”:“openid”,“audience”:“https://api.canonn.technology/”}}}

(Theme was removed here for length). Then when I call .show() the options are extended with a state of / (to redirect internally in the app after login).

After the login redirect, a new instance is created identically, and the Nonce error is emitted.

This does not explain why you would get a nonce does not match error when not trying to specify a custom nonce anywhere (this was the part that I could not reproduce). However, if you want to try to workaround the error you got by providing your own nonce value then you can try the following:

var options = { auth: {} };

options.autoclose = true;
options.oidcConformant = true;

options.auth.redirectUrl = window.location.origin;
options.auth.responseType = "id_token token";
options.auth.nonce = '...'; // Your nonce here

var lock = new Auth0Lock("client_id", "domain", options);

When showing Lock you would pass the additional parameters:

var options = { auth: { params: {} } };

options.auth.params.state = "..."; // your state here
options.auth.params.scope = 'openid';
options.auth.params.audience = "..."; // your API identifier

lock.show(options);

Have in mind that the options passed to the show method are not equivalent to the ones passed to the constructor so you should not be extending them and passing the same object (it’s recommended that you use different objects). The option for the show method are meant for you to override/pass only specific options and one the option that you can override is the auth.params.

I’m assuming you want want to pass a specific state at the time of showing Lock so you should pass all your auth.params when showing the Lock and in an independent object. With the above configuration I had no issues locally. Also, the usage of Lock 10 with OIDC conformance is still not yet formally documented so this should be much more straightforward when that is put on paper.

I tried with very similar configuration in my local application and did not get the error in that situation. I only reproduced the error when I also passed a custom nonce parameter in lock.show, but you’re just passing scope, audience and state to that method so your issue may be different. I replied with an answer to try to workaround it by providing your own nonce; it’s similar to what you tried, but the nonce needs to be specified at the auth level, not at the auth.params.

Okay, now I’m even more confused than before.

In my first question I had the problem that I got back an opaque token for a user using auth0 username-password logins. Now that doesn’t happen anymore and I get back a JWT token. I can’t reproduce the previous behaviour anymore at all. Did that change on your end somewhen today?

However, even when splitting up the options object between an options object to create an Auth0Lock instance (without auth.params) and the call to show (just with auth.params there), I still get the Nonce does not match error for twitter and google users.

Ah, I moved the nonce to auth, from auth.params, and that seemed to help (at least a bit).
I will investigate further to get that running smoothly.

Thank you. All problems are sorted out.
When I use a custom nonce and add it to auth instead of auth.params, and when I separate the options objects for creating the Auth0Lock instance and for calling .show() into distinct objects, it works.