Skip to content

[blazor-wasm] Pass access token as query string when running SignalR in the browser #20115

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

Closed
wants to merge 15 commits into from

Conversation

wtgodbe
Copy link
Member

@wtgodbe wtgodbe commented Mar 24, 2020

Attempts to resolve #18697

When the signalR client is running in the browser, we need to append the access token as a query string rather than using a request header.

Since this is in blazor-wasm, there were some infra changes needed to get the package building & whatnot.

I used https://github.com/wtgodbe/scratch/tree/master/SigRBlazor/BlazorSignalRApp to validate that the token gets passed as a query string & can be pulled out and referenced by the server.

@wtgodbe wtgodbe requested a review from halter73 as a code owner March 24, 2020 22:11
@wtgodbe wtgodbe changed the title Wtgodbe/access token provider Pass access token as query string when running SignalR in the browser Mar 24, 2020
@wtgodbe wtgodbe changed the title Pass access token as query string when running SignalR in the browser [blazor-wasm] Pass access token as query string when running SignalR in the browser Mar 24, 2020
@@ -1,18 +0,0 @@
<!-- This file is automatically generated. -->
<Project Sdk="Microsoft.NET.Sdk">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm, I wonder why we had this. It wasn't in the shared framework before... (I just checked)

@wtgodbe
Copy link
Member Author

wtgodbe commented Mar 24, 2020

@pranavkm @BrennanConroy @anurse I pushed a commit responding to feedback

@mkArtakMSFT mkArtakMSFT added Blazor ♥ SignalR This issue is related to the experience of Signal R and Blazor working together feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly area-blazor Includes: Blazor, Razor Components labels Mar 25, 2020
// We can't use request headers in the browser, so instead append the token as a query string in that case
if (_isRunningInBrowser)
{
var accessTokenEncoded = UrlEncoder.Default.Encode(accessToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to test this code path. Maybe we can make _isRunningInBrowser internal and modify it in tests to be true.

Copy link
Member Author

@wtgodbe wtgodbe Mar 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing a test for this is probably something I'd need help with - do you know of a test I can use as an example of some similar scenario?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably something similar to

public async Task WebSocketsTransportSendsUserAgent()

Copy link
Contributor

@pranavkm pranavkm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Good to go once SignalR's happy

@BrennanConroy
Copy link
Member

Was thinking about this over the weekend and realized we need to do something about SSE.

Right now it doesn't work because we use an HttpClient GET with "text/event-stream" Accept header. Which doesn't work in the browser, we use the EventSource API in the Typescript client to do a streaming response.

We might just have to disable SSE when running the .NET client in the browser.

@analogrelay
Copy link
Contributor

analogrelay commented Mar 30, 2020

We might just have to disable SSE when running the .NET client in the browser.

Yep, let's do that. In 5.0 we should just remove it altogether.

@wtgodbe
Copy link
Member Author

wtgodbe commented Mar 31, 2020

This guy? https://github.com/dotnet/aspnetcore/blob/master/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsTransport.cs

Is there standard practice for this? Throw a PlatformNotSupportedException or similar in StartAsync?

@BrennanConroy
Copy link
Member

We are going to want to disable transport fallback to SSE in the browser, and probably throw if the client specifies SSE as the only transport it wants to use.

@halter73
Copy link
Member

This guy?

Yep.

Is there standard practice for this? Throw a PlatformNotSupportedException or similar in StartAsync?

ServerSentEventsTransport is internal, so as long as StartAsync doesn't get called, we shouldn't need to change it. I would take a look at how we skip WebSockets on platforms where it's not supported and do something similar:

if (transportType == HttpTransportType.WebSockets && !IsWebSocketsSupported())
{
Log.WebSocketsNotSupportedByOperatingSystem(_logger);
transportExceptions.Add(new TransportFailedException("WebSockets", "The transport is not supported on this operating system."));
continue;
}

@wtgodbe
Copy link
Member Author

wtgodbe commented Mar 31, 2020

We should also throw an exception if the user passes only SSE, and is running in the browser

_httpConnectionOptions = httpConnectionOptions;

@@ -66,6 +66,9 @@ private static class Log
private static readonly Action<ILogger, HttpTransportType, Exception> _transportStarted =
LoggerMessage.Define<HttpTransportType>(LogLevel.Debug, new EventId(18, "TransportStarted"), "Transport '{Transport}' started.");

private static readonly Action<ILogger, Exception> _serverSentEventsNotSupportedByBrowser =
LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because they are not supported by the browser.");
Copy link
Member

@BrennanConroy BrennanConroy Apr 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because they are not supported by the browser.");
LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because it is not supported by the browser.");

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know what line you're trying to point out

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops

LoggerMessage.Define(LogLevel.Debug, new EventId(16, "WebSocketsNotSupportedByOperatingSystem"), "Skipping WebSockets because they are not supported by the operating system.");

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we can just keep both as is. Not too picky

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is that WebSockets is the name of a transport and a name for the type of socket. In that latter sense, that could be plural. ServerSentEvents is just the name of a transport, so it should probably be singular. Super nitpicky though.

@mkArtakMSFT mkArtakMSFT removed the feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly label Apr 8, 2020
@wtgodbe
Copy link
Member Author

wtgodbe commented Apr 14, 2020

Closing in favor of #20466, as this change is going into release/3.1 instead of blazor-wasm

@wtgodbe wtgodbe closed this Apr 14, 2020
@wtgodbe wtgodbe deleted the wtgodbe/AccessTokenProvider branch April 14, 2020 19:59
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 Blazor ♥ SignalR This issue is related to the experience of Signal R and Blazor working together
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants