go-oidc icon indicating copy to clipboard operation
go-oidc copied to clipboard

Auth provider creation does not allow for a URL query string

Open federicobozzini opened this issue 4 years ago • 8 comments

This is foundamentally another issue with Azure, but different from the ones raised in the past regarding the problem with a different issuer returned by Azure.

It would be useful to be able to use a query string in the issuer URL, this is necessary with Azure B2C when policies are used .

In more details when a Azure policy is used the well known URL needs to be in this format:

https://login.microsoftonline.com//{tenantID}/v2.0/.well-known/openid-configuration?p={policyName}

Due to how the well known URL is built at the moment it is unfortunately not possible to add a parameter to the URL.

My proposal would be to allow the issuer to contain a query string (EG: https://login.microsoftonline.com/organizations/v2.0/?p={policyName}) or allow a third parameter to the NewProvider method. The second option would break backward compatibility so it might be more problematic.

I can work on this change myself if you think it might OK to include it in this library.

federicobozzini avatar Mar 02 '21 10:03 federicobozzini

Dup of https://github.com/coreos/go-oidc/issues/233?

ericchiang avatar Mar 02 '21 17:03 ericchiang

Thanks, I didn't see that. It's surely a duplicate.

As you correcly point out, Azure B2C is not following the OIDC standard. Do you think it might be worth adding something like what you suggested in the other issue?

type Discovery struct {
    IssuerURL    string
    DiscoveryURL string
}
func (d *Discovery) NewProvider(ctx context.Context) (*oidc.Provider, error)

federicobozzini avatar Mar 02 '21 17:03 federicobozzini

Arguably we do have that https://github.com/coreos/go-oidc/issues/233#issuecomment-582233909

Does the fix in that comment work? I think we need to document that workaround more prominently.

ericchiang avatar Mar 02 '21 18:03 ericchiang

That fix would work.

As far as I see it makes necessary for the library user to call the well-know URL autonomosly which means having to rewrite a bunch of utilities for making http requests and unmarshalling the json response. It's just not ideal.

Said that, I understand why you might not want to support a non-standard implementation.

federicobozzini avatar Mar 05 '21 08:03 federicobozzini

@federicobozzini It turns out that you have to use a very specific issuer URL format:

provider, err := oidc.NewProvider(context.Background(), "https://yourname.b2clogin.com/tfp/yourtenantid/yourUserFlow/v2.0/") //REPLACE THIS WITH YOUR VALUE

Notice tfp and yourUserFlow above.

In order to make it work you have to:

  • in Azure go to: B2C -> User flows -> <your user flow> -> Properties -> Token compatibility settings -> Issuer (iss) claim and select the one that has tfp and your user flow in it.
  • when creating an auth URL, set the scope to your <clientID> value, cause otherwise you will get only id_token (without access_token) in exchange for provided code (per https://docs.microsoft.com/en-us/azure/active-directory-b2c/access-tokens#openid-connect-scopes). Notice that when you click on "Run user flow" to test it from the Azure Portal, scope gets prepopulated with openid

ziemekobel-ef avatar Apr 09 '21 10:04 ziemekobel-ef

@ziemekobel-ef Thank you for your help.

Unfortunately in my case I don't have access to the Azure configuration panel, so I cannot easily test your solution.

federicobozzini avatar Apr 19 '21 08:04 federicobozzini

Thanks @ziemekobel-ef for your solution. This fixed it for us.

davidspiess avatar Apr 30 '21 09:04 davidspiess

I've opened https://github.com/coreos/go-oidc/issues/344 for a broader conversation around Azure AD. If anyone from this thread has some insight, it'd be really appreciated

ericchiang avatar Jul 01 '22 20:07 ericchiang