Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenID connect fails with Azure AD #153

Closed
stevenrombauts opened this issue Apr 30, 2019 · 24 comments
Closed

OpenID connect fails with Azure AD #153

stevenrombauts opened this issue Apr 30, 2019 · 24 comments
Assignees
Labels
bug Something isn't working support Further information is requested or user requires assistance
Milestone

Comments

@stevenrombauts
Copy link

stevenrombauts commented Apr 30, 2019

OpenID connect fails with Azure AD

Description

Hi! Following the 1.6.0 update that fixes the OpenID Connect issue mentioned in #36, I'm still unable to use Azure AD for authenticating. The OpenID Connect button will send me to microsoft login page, which redirects back correctly to FusionAuth, but then fails with the following message:

A request to the OpenID Connect Token API has failed. Unable to complete this login request. The authentication request has failed. The login request failed.

The redirect URL looks like this:

/oauth2/authorize?client_id=60f26389-8465-4632-9d1f-98918ad208b9&grant_type=authorization_code&metaData.device.name=Mac+Chrome&metaData.device.type=BROWSER&redirect_uri=http%3A%2F%2Fjoomla.box%2Faci%2Fweb%2F&response_type=code&state=5cc8842613bd0&timezone=Europe%2FLondon

I'm not sure how to debug this further. Any tips on this are most appreciated :)

Steps to reproduce

Steps to reproduce the behavior:

  1. Create an App Registration on Azure AD (possible with free trial account)
  2. Configure OpenID Connect (see screenshot below)
  3. Attempt to login from your app via the Login with Azure AD button.
  4. Login with your Microsoft account.

Expected behavior

I would expect to be authenticated successfully and redirected back to my application. Instead, I get an error about a failed request to the OpenID Connect Token API.

Screenshots

OpenID Connect configuration:

openid connect config

Flow:

2019-04-30 21 45 50

Platform

  • Chrome Version 73.0.3683.86

Additional context

Thanks for your help!

@robotdan
Copy link
Member

Hi, thanks for reporting this issue. I apologize for the inconvenience.

Another user reported a similar issue, I think Microsoft is sending back a field in the Token Response that is not specified by OpenID Connect.

FusionAuth should probably allow for some flexibility in what the IDP returns in this HTTP response.

If you review the logs, do you see an exception like this? /usr/local/fusionauth/logs/fusionauth-app.log

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ext_expires_in" (class io.fusionauth.domain.oauth2.AccessToken), not marked as ignorable (7 known properties: "expires_in", "scope", "id_token", "userId", "access_token", "token_type", "refresh_token"])
 at [Source: (BufferedInputStream); line: 1, column: 62] (through reference chain: io.fusionauth.domain.oauth2.AccessToken["ext_expires_in"])

In this example ext_expires_in is coming back on the JSON response from Azure AD which is what is causing the issue.

If this is what you're seeing, I have a fix that will go out in a patch release shortly. If your log looks different, can you attach it to this issue?

@robotdan robotdan self-assigned this Apr 30, 2019
@robotdan robotdan added support Further information is requested or user requires assistance bug Something isn't working labels Apr 30, 2019
@stevenrombauts
Copy link
Author

Hi @robotdan, thanks for your quick response! I had a look at the logs and I'm seeing two errors being logged. They seem to be happening randomly:

  1. One is the ext_expires_in field you described above,
  2. The second one is Read timed out

I've tried a couple of consecutive login attempts, and I get both errors randomly. I've attached my log file: fusionauth-app.log

@robotdan
Copy link
Member

Ok, great thanks for the additional information. The ext_expires_in issue is for sure the same, the other exceptions are likely a side effect of the former.

I should have a patch out for the issue shortly. I have confirmed with the other user that encountered this issue that my patch works.

@robotdan robotdan added this to Backlog in FusionAuth Issues via automation Apr 30, 2019
@robotdan robotdan added this to the 1.6.1 milestone Apr 30, 2019
@stevenrombauts
Copy link
Author

@robotdan Ok, great, thanks again. I'll be happy to test that patch as soon as its available then :)

@robotdan robotdan moved this from Backlog to Code complete in FusionAuth Issues May 2, 2019
@robotdan robotdan moved this from Code complete to Done in FusionAuth Issues May 2, 2019
@robotdan
Copy link
Member

robotdan commented May 2, 2019

Available in 1.6.1

@robotdan robotdan closed this as completed May 2, 2019
@stevenrombauts
Copy link
Author

@robotdan Thanks, I've upgraded and tested this again and the ext_expires_in error is gone. However, the read timed out one is still present. The error shown on the login UI is also still the same.

Here's a recent log excerpt: fusionauth-app.log

Want me to create a new ticket for this?

@robotdan
Copy link
Member

robotdan commented May 14, 2019

Hi @stevenrombauts, it does seem to be a different issue. But we can work it here if you'd like.

For whatever reason we get a socket timeout from the Microsoft endpoint. https://login.microsoftonline.com/common/oauth2/v2.0/token

May 10, 2019 10:56:19.664 AM ERROR i.f.a.s.authentication.OpenIdConnectIdentityProviderAuthenticationService - Call to OpenIDConnect [https://login.microsoftonline.com/common/oauth2/v2.0/token] API failed. Status code [-1].
May 10, 2019 10:56:19.666 AM ERROR i.f.a.s.authentication.OpenIdConnectIdentityProviderAuthenticationService - Unable to parse OpenIDConnect response. Exception encountered
java.net.SocketTimeoutException: Read timed out

Can you show me each endpoint you have configured in the OpenID Config for the authorize, token and userinfo fields? Or are you using the auto discovery with the issuer field?

On this site https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow it seems to indicate that your URLs should be something like (using a {tenant} value)

Authorize: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
Token: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

The https://login.microsoftonline.com/common/ prefix seems to be a default redirect location for Azure AD? This is the value I'm seeing in the logs, so perhaps the URLs are not configured correctly in FusionAuth?

@stevenrombauts
Copy link
Author

stevenrombauts commented May 15, 2019

Thanks @robotdan for looking into this further.

I tried replacing common with our tenant name, and that no longer triggers the read timed out error. However, the following error is now shown:

An email address was not provided for the user. This account cannot be used to login, unable to complete this login request. The authentication request has failed. The login request failed.

I've extended the scope values to read openid email profile, which should return all the required information.

I am also using the auto-discovery feature. I have now also tried configuring each endpoint manually (based on the values from https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration as well as the one for our tenant).

I'm not sure why the common endpoint wouldn't work, it's a valid endpoint to use with multi-tenant applications. I have used this endpoint in OAuth2 flows before. It's also mentioned as a valid value in the Azure AD OpenID connect docs

@robotdan
Copy link
Member

Great, glad that helped. I have no idea why the other endpoint would not work. But if we are getting a socket timeout, they must not be responding to our connection request for some reason.

FusionAuth will require an email address claim to be returned so we can complete the reconcile process.

Depending upon your configuration, they may not be sending back the email address, or not sending it back in the registered claim email.

https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens
https://docs.microsoft.com/en-us/azure/active-directory/develop/id-tokens
https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims

It does look like in the newer versions, the email claim is returned when openid or email scopes are requested. I am not very AD smart, so I may not be able to assist much with this. It sounds like there may be additional configuration required to get email for managed users.

If the email address is returned but using a different claim you cannot modify your configuration to change that, you can map it using a lambda.

To build a lambda, navigate to Settings --> Lambdas and create a new lambda of type OpenID Connect reconcile.

Your lambda may look something like:

function reconcile(user, registration, jwt) {
  // Dump out the contents of the JWT from Microsoft to the event log for debug
  // You can use this output in the event log to see what you have available.
  console.info(JSON.stringify(jwt, null, 2));

  // Example, if the email address is returned in the 'foo' field, then set that value to user.email
  user.email = jwt['foo'];
}

Then assign that lambda in your OpenID Configuration. You can use the Event Log (Settings --> Event Log) to see any errors that occur, and you can use console statements in the lambda to debug, these will also show up in the event log)

@plunkettscott I think you got AD working ok with OpenID Connect, any tips to share with @stevenrombauts ?

@stevenrombauts
Copy link
Author

@robotdan Thanks again for your help! It works fine if I use the v1.0 of the API, then email is included and log in works.

v2 doesn't include it all and so far I have not been able to figure it out yet. But it's definitely related to way the Microsoft account and Azure AD is configured, not FusionAuth.

Thanks again!

@robotdan
Copy link
Member

Thanks for the update @stevenrombauts, we'll try to do some additional testing with v2 to see if we can do anything to be more compatible, or build out the documentation on how it needs to be configured to work with FusionAuth.

We are in the middle of a feature release, but once that is out, we'll be circling back to documentation. I hope to get several common OpenID Connect providers documented for use with FusionAuth. So I'll add Azure AD v1 and v2 to the list to test out and document.

Thanks!

@RPSimon
Copy link

RPSimon commented Jul 6, 2019

I think I found some more information about this issue. I searched the whole day for some more information, and this is what I found.

I did a setup similar to @stevenrombauts. I used the endpoint

https://login.microsoftonline.com/common/oauth2/v2.0

It works, but only for Work Accounts who have an Office 365 License. Apparently the mail claim is mapped to the "primary_smtp_address" attribute on the Azure AD. And this attribute is filled by Exchange/Office365. So only when a user has an "primary_smtp_address", the mail claim is sent. ( I cannot find the documentation for this anymore )

You can apparently create custom claims in you Azure App Registration: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims
But this can only be done with private apps ( See "optional_claims" on this link: https://docs.microsoft.com/en-gb/azure/active-directory/develop/reference-app-manifest )

So I'm stranded at this point at the moment. If the user has an Office365 account, the login works. If no Office365 is active, the error "An email address was not provided for the user" occurs.

I'm still trying to find an option to let Azure send a email address for non-Office365 accounts. I will keep you guys posted.

@robotdan
Copy link
Member

robotdan commented Jul 6, 2019

Thanks for that information @RPSimon that is great.

If there is a consistent way to get an email even if the claim name changed that can be mapped using a FusionAuth lambda.

@RPSimon
Copy link

RPSimon commented Jul 8, 2019

@robotdan, is there an option to do an external call in those lambda functions? I could fix it, if I could call there Graphs. An other option is not possible at the moment apparently.

@robotdan
Copy link
Member

robotdan commented Jul 8, 2019

@RPSimon we do not currently support making external calls in a lambda. Unless an email address is available we cannot reconcile the user during login.

@pendenga
Copy link

Just wanted to comment on our resolution to this same issue. We noticed that since this discussion, there's a new field in the OpenID Connect Configuration Settings screen for "Email Claim". (we noticed the difference in the screenshot). We noticed in the JWT response from Azure (v.1) the email claim was labeled 'upn', so in this configuration we put "upn" in the "Email Claim" field. This made it work for us without using lambdas or any other custom config on the Azure side.

Hope that helps, and thanks FusionAuth for making that email claim configuration available.

@pendenga
Copy link

Just wanted to comment on our resolution to this same issue. We noticed that since this discussion, there's a new field in the OpenID Connect Configuration Settings screen for "Email Claim". (we noticed the difference in the screenshot). We noticed in the JWT response from Azure (v.1) the email claim was labeled 'upn', so in this configuration we put "upn" in the "Email Claim" field. This made it work for us without using lambdas or any other custom config on the Azure side.

Hope that helps, and thanks FusionAuth for making that email claim configuration available.

Another update. The above is for Active Directory Version 1 using this address for the issuer in the FusionAuth config: https://login.microsoftonline.com/[azure-tenant-id]

We were able to configure it for Active Directory Version 2 by using this address for the issuer in the FusionAuth config: https://login.microsoftonline.com/[azure-tenant-id]/v2.0. You can check this with your Azure tenant id by loading the well-known configuration https://login.microsoftonline.com/[azure-tenant-id]/v2.0/.well-known/openid-configuration. With this configuration we were able to set the email claim in the FusionAuth config back to "email".

@robotdan
Copy link
Member

robotdan commented Jul 30, 2020

Thanks for the update @pendenga - if I understand you correctly, you have been able to get AD v2 configured using OpenID Connect?

If that is correct, then our warnings about v2.0 in our Azure OpenID Connect documentation is no longer accurate?
https://fusionauth.io/docs/v1/tech/identity-providers/openid-connect/azure-ad

Edit: opened an issue with doc to track if we need to make changes. FusionAuth/fusionauth-site#156

@pendenga
Copy link

I believe you can remove the warning about AD V2 on that page in your documentation. I'd also update the screenshot of your Edit Identity Provider page to include the "Email claim" field. That was the key for us to use AD V2.

@robotdan
Copy link
Member

Thanks for the update @pendenga. When we get a chance we'll re-test this config and update the doc! Thanks for the assist!

@robotdan
Copy link
Member

robotdan commented Dec 2, 2020

Docs have been updated and tested against AD v2.
https://fusionauth.io/docs/v1/tech/identity-providers/openid-connect/azure-ad/

Thanks!

@dvins
Copy link

dvins commented Aug 19, 2021

@robotdan Just FYI, we ran into the issue with the v2 Azure endpoint tonight -- the docs at the above URL do not specify the .../v2.0 suffix on the FusionAuth issuer config. Without this part of the path login via this IdP fails with the "An email address was not provided for the user." error. Upon adding it, everything works fine.

@robotdan
Copy link
Member

Thanks @dvins ! We’ll take a look at the doc.

@robotdan
Copy link
Member

robotdan commented Aug 19, 2021

For anyone else reading this issue, the issuer (authority) used for discovery:

  • Azure AD v1 : https://login.microsoftonline.com/{tenantId}
  • Azure AD v2: https://login.microsoftonline.com/{tenant}/v2.0

Sources:

Not sure where the v1 issuer is documented, but I believe that works. We'll update the doc.

Edited
Added this to doc:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working support Further information is requested or user requires assistance
Projects
FusionAuth Issues
  
Delivered
Development

No branches or pull requests

5 participants