dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.32k stars 9.97k forks source link

Blazor WebAsm 3.2.0 preview, release 2 - broken... #19787

Closed KeithBarrows closed 4 years ago

KeithBarrows commented 4 years ago

Describe the bug

Handling OIDC from a 3rd party. I believe I have everything setup correctly. When I try to login the app redirects to the Token Server I configured, asks for scope permissions and then redirects back (confirmed in fiddler). However, the \authorization\ page in the WebAsm keeps throwing this error:

https://localhost:5001/Home/Error?message=Method%20not%20found:%20%27Void%20Microsoft.AspNetCore.Authentication.OAuth.OAuthCreatingTicketContext.RunClaimActions(Newtonsoft.Json.Linq.JObject)%27.

Sorry, there's nothing at this address.

Maybe my claims are wrong and that is doing it? 3rd party docs here.

To Reproduce

My code on github

Method not found: 'Void Microsoft.AspNetCore.Authentication.OAuth.OAuthCreatingTicketContext.RunClaimActions(Newtonsoft.Json.Linq.JObject)'.

at SC.Dashboard.Shared.Auth.EsiAuthenticationMiddleware.<>c.<b0_0>d.MoveNext() in D:\Repos\Sandbox\SC.Dashboard\src\Shared\Auth\EsiAuthenticationMiddleware.cs:line 69 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine) at SC.Dashboard.Shared.Auth.EsiAuthenticationMiddleware.<>c.b__0_0(OAuthCreatingTicketContext context) at Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents.CreatingTicket(OAuthCreatingTicketContext context) at Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler`1.d11.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler1.d8.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.d12.MoveNext()

Further technical details

Runtime Environment: OS Name: Windows OS Version: 10.0.18363 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\3.1.102\

Host (useful for support): Version: 3.1.2 Commit: 916b5cba26

.NET Core SDKs installed: 1.1.11 [C:\Program Files\dotnet\sdk] 1.1.13 [C:\Program Files\dotnet\sdk] 2.1.202 [C:\Program Files\dotnet\sdk] 2.1.500 [C:\Program Files\dotnet\sdk] 2.1.503 [C:\Program Files\dotnet\sdk] 2.1.505 [C:\Program Files\dotnet\sdk] 2.1.602 [C:\Program Files\dotnet\sdk] 2.1.801 [C:\Program Files\dotnet\sdk] 2.2.103 [C:\Program Files\dotnet\sdk] 2.2.401 [C:\Program Files\dotnet\sdk] 3.0.100-preview4-011223 [C:\Program Files\dotnet\sdk] 3.1.100 [C:\Program Files\dotnet\sdk] 3.1.101 [C:\Program Files\dotnet\sdk] 3.1.102 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview4-19216-03 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 1.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0-preview4-27615-11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.0.0-preview4-27613-28 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download

Installed Version: Professional

ADL Tools Service Provider 1.0 This package contains services used by Data Lake tools

ASP.NET and Web Tools 2019 16.4.460.23317 ASP.NET and Web Tools 2019

ASP.NET Web Frameworks and Tools 2019 16.4.460.23317 For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0 16.4.460.23317 Azure App Service Tools v3.0.0

Azure Data Lake Node 1.0 This package contains the Data Lake integration nodes for Server Explorer.

Azure Data Lake Tools for Visual Studio 2.4.1000.0 Microsoft Azure Data Lake Tools for Visual Studio

Azure Functions and Web Jobs Tools 16.4.460.23317 Azure Functions and Web Jobs Tools

Azure Stream Analytics Tools for Visual Studio 2.4.1000.0 Microsoft Azure Stream Analytics Tools for Visual Studio

C# Tools 3.4.1-beta4-19614-01+165046097562cfe65b09c2e9a9d8f7cd88526f2c C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools 1.10 Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Fabric.DiagnosticEvents 1.0 Fabric Diagnostic Events

IntelliCode Extension 1.0 IntelliCode Visual Studio Extension Detailed Info

Microsoft Azure HDInsight Azure Node 2.4.1000.0 HDInsight Node under Azure Node

Microsoft Azure Hive Query Language Service 2.4.1000.0 Language service for Hive query

Microsoft Azure Service Fabric Tools for Visual Studio 16.0 Microsoft Azure Service Fabric Tools for Visual Studio

Microsoft Azure Stream Analytics Language Service 2.4.1000.0 Language service for Azure Stream Analytics

Microsoft Azure Stream Analytics Node 1.0 Azure Stream Analytics Node under Azure Node

Microsoft Azure Tools 2.9 Microsoft Azure Tools for Microsoft Visual Studio 2019 - v2.9.21016.1

Microsoft Continuous Delivery Tools for Visual Studio 0.4 Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.

Microsoft JVM Debugger 1.0 Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft Library Manager 2.0.87+gbb515bf382 Install client-side libraries easily to any web project

Microsoft MI-Based Debugger 1.0 Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual Studio Tools for Containers 1.1 Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

NuGet Package Manager 5.4.0 NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

ProjectServicesPackage Extension 1.0 ProjectServicesPackage Visual Studio Extension Detailed Info

SQL Server Data Tools 16.0.62002.03150 Microsoft SQL Server Data Tools

ToolWindowHostedEditor 1.0 Hosting json editor into a tool window

TypeScript Tools 16.0.11031.2001 TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools 3.4.1-beta4-19614-01+165046097562cfe65b09c2e9a9d8f7cd88526f2c Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools 10.4 for F# 4.6 16.4.0-beta.19556.5+e7597deb7042710a7142bdccabd6f92b0840d354 Microsoft Visual F# Tools 10.4 for F# 4.6

Visual Studio Code Debug Adapter Host Package 1.0 Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Container Tools Extensions (Preview) 1.0 View, manage, and diagnose containers within Visual Studio.

Visual Studio Tools for Containers 1.0 Visual Studio Tools for Containers

Visual Studio Tools for Kubernetes 1.0 Visual Studio Tools for Kubernetes

javiercn commented 4 years ago

Thanks for filing the issue @KeithBarrows.

I think there's an issue in the configuration/definition for your scenario. I'm not entirely sure of the specifics of what you are trying to achieve, so I laid out below the two scenarios I can think of and how to decide what/when to use one or the other.

When authenticating and authorizing a hosted Blazor app with a third party provider, there are several options available for authenticating the user. Which one you choose depends on your specific scenario:

Do you want to authenticate a user to talk to a third party API?

Do you want to allow users to log-in with a third party provider and call protected APIs on your host server and the third party API resources?

Hope that helps. I'll file an issue to improve the docs in this area.

javiercn commented 4 years ago

The specific issue you are having is that it looks like you are trying to implement the 2nd scenario, but you are trying to redirect to the Blazor webassembly app callback url instead of the callback url on the server (/signin-oauth or similar I presume).

What's happening is something like this: /authentication/login -> /connect/authorize -> /Identity/Account/Login -> https://login.eveonline.com/oauth/authorize -> /authentication/login-callback (failure)

What should happen is something like What's happening is something like this: /authentication/login -> /connect/authorize -> /Identity/Account/Login -> https://login.eveonline.com/oauth/authorize -> /Identity/Account/External (not sure of the url, check with the identity docs) -> /connect/authorize/ -> /authentication/login-callback

See this doc for details on how to configure identity to do this https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-3.1

javiercn commented 4 years ago

Here's the link to the docs https://github.com/dotnet/AspNetCore.Docs/issues/17288

KeithBarrows commented 4 years ago

And your answers, while great, are where I am having my moment of confusion. i.e.: Every sample I have found tends to jump over the "obvious to you" parts of the setup process. Yes, the 2nd scenario is what I am trying to achieve in a POC. However, the first scenario fits over 95% of my use cases. I only have 2 (right now) actions that require a central server I have control over. That being said, my idea was to use a Client Credential for the 2 calls I want to make to my own server. 1 to upload a file, the other to download a file. Everything else is handled via the eveonline.com REST services.

You said: What's happening is something like this (w/my comments): /authentication/login ==> WebAsm:Authentication(action:='login') -> /connect/authorize ==> ???? (buried in a nuget?) -> /Identity/Account/Login ==> Server: ???? (buried in a nuget?) -> https://login.eveonline.com/oauth/authorize ==> 3rd party OIDC service -> /authentication/login-callback (failure) ==> obviously missing something between the last step and here!)

I have started a new POC using dotnet new blazorwasm -au Individual -o [newProject". This has no server, obviously. And for the life of me, configuring the OIDC is not working at all. Following the help at https://aka.ms/blazor-standalone-auth.

Also note that I am using an OKTA OIDC as all EveOnline URLs are blocked at work.

    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");
            builder.Services.AddBaseAddressHttpClient();
            builder.Services.AddOidcAuthentication(options =>
            {
                // Configure your authentication provider options here.
                // For more information, see https://aka.ms/blazor-standalone-auth
                options.ProviderOptions.Authority = "https://dev-712283.okta.com";
                options.ProviderOptions.ClientId = "0oa2yttq55XjCR3AO357";

                // also tried https://localhost:5001/.... for all settings
                options.AuthenticationPaths.LogInCallbackPath = "http://localhost:5000/authentication/login-callback"; 
                options.AuthenticationPaths.LogInFailedPath = "http://localhost:5000/authentication/login-failed";
                options.AuthenticationPaths.LogInPath = "http://localhost:5000/authentication/login";
                options.AuthenticationPaths.LogOutCallbackPath = "http://localhost:5000/authentication/logout-callback";
                options.AuthenticationPaths.LogOutFailedPath = "http://localhost:5000/authentication/logout-failed";
                options.AuthenticationPaths.LogOutPath = "http://localhost:5000/authentication/logout";
                options.AuthenticationPaths.LogOutSucceededPath = "http://localhost:5000/authentication/logged-out";
            });

            await builder.Build().RunAsync();
        }
    }

I run and I see: 2020-03-12_1618

I click the Log In button and see that an error happened: 2020-03-12_1619

I am also seeing this error in F12 tools:

Access to XMLHttpRequest at 'https://dev-712283.okta.com/.well-known/openid-configuration' from origin 'https://localhost:5001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Sorry to be a PITA...

javiercn commented 4 years ago

Access to XMLHttpRequest at 'https://dev-712283.okta.com/.well-known/openid-configuration' from origin 'https://localhost:5001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This clearly indicates to me that their endpoint doesn't support CORS and that as a result the app is failing to even get the metadata document.

javiercn commented 4 years ago

That being said, my idea was to use a Client Credential for the 2 calls I want to make to my own server. 1 to upload a file, the other to download a file

Not sure what this means. Client credentials from where to where?

Every sample I have found tends to jump over the "obvious to you" parts of the setup process. Yes, the 2nd scenario is what I am trying to achieve in a POC. However, the first scenario fits over 95% of my use cases.

Here a simple sample with identity server A simple sample with Identity Server demo server. The issues you are having with okta is because it doesn't support cors on the metadata endpoint.

            builder.Services.AddOidcAuthentication(options =>
            {
                options.ProviderOptions.Authority = "https://demo.identityserver.io/";
                options.ProviderOptions.ClientId = "interactive.public";
                options.ProviderOptions.ResponseType = "code";
                options.ProviderOptions.DefaultScopes.Add("api");
            });
javiercn commented 4 years ago

You said: What's happening is something like this (w/my comments): /authentication/login ==> WebAsm:Authentication(action:='login') -> /connect/authorize ==> ???? (buried in a nuget?) -> /Identity/Account/Login ==> Server: ???? (buried in a nuget?) -> https://login.eveonline.com/oauth/authorize ==> 3rd party OIDC service -> /authentication/login-callback (failure) ==> obviously missing something between the last step and here!)

/authentication/login ==> WebAsm:Authentication(action:='login') -> /connect/authorize ==> Default identity server authorization path -> /Identity/Account/Login ==> Default Identity UI authentication -> https://login.eveonline.com/oauth/authorize ==> Where you are sent when the user clicks with sign-in with eve online -> /signin-oauth-callback (or something like that, check the security docs) Where you should be sent after the login with your provider -> /Account/Login/External Where the middleware sends you after successfully authenticating you. -> /connect/authorize Where the external login redirects you after you are correctly authenticated -> /authentication/login-callback Where Identity server redirects you after the successful authorization

KeithBarrows commented 4 years ago

This clearly indicates to me that their endpoint doesn't support CORS and that as a result the app is failing to even get the metadata document.

Yep, missed a setting in Okta.

Are there plans to add triple slash comments to each of the settings and/or documentation that shows default values (if any) for all of these settings? And does it support PKCE for public clients?

Outside of that we can close this down.

Thanks for your awesome help!

javiercn commented 4 years ago

And does it support PKCE for public clients

Yep, that's the default when you are using it in a hosted scenario with our SPA authentication integration and you can configure it by setting the response type to code (I believe it does PKCE by default).

KeithBarrows commented 4 years ago

Are there any documents that list the acceptable values for response type as well as the other settings? :)

My biggest concern is not being a security expert I touch these setting once, maybe twice a year. Then I have to remember the various flows, which are for what purposes, the various response types, client definition (in the ID Server) vs client setup (in your app), etc. ;)

javiercn commented 4 years ago

Are there any documents that list the acceptable values for response type as well as the other settings? :)

The OIDC spec is the best source for that type of stuff https://openid.net/specs/openid-connect-core-1_0.html#Authentication and with an open id connect compatible provider you can always check all those things in the medatada document, which lives at <<authority>>/.well-known/openid-configuration

For example https://dev-712283.okta.com/.well-known/openid-configuration

javiercn commented 4 years ago

I'm closing this issue as the question has been answered.