Skip to content

Commit deaa884

Browse files
Recover DefaultCredentials functionality and update E2E tests
1 parent 57c9b5c commit deaa884

File tree

7 files changed

+103
-27
lines changed

7 files changed

+103
-27
lines changed

src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHost.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Threading;
66
using System.Threading.Tasks;
7+
using Microsoft.AspNetCore.Blazor.Http;
78
using Microsoft.AspNetCore.Blazor.Rendering;
89
using Microsoft.Extensions.DependencyInjection;
910
using Microsoft.JSInterop;
@@ -17,6 +18,12 @@ internal class WebAssemblyHost : IWebAssemblyHost
1718
private IServiceScope _scope;
1819
private WebAssemblyRenderer _renderer;
1920

21+
static WebAssemblyHost()
22+
{
23+
// This default most closely matches what web developers expect
24+
WebAssemblyHttpMessageHandlerOptions.DefaultCredentials = FetchCredentialsOption.SameOrigin;
25+
}
26+
2027
public WebAssemblyHost(IServiceProvider services, IJSRuntime runtime)
2128
{
2229
Services = services ?? throw new ArgumentNullException(nameof(services));
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace Microsoft.AspNetCore.Blazor.Http
5+
{
6+
/// <summary>
7+
/// Specifies a value for the 'credentials' option on outbound HTTP requests.
8+
/// </summary>
9+
public enum FetchCredentialsOption
10+
{
11+
/// <summary>
12+
/// Advises the browser never to send credentials (such as cookies or HTTP auth headers).
13+
/// </summary>
14+
Omit,
15+
16+
/// <summary>
17+
/// Advises the browser to send credentials (such as cookies or HTTP auth headers)
18+
/// only if the target URL is on the same origin as the calling application.
19+
/// </summary>
20+
SameOrigin,
21+
22+
/// <summary>
23+
/// Advises the browser to send credentials (such as cookies or HTTP auth headers)
24+
/// even for cross-origin requests.
25+
/// </summary>
26+
Include,
27+
}
28+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Reflection;
6+
7+
namespace Microsoft.AspNetCore.Blazor.Http
8+
{
9+
/// <summary>
10+
/// Configures options for the WebAssembly HTTP message handler.
11+
/// </summary>
12+
public static class WebAssemblyHttpMessageHandlerOptions
13+
{
14+
/// <summary>
15+
/// Gets or sets the default value of the 'credentials' option on outbound HTTP requests.
16+
/// Defaults to <see cref="FetchCredentialsOption.SameOrigin"/>.
17+
/// </summary>
18+
public static FetchCredentialsOption DefaultCredentials
19+
{
20+
get
21+
{
22+
var valueString = MonoDefaultCredentialsGetter.Value();
23+
var result = default(FetchCredentialsOption);
24+
if (valueString != null)
25+
{
26+
Enum.TryParse(valueString, out result);
27+
}
28+
return result;
29+
}
30+
31+
set
32+
{
33+
MonoDefaultCredentialsSetter.Value(value.ToString());
34+
}
35+
}
36+
37+
static Func<Type> MonoWasmHttpMessageHandlerType = ()
38+
=> Assembly.Load("WebAssembly.Net.Http")
39+
.GetType("WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler");
40+
41+
static Func<Type> MonoFetchCredentialsOptionType = ()
42+
=> Assembly.Load("WebAssembly.Net.Http")
43+
.GetType("WebAssembly.Net.Http.HttpClient.FetchCredentialsOption");
44+
45+
static Lazy<PropertyInfo> MonoDefaultCredentialsProperty = new Lazy<PropertyInfo>(
46+
() => MonoWasmHttpMessageHandlerType()?.GetProperty("DefaultCredentials", BindingFlags.Public | BindingFlags.Static));
47+
48+
static Lazy<Func<string>> MonoDefaultCredentialsGetter = new Lazy<Func<string>>(() =>
49+
{
50+
return () => MonoDefaultCredentialsProperty.Value?.GetValue(null).ToString();
51+
});
52+
53+
static Lazy<Action<string>> MonoDefaultCredentialsSetter = new Lazy<Action<string>>(() =>
54+
{
55+
var fetchCredentialsOptionsType = MonoFetchCredentialsOptionType();
56+
return value => MonoDefaultCredentialsProperty.Value?.SetValue(null, Enum.Parse(fetchCredentialsOptionsType, value));
57+
});
58+
}
59+
}

src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@
1818
<type fullname="System.ComponentModel.GuidConverter" />
1919
<type fullname="System.ComponentModel.TimeSpanConverter" />
2020
</assembly>
21+
22+
<assembly fullname="WebAssembly.Net.Http">
23+
<!-- Without this, the setter for DefaultCredentials would be removed, but we need it -->
24+
<type fullname="WebAssembly.Net.Http.HttpClient.FetchCredentialsOption" />
25+
<type fullname="WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler" />
26+
</assembly>
2127
</linker>

src/Components/test/E2ETest/Tests/HttpClientTest.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ public void CanReadResponseHeaders()
8989
[Fact]
9090
public void CanSendRequestHeaders()
9191
{
92-
AddRequestHeader("TestHeader", "Value from test");
92+
AddRequestHeader("testheader", "Value from test");
9393
AddRequestHeader("another-header", "Another value");
9494
IssueRequest("DELETE", "/subdir/api/person");
9595
Assert.Equal("OK", _responseStatus.Text);
96-
Assert.Contains("TestHeader: Value from test", _responseBody.Text);
96+
Assert.Contains("testheader: Value from test", _responseBody.Text);
9797
Assert.Contains("another-header: Another value", _responseBody.Text);
9898
}
9999

@@ -107,15 +107,6 @@ public void CanSendAndReceiveJson()
107107
Assert.Equal("{\"id\":123,\"name\":\"Bert\"}", _responseBody.Text);
108108
}
109109

110-
[Fact]
111-
public void CanSetRequestReferer()
112-
{
113-
SetValue("request-referrer", "/test-referrer");
114-
IssueRequest("GET", "/subdir/api/person/referrer");
115-
Assert.Equal("OK", _responseStatus.Text);
116-
Assert.EndsWith("/test-referrer", _responseBody.Text);
117-
}
118-
119110
[Fact]
120111
public void CanSendAndReceiveCookies()
121112
{

src/Components/test/testassets/BasicTestApp/HttpClientTest/HttpRequestsComponent.razor

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
@using System.Net
22
@using System.Net.Http
3-
@using Microsoft.AspNetCore.Blazor.Http
43
@inject HttpClient Http
54

65
<h1>HTTP request tester</h1>
@@ -38,11 +37,6 @@
3837
<button id="add-header" @onclick="AddHeader">Add</button>
3938
</p>
4039

41-
<p>
42-
<div>Request referrer:</div>
43-
<input id="request-referrer" type="text" @bind=requestReferrer />
44-
</p>
45-
4640
<button id="send-request" @onclick="DoRequest">Request</button>
4741

4842
@if (responseStatusCode.HasValue)
@@ -65,7 +59,6 @@
6559
string method = "GET";
6660
string requestBody = "";
6761
List<RequestHeader> requestHeaders = new List<RequestHeader>();
68-
string requestReferrer = "";
6962

7063
HttpStatusCode? responseStatusCode;
7164
string responseBody;
@@ -103,14 +96,6 @@
10396
}
10497
}
10598

106-
if (!string.IsNullOrEmpty(requestReferrer))
107-
{
108-
requestMessage.Properties[WebAssemblyHttpMessageHandler.FetchArgs] = new
109-
{
110-
referrer = requestReferrer
111-
};
112-
}
113-
11499
var response = await Http.SendAsync(requestMessage);
115100
responseStatusCode = response.StatusCode;
116101
responseBody = await response.Content.ReadAsStringAsync();

src/Components/test/testassets/BasicTestApp/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void Configure(IComponentsApplicationBuilder app)
3030
{
3131
// Needed because the test server runs on a different port than the client app,
3232
// and we want to test sending/receiving cookies underling this config
33-
WebAssemblyHttpMessageHandler.DefaultCredentials = FetchCredentialsOption.Include;
33+
WebAssemblyHttpMessageHandlerOptions.DefaultCredentials = FetchCredentialsOption.Include;
3434
}
3535

3636
app.AddComponent<Index>("root");

0 commit comments

Comments
 (0)