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

[Bug] AADB2C90088: The provided grant has not been issued for this endpoint after Reset Password #729

Closed
8 tasks
quisitive-crogers opened this issue Oct 28, 2020 · 19 comments
Assignees
Labels
b2c by design external v3_userFlow new B2C v3 user flow -> recommended checkbox in portal

Comments

@quisitive-crogers
Copy link

Which version of Microsoft Identity Web are you using?
Note that to get help, you need to run the latest version.

Where is the issue?

  • Web app
    • Sign-in users
    • Sign-in users and call web APIs
  • Web API
    • Protected web APIs (validating tokens)
    • Protected web APIs (validating scopes)
    • Protected web APIs call downstream web APIs
  • Token cache serialization
    • In-memory caches
    • Session caches
    • Distributed caches
  • Other (please describe)
    User is send to MicrosoftIdentity/Account/Error after resetting password.

Is this a new or an existing app?

This is a new app. I reproduced the error in a clean slate web app.

Repro
Included clean slate web app that is exhibiting the behavior.
TestApplication.zip

Expected behavior
Once user has reset their password, they should be redirected to login screen to log in with the new password.

Actual behavior
user is redirected to the MicrosoftIdentity/Account/Error page on the app which results in a 404 error. An exception is logged stating

MSAL.NetCore.4.21.1.0.MsalUiRequiredException: 
	ErrorCode: invalid_grant
Microsoft.Identity.Client.MsalUiRequiredException: AADB2C90088: The provided grant has not been issued for this endpoint. Actual Value : B2C_1_SA_SignupSignin and Expected Value : B2C_1_SA_ResetPassword

These are the packages I am referencing


    <PackageReference Include="Microsoft.Identity.Web" Version="1.2.0" />
    <PackageReference Include="Microsoft.Identity.Web.UI" Version="1.2.0" />

Possible solution

Additional context / logs / screenshots
Add any other context about the problem here, such as logs and screenshots.

@jennyf19 jennyf19 added the b2c label Oct 28, 2020
@quisitive-crogers quisitive-crogers changed the title [Bug] [Bug] AADB2C90088: The provided grant has not been issued for this endpoint after Reset Password Oct 28, 2020
@jennyf19
Copy link
Collaborator

@quisitive-crogers thanks for the repro. I tried w/our templates, and was not able to repro it. I would suggest building the app from one of the templates, so we can ensure all the correct pieces are there, and then let us know if the issue still repros.

dotnet new mvc2 --auth IndividualB2C

@quisitive-crogers
Copy link
Author

@jennyf19

I have narrowed it down by comparing with the template you suggested. It is one of these two that is causing the problem.

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
             .AddMicrosoftIdentityWebApp(Configuration, "AzureAdB2C")
    -->   .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "https://randomtenant.onmicrosoft.com/myapp-uat/access" })
    -->   .AddInMemoryTokenCaches();

I am assuming it has something to do with token validation, but I am unable to track it down.

@quisitive-crogers
Copy link
Author

quisitive-crogers commented Oct 28, 2020

Upon further debugging the flow is as such... the user is not yet logged in, as evidenced by the fact that context.Principal is null. Any thoughts here?

Specifically, line 152 of TokenAcquisition.cs is grabbing the userFlow from the context.Principal (which is null because the user has not yet authenticated having just left the reset password screen). Because that is null, it defaults to the DefaultUserFlow, which appears to be the SignUpSignInPolicyId. That is then apparently compared to the actual authority that is returned, which is the ResetPasswordPolicyId. Since they don't match, it throws the exception.

I would honestly expect the redirect to the sign in screen to happen before any attempt to get a downstream api token.

Incidentally, I was able to reproduce this with the bae template you provided earlier.

@jennyf19
Copy link
Collaborator

@quisitive-crogers thanks for the additional info, like i said i wasn't able to repro it, but will look into this more.
Seems related to this issue but we've since fixed it. I'll take a look. thanks again.

@quisitive-crogers
Copy link
Author

quisitive-crogers commented Oct 29, 2020

@jennyf19 thanks. This is heading into UAT next week, so I need to come up with a work around. Is there an example of how to manually acquire the API token at the controller level without the middleware?

@jennyf19
Copy link
Collaborator

@quisitive-crogers I tried the template for mvc2 (the one I sent above)...You should have this in the Startup.cs

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C"));
            services.AddControllersWithViews();
           services.AddRazorPages()
                .AddMicrosoftIdentityUI();
        }

and I'm not able to repro the issue still. Are you starting w/the mvc2 web app template and just changing the values in appSettings.json? If not, let's start there and then we can go incrementally. just a thought.

One other thing to try, is in the B2C portal, you can test out the user flows there directly to make sure they are set up properly:
image

@quisitive-crogers
Copy link
Author

quisitive-crogers commented Oct 29, 2020

@jennyf19 Yes, that much works. The problem appears when I add the DownstreamAPI pieces as shown.

            services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C"))
                .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "https://randomtenant.onmicrosoft.com/myapp-uat/access" })
                .AddInMemoryTokenCaches(); 

I pulled down this repo and referenced it directly and can confirm that this is being thrown by the code here, not by the userflow.

@jennyf19
Copy link
Collaborator

@quisitive-crogers ok. thanks for confirming. did you try this template: dotnet new webapi2 --auth IndividualB2C?

@quisitive-crogers
Copy link
Author

@jennyf19 yup. I can confirm that the problem occurs when using that template.

@quisitive-crogers
Copy link
Author

@jennyf19 Thinking on this a bit and testing with another app in the same organization that is working, I see that one difference is that the userflow that is working is the old style and the one I am using is the new recommended style. I don't know if that makes a difference.

For now, I am going to follow the steps here to see if I can manually retrieve the API tokens on demand.

@jennyf19
Copy link
Collaborator

@quisitive-crogers what is the "new recommended style"? Can you share a link to a doc?

@quisitive-crogers
Copy link
Author

This is what I mean. I will try creating a new password reset userflow in the "standard" fashion tomorrow to see if that works and report back.

image

@jennyf19
Copy link
Collaborator

@quisitive-crogers oh, interesting. I'll check w/our B2C team as well. I wasn't aware of changes made there. Thanks for noticing that, you're right, that could be the issue. I'll check back tomorrow w/you.

@quisitive-crogers
Copy link
Author

@jennyf19 I just tested against user flow built on that "standard" variant and everything operates as it should. I suppose for now, that is my best workaround, but I would be interested in seeing if this does get fixed in the future.

@jennyf19
Copy link
Collaborator

@quisitive-crogers thanks for the update. Will continue to sort this out w/the b2c team on our end. Will keep you posted.

@jennyf19
Copy link
Collaborator

@quisitive-crogers I'm not able to repro this w/the new policy (recommended), and we had someone from B2C try as well, and they are not able to repro. If you're still having the issue w/the recommended version, maybe send me an email and I can get you in contact w/someone from B2C to help you out.
jeferrie@microsoft.com

Going to close, as cannot repro, but feel free to reopen &/or send the email.

@jennyf19 jennyf19 added v3_userFlow new B2C v3 user flow -> recommended checkbox in portal no repro and removed blocked labels Dec 12, 2020
@xavier-90
Copy link

@jennyf19 I can reproduce this & have sent you an email with further details.

@jennyf19 jennyf19 reopened this Dec 12, 2020
@jennyf19 jennyf19 removed the no repro label Dec 14, 2020
@jennyf19
Copy link
Collaborator

@xavier-90 The issue is that a client secret is included w/the web app, but there is no call to a downstream web API. Because the client secret is included in the appsettings.json, it’s implied that a call to a downstream API will happen, so we request an auth code from AAD B2C, which then invokes MSAL .NET to redeem that code for an access token. But an access token isn't needed, as there is no call to a downstream web API. Need the id_token, which has information about the signed in user.

By removing/commenting out the client secret in appsettings.json, I was able to redirect correctly to the initial starting page because I only received the id_token, and not the code + id_token.

Closing as by design, but we will update the wiki. thanks for your help w/this one!

@xavier-90
Copy link

@jennyf19 I do occasionally use Microsoft.Graph "downstream" hence the client secret in the AzureAdB2C section. To avoid triggering the default behaviour I have now moved the secret to a separate section of appsettings.json.

Thank you for your support in getting to the bottom of this one!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
b2c by design external v3_userFlow new B2C v3 user flow -> recommended checkbox in portal
Projects
None yet
Development

No branches or pull requests

4 participants