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

BlazorBFFOidc and DevTunnel - Auth to MS Entra works for swagger SPA and nearly working for Blazor website #55537

Closed
1 task done
swegele opened this issue May 5, 2024 · 12 comments
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved

Comments

@swegele
Copy link

swegele commented May 5, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

First let me say a big YAY! With https://localhost/ I got Aspire/Blazor/API auth working with MS Entra for Customers (preview).
Thank you so much for this sample code and docs!


Side note: For the curious - after using this authority:
oidcOptions.Authority = "https://-mydomain-.ciamlogin.com/-tenantid-/oauth2/v2.0/authorize";

...the code automatically tries to get OIDC meta-data from the wrong url.
So I had to do this manually:
oidcOptions.MetadataAddress = "https://-mydomain-.ciamlogin.com/-tenantid-/v2.0/.well-known/openid-configuration";


Anyway, now I have setup a dev-tunnel with 2 ports to reach BOTH the WebAPI swagger page AND the Blazor web site when I fire up Aspire. I start the dev-tunnel in aspire AppHost program.cs like so:
var mydevtunnel = builder.AddExecutable("my-dev-tunnel", "c:/tools/devtunnel.exe", builder.AppHostDirectory, "host");

Credit to @SteveSandersonMS comment here
Works great!. I can navigate to the devtunnel from a browser:

WebAPI

  • nav to swagger (success)
  • authenticate with MS (success)
  • redirect back to site (success)
  • start exploring secure endpoints :-)

Blazor Website

  • nav to Blazor site (success)
  • authenticate with MS (success)
  • redirect back to site (fails)
    No matter what I try, after coming back from Microsoft, I always end up seeing that the url/path got changed somehow back to https://localhost:7327 even though it start as https://xxxxx-7182.usw3.devtunnels.ms/ when went to MS for auth.
    Thus the signin-oidc page/middleware kicks out a 500 error saying "failed to correlate".

I have quadruple checked all the combinations of Azure AppRegistration Redirect URLs - those are all fine.

I think it is related to how the code does the redirect to auth and back via the following:

LoginLogoutEndpointRouteBuilderExtensions
and
app.MapGroup("/authentication").MapLoginAndLogout();

But I can't figure it out.

I think this would be REALLY cool to prove/show that the dev Inner-Loop with Aspire can include DevTunnels.
I'm half way there with it working for the WebAPI swagger/OpenAPI site.

cc: @guardrex dotnet/blazor-samples#288

Expected Behavior

Just like it works with Swagger index.html page...the Blazor Website and DevTunnel should also work leaving me logged in to the site with the proper url after coming back from auth against MS entra.

Steps To Reproduce

See above

Exceptions (if any)

Authorization failed - failed to correlate

.NET Version

8.0.300-preview.24203.14

Anything else?

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label May 5, 2024
@mkArtakMSFT
Copy link
Member

Thanks for contacting us. It looks like there are a few issues here, so let's address those in order:

  1. When specifying the Authority, you shouldn't have to explicitly specify the MetadataAddress. We think this is due to you having specified wrong Authority. Try this instead:
    oidcOptions.Authority = "https://-mydomain-.ciamlogin.com/-tenantid-/oauth2/v2.0";
  2. As for the redirect failure, we believe you have to configure the return URL in your app configuration in the Azure Portal.

Let us know how this goes?

@mkArtakMSFT mkArtakMSFT added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label May 6, 2024
@swegele
Copy link
Author

swegele commented May 6, 2024

Thanks @mkArtakMSFT

Re: Issue 1:

I made the .Authority change as you indicated so now it is:
oidcOptions.Authority = "https://xxxx.ciamlogin.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/v2.0";

And when I click login the site gives this error

InvalidOperationException: IDX20803: Unable to obtain configuration from: 
'https://dotheinterviewcustomers.ciamlogin.com/-mytenantid-/oauth2/v2.0/.well-known/openid-configuration'

(It is adding a .../oauth2/... part in the path.

The Azure AppRegistration : Endpoints tab shows the following as the proper metadata url:
https://dotheinterviewcustomers.ciamlogin.com/-mytenantid-/v2.0/.well-known/openid-configuration
When I manually force it to use this in config then I get sent to MS to login.

EDIT: I just figured this was something to do with the MS Entra for Customers being in preview still?

@dotnet-policy-service dotnet-policy-service bot added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels May 6, 2024
@swegele
Copy link
Author

swegele commented May 6, 2024

@mkArtakMSFT

So this is interesting. On a whim I tried the authority to this:
oidcOptions.Authority = "https://-mydomainhere-.ciamlogin.com/-mytenantid-/v2.0";

That works to get me past that metadata error. I no longer have to set the meta data url:
YAY Cool - that solves Issue 1.


Now for Issue 2.
When I site sends me to Microsoft for auth here is the URL:

https://-mydomainhere-.ciamlogin.com/-mytenantid-/oauth2/v2.0/authorize?client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&redirect_uri=https%3A%2F%2Flocalhost%3A7237%2Fsignin-oidc&response_type=code...bla bla bla

Notice the query string variable "redirect_uri" is https://localhost/signin-oidc
I'm not sure how that got set that way because I was viewing the site through the dev tunnel at https://r2xxxxxx-7237.usw3.devtunnels.ms/

MS Auth works and MFA works...but obviously when redirected back to localhost it blows up.

Here is my Azure AppRegistration redirect URL (from manifest):

"replyUrlsWithType": [
		{
			"url": "https://r2xxxxxx-7237.usw3.devtunnels.ms/signin-oidc",
			"type": "Web"
		},
		{
			"url": "https://localhost:7237/signin-oidc",
			"type": "Web"
		}
	],

EDIT: Remember my swagger page is authorizing and redirecting just fine. I notice it sends the correct redirect_uri value to microsoft. So my gut says this Issue 2 is something to do with the LoginLogoutEndpointRouteBuilderExtensions not properly setting that value.

I wonder if this "TODO" is the culprit:

   private static AuthenticationProperties GetAuthProperties(string? returnUrl)
   {
       // TODO: Use HttpContext.Request.PathBase instead.
       const string pathBase = "/";

@swegele
Copy link
Author

swegele commented May 6, 2024

Update:

I tried changing the minimal API in several ways and no matter what I do the querystring variable redirect_uri that gets sent to microsoft is always https://localhost....

So just for giggles...I manually copied the correct value to that variable sent to microsoft:
...&redirect_uri=https%3A%2F%2Fxxxxxxxx-7237.usw3.devtunnels.ms%2Fsignin-oidc...

Hit enter. It did the auth. Then MFA. Then redirected back to my site and I get this error:

An unhandled exception occurred while processing the request.
OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'AADSTS500112: The reply address 'https://localhost:7237/signin-oidc' does not match the reply address 'https://xxxxxxxx-7237.usw3.devtunnels.ms/signin-oidc'

So it looks like on the way out AND on the way in, the site OIDC is always using localhost instead of the devtunnel.
If I DO NOT use the dev tunnel and simply go to the site like normal using localhost then everything works great.

@swegele
Copy link
Author

swegele commented May 6, 2024

It even ignores setting the querystring variable sent to MS even if I do this!

        return new AuthenticationProperties 
        {            
            RedirectUri = "https://xxxxxxxx-7237.usw3.devtunnels.ms/"
        };

I'm baffled.

@swegele
Copy link
Author

swegele commented May 6, 2024

This works! Manual set value in blazor Program.cs. This makes auth work front to back (which proves my AppRegistration was set correctly):

oidcOptions.Events = new OpenIdConnectEvents()
{
    OnRedirectToIdentityProvider = context =>
    {
        context.ProtocolMessage.RedirectUri = "https://xxxxxxxx-7237.usw3.devtunnels.ms/signin-oidc";
        return Task.FromResult(0);
     }
};

@swegele
Copy link
Author

swegele commented May 6, 2024

@mkArtakMSFT (sorry for many messages as I figured this out)

Issue 2 - Summary

OIDC to MS Entra works fine using aspire localhost link to the blazor app. But when I try same using a DevTunnel - the OIDC engine doesn't use the base path, but rather continues using localhost. True for both the "to MS" and the "back from MS" parts.

The only way I have gotten OIDC in blazor to FULLY work with devtunnel is to manually set BOTH of these uri:

FIRST (in program.cs of blazor server):

oidcOptions.Events = new OpenIdConnectEvents()
{
    OnRedirectToIdentityProvider = context =>
    {
        context.ProtocolMessage.RedirectUri = "https://xxxx-7237.usw3.devtunnels.ms/signin-oidc";
        return Task.FromResult(0);
    }
};

SECOND (in LoginLogoutEndpointRouteBuilderExtensions.cs):

 return new AuthenticationProperties 
 {            
     RedirectUri = "https://xxxx-7237.usw3.devtunnels.ms/"
 };

@guardrex
Copy link
Contributor

guardrex commented May 7, 2024

@mkArtakMSFT ... If @swegele's working approach in the last comment becomes the accepted approach, I can add a section to the end of the article on this. @swegele will see if I have the explanation correct. 👂

Based on Steve's comment 👇, I'll hold and watch 👁️.

@SteveSandersonMS
Copy link
Member

We discussed, and are not sure these workarounds should be required. We think it should just work without these workarounds, hence marking for investigation.

@SteveSandersonMS SteveSandersonMS added investigate and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels May 7, 2024
@SteveSandersonMS SteveSandersonMS added this to the .NET 10 Planning milestone May 7, 2024
@swegele
Copy link
Author

swegele commented May 8, 2024

We discussed, and are not sure these workarounds should be required. We think it should just work without these workarounds, hence marking for investigation.

Agreed @SteveSandersonMS. The workaround proved it "can" and "should" work which is comforting.
But just like the Swagger SPA correctly picks up the devtunnel host from the url...so should the blazor web app.
This ignoring of host part of address happens both with F5 and ctrl+F5.

I'm on
Aspire 8.0.0-preview.6
Microsoft.AspNetCore.Authentication.OpenIdConnect (8.0.4)

I set a breakpoint here:

OnRedirectToIdentityProvider = context =>
{
    context.ProtocolMessage.RedirectUri = "https://xxxxxxxx-7237.usw3.devtunnels.ms/signin-oidc";

Then walked backwards up the callstack - to here:

Microsoft.aspNetCore.Authentication.OpenIdConnect.
private async Task HandleChallengeAsyncInternal(AuthenticationProperties properties)

image

Very strange that Context is showing address at localhost because look at the URL in the browser window address:

image

@mkArtakMSFT
Copy link
Member

After some further discussion on this topic, we think the workaround you've landed on is indeed required.
That's because for DevTunnels there is proxying going on, but for the server, it still serves at localhost and has no understanding of the hostname that the proxy uses. Hence, the workaround is valid.

@mkArtakMSFT mkArtakMSFT closed this as not planned Won't fix, can't repro, duplicate, stale Nov 13, 2024
@mkArtakMSFT mkArtakMSFT added question ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. and removed investigate labels Nov 13, 2024
@guardrex
Copy link
Contributor

guardrex commented Nov 14, 2024

@mkArtakMSFT ... Does this rise to the level of placing a Troubleshoot section in the article with the full workaround guidance described by @swegele above ☝, or should I just add a cross-link to this PU issue in the existing Additional Resources section?

If taking either approach for coverage, I see this is explicitly discussing OIDC to MS Entra. Is this only a concern for the BWA+OIDC article?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved
Projects
None yet
Development

No branches or pull requests

4 participants