OpenID Connect issue with Azure AD

We are getting a client secret error.

(oidc) Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided.
Trace ID: 9748cd74-7a0a-4ac5-8802-b2072c0b0d00
Correlation ID: f6677275-43f3-4d73-a0d2-ec6187a5e26a

Has anyone seen this issue before? We’re using Azure AD as our provider and use it successfully with other OIDC clients.

Well we got past the error, simply by regenerating the key. Looks like there a bug in the code, maybe it’s not being escaped properly, but it’s hard given there isn’t much to tell us that in the logs. There another issue though, it looks like the email is not being pulled across in the bootstrap process.

3 Likes

Can you share the old key (assuming it is completely deactivated). I can check for any encoding issues.

Does your ‘userinfo endpoint’ definitely supply the email address under the “email” key in the JSON response?

2 Likes

Not sure how to tell, how would I check that?

It can be tricky, the best way will be for us to add some proper debugging information to the plugin.

Having a quick look at the Azure AD documentation, it looks like you need to request the email scope to obtain the email: Microsoft identity platform scopes, permissions, and consent | Microsoft Docs

So I think the openid_connect_authorize_scope should be

openid email

You may also want to add “profile”, depending how much information you want to pull in.

2 Likes

Yes, I’ve tried ‘openid email’ and 'openid email profile" and all combinations of the two. It is getting some information because it’s populating the name. Could there be something in the logs I can look for?

Selection_056

1 Like

Unfortunately there’s nothing in the logs at the moment. I have some time this afternoon so I’ll add some debug logging to the plugin - it will help these kinds of situations a lot!

Thanks a tonne, I will wait for that. While I have you, one last question. If we can get this working, the next part will be to migrate an existing instance, where we were just using plain-old LDAP for auth. Is there a bulk approach to link existing users to an OIDC associated account? How would be go about making this a simple transition for existing users? We don’t want to lose all the content. Thoughts?

If the email addresses match, then accounts will be linked up automatically. If not, then you can use the rails console to migrate the associations - that would rely on the UIDs being the same for OpenID-connect as LDAP

1 Like

Here we go:

https://github.com/discourse/discourse-openid-connect/commit/94bba5f710febf1c511c7cbfc94bdb0c27cd0281

Enable the new openid connect verbose logging site setting, and you should see some useful information in your logs. For example:

The userinfo response line should show you whether the endpoint is returning an email address correctly

5 Likes

Fantastic! I’ll grabbed it and here is what I am seeing in the log as part of the userinfo response.

Selection_057

Also note, the discovery document shows

scopes_supported:
  - openid

So it looks like the userinfo endpoint does not include the email address. Maybe there is some configuration that can be done in Azure AD so that it provides the email?

Is the email address included in the JWT?

1 Like

Selection_058

Interestingly, we use the same configuration for other apps where Azure AD is the IDP and those applications seem to pull the email just fine. Admittedly, I don’t know all the details of those products and how they accomplish that.

1 Like

Hmm… have you tried putting the email scope in both the openid_connect_authorize_scope setting AND the openid_connect_token_scope setting?

Yes, just tried ‘openid email profile’ in both. Same result.

I also found this post, which may speak to the problem?

1 Like

From that link:

Note that the e-mail address may not be returned in an email claim: in my case (once I got it working) it’s coming back in a name claim.

That is indeed what we’re seeing - so it sounds like AD does not quite comply with the openid-connect specification :cry:. If you can manage to configure AD to return it in the email claim, that would be the best solution. However, it looks like even microsoft’s own ruby implementation hacks around the problem:

You could try GitHub - discourse/discourse-azure-ad instead (which uses GitHub - marknadig/omniauth-azure-oauth2 under the covers)

If you really want to use the openid-connect plugin, you could write another plugin to ‘trick’ our openid-connect plugin into using the upn for the email address. Note that this would not be a ‘supported’ configuration, but if you have some ruby experience you could do something like this (not tested):

after_initialize do
  module SwapNameEmail
    def after_authenticate(auth_token, existing_account: nil)
      auth_token[:info][:email] = auth_token[:extra][:raw_info][:upn]
      super
    end
  end

  ::OpenIDConnectAuthenticator.class_eval do
    prepend SwapNameEmail
  end  
end
3 Likes

Would it not make sense to add that or condition to the base plugin given that make people will be using Azure AD as their provider? I know it’s not pure, but I’m guessing that’s how the other clients do it so that they can support Azure AD, which is probably the most widely used IDP in the corporate world?

2 Likes

Possibly… the (admittedly small) risk would be if another provider decided to use the claim upn for something else (it is not mentioned in the openid-connect specification at all).

Out of interest, are any of the other tools you have connected to AD open-source? It would be interesting to look at their implementations.

1 Like