PR comments incorporated
This commit is contained in:
parent
7b190ccf0f
commit
fb240d4382
|
|
@ -1,34 +1,35 @@
|
|||
CORS Sample
|
||||
===
|
||||
This sample consists of a request origin (SampleOrigin) and a request destination (SampleDestination).
|
||||
Both have different domain names, to simulate a CORS request.
|
||||
# CORS Sample
|
||||
|
||||
Modify Hosts File
|
||||
Windows:
|
||||
This sample consists of a request origin (SampleOrigin) and a request destination (SampleDestination). Both have different domain names, to simulate a CORS request.
|
||||
|
||||
## Modify Hosts File
|
||||
To run this CORS sample, modify the hosts file to register the hostnames ```destination.example.com``` and ```origin.example.com.```
|
||||
### Windows:
|
||||
Run a text editor (e.g. Notepad) as an Administrator. Open the hosts file on the path: "C:\Windows\System32\drivers\etc\hosts".
|
||||
|
||||
Linux:
|
||||
### Linux:
|
||||
On a Terminal window, type "sudo nano /etc/hosts" and enter your admin password when prompted.
|
||||
|
||||
In the hosts file, add the following to the bottom of the file:
|
||||
127.0.0.1 destination.example.com
|
||||
127.0.0.1 origin.example.com
|
||||
``` 127.0.0.1 destination.example.com```
|
||||
``` 127.0.0.1 origin.example.com ```
|
||||
|
||||
Save the file and close it. Then clear your browser history.
|
||||
|
||||
Run the sample
|
||||
*In a command prompt window, open the directory where you cloned the repository, and open the SampleDestination directory. Run the command: dotnet run
|
||||
*Repeat the above step in the SampleOrigin directory.
|
||||
*Open a browser window and go to http://origin.example.com:5001
|
||||
*Click the button to see CORS in action.
|
||||
|
||||
## Run the sample
|
||||
The SampleOrigin application will use port 5001, and SampleDestination will use 5000. Please ensure there are no other processes using those ports before running the CORS sample.
|
||||
|
||||
As an example, apart from GET, HEAD and POST requests, PUT requests are allowed in the CORS policy on SampleDestination. Any others, like DELETE, OPTIONS etc. are not allowed and throw an error.
|
||||
Content-Length has been added as an allowed header to the sample. Any other headers are not allowed and throw an error.
|
||||
To edit the policy, please see app.UseCors() method in the Startup.cs file of SampleDestination.
|
||||
* In a command prompt window, open the directory where you cloned the repository, and open the SampleDestination directory. Run the command: dotnet run
|
||||
* Repeat the above step in the SampleOrigin directory.
|
||||
* Open a browser window and go to ```http://origin.example.com:5001```
|
||||
* Input a method and header to create a CORS request or use one of the example buttons to see CORS in action.
|
||||
|
||||
As an example, apart from ```GET```, ```HEAD``` and ```POST``` requests, ```PUT``` requests are allowed in the CORS policy on SampleDestination. Any others, like ```DELETE```, ```OPTIONS``` etc. are not allowed and throw an error.
|
||||
```Cache-Control``` has been added as an allowed header to the sample. Any other headers are not allowed and throw an error. You may leave the header name and value blank.
|
||||
|
||||
To edit the policy, please see ```app.UseCors()``` method in the ```Startup.cs``` file of SampleDestination.
|
||||
|
||||
**If using Visual Studio to launch the request origin:**
|
||||
Open Visual Studio and in the ```launchSettings.json``` file for the SampleOrigin project, change the ```launchUrl``` under SampleOrigin to ```http://origin.example.com:5001```.
|
||||
Using the dropdown near the Start button, choose SampleOrigin before pressing Start to ensure that it uses Kestrel and not IIS Express.
|
||||
|
||||
If using Visual Studio to launch the request origin:
|
||||
Open Visual Studio and in the launchSettings.json file for the SampleOrigin project, change the launchUrl under SampleOrigin to
|
||||
http://origin.example.com:5001. Using the dropdown near the Start button, choose SampleOrigin before pressing Start to ensure that it uses Kestrel
|
||||
and not IIS Express.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -21,17 +20,18 @@ namespace SampleDestination
|
|||
{
|
||||
loggerFactory.AddConsole();
|
||||
|
||||
app.UseCors(policy => policy
|
||||
.WithOrigins("http://origin.example.com:5001")
|
||||
app.UseCors(policy => policy
|
||||
.WithOrigins("http://origin.example.com:5001")
|
||||
.WithMethods("PUT")
|
||||
.WithHeaders("Cache-Control"));
|
||||
|
||||
app.Run(async context =>
|
||||
{
|
||||
var responseHeaders = context.Response.Headers;
|
||||
context.Response.ContentType = "text/plain";
|
||||
foreach (var responseHeader in responseHeaders)
|
||||
{
|
||||
await context.Response.WriteAsync("\n"+responseHeader.Key+": "+responseHeader.Value);
|
||||
await context.Response.WriteAsync("\n" + responseHeader.Key + ": " + responseHeader.Value);
|
||||
}
|
||||
|
||||
await context.Response.WriteAsync("\nStatus code of your request: " + context.Response.StatusCode.ToString());
|
||||
|
|
|
|||
|
|
@ -20,5 +20,4 @@ namespace SampleOrigin
|
|||
host.Run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,19 +18,13 @@ namespace SampleOrigin
|
|||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole();
|
||||
app.Run( context =>
|
||||
{
|
||||
var fileInfoProvider = env.WebRootFileProvider;
|
||||
var fileInfo = fileInfoProvider.GetFileInfo("/Index.html");
|
||||
context.Response.Headers.Add("Content-Type", "text/html; charset=utf-8");
|
||||
return context.Response.SendFileAsync(fileInfo);
|
||||
});
|
||||
|
||||
app.Run(async context =>
|
||||
{
|
||||
await context.Response.WriteAsync("Status code of your request: " + context.Response.StatusCode.ToString());
|
||||
});
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
var fileInfoProvider = env.WebRootFileProvider;
|
||||
var fileInfo = fileInfoProvider.GetFileInfo("/Index.html");
|
||||
context.Response.ContentType = "text/html";
|
||||
return context.Response.SendFileAsync(fileInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="false" />
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
|
@ -41,7 +41,9 @@
|
|||
var url = 'http://destination.example.com:5000/';
|
||||
var request = new XMLHttpRequest();
|
||||
request.open(method, url, true);
|
||||
request.setRequestHeader(headerName, headerValue);
|
||||
if (headerName && headerValue) {
|
||||
request.setRequestHeader(headerName, headerValue);
|
||||
}
|
||||
|
||||
if (!request) {
|
||||
alert('CORS not supported');
|
||||
|
|
@ -61,24 +63,11 @@
|
|||
request.send();
|
||||
}
|
||||
</script>
|
||||
|
||||
<p>CORS Sample</p>
|
||||
Method: <input type="text" id="methodName" /><br /><br />
|
||||
Header Name: <input type="text" id="headerName" value="Cache-Control" /> Header Value: <input type="text" id="headerValue" value="no-cache" /><br /><br />
|
||||
Header Name: <input type="text" id="headerName" /> Header Value: <input type="text" id="headerValue" /><br /><br />
|
||||
<script>
|
||||
document.getElementById('methodName')
|
||||
.addEventListener("keyup", function (event) {
|
||||
event.preventDefault();
|
||||
if (event.keyCode == 13) {
|
||||
document.getElementById("headerName").focus();
|
||||
}
|
||||
});
|
||||
document.getElementById('headerName')
|
||||
.addEventListener("keyup", function (event) {
|
||||
event.preventDefault();
|
||||
if (event.keyCode == 13) {
|
||||
document.getElementById("headerValue").focus();
|
||||
}
|
||||
});
|
||||
document.getElementById('headerValue')
|
||||
.addEventListener("keyup", function (event) {
|
||||
event.preventDefault();
|
||||
|
|
@ -91,9 +80,9 @@
|
|||
<button class="button gray" id="CORS" type="submit" onclick="makeCORSRequest(document.getElementById('methodName').value, document.getElementById('headerName').value, document.getElementById('headerValue').value);">Make a CORS Request</button><br /><br /><br /><br />
|
||||
|
||||
Method DELETE is not allowed:<button class="button red" id="InvalidMethodCORS" type="submit" onclick="makeCORSRequest('DELETE', 'Cache-Control', 'no-cache');">Invalid Method CORS Request</button>
|
||||
Method PUT is allowed:<button class="button green" id="InvalidMethodCORS" type="submit" onclick="makeCORSRequest('PUT', 'Cache-Control', 'no-cache');">Valid Method CORS Request</button><br /><br />
|
||||
Method PUT is allowed:<button class="button green" id="ValidMethodCORS" type="submit" onclick="makeCORSRequest('PUT', 'Cache-Control', 'no-cache');">Valid Method CORS Request</button><br /><br />
|
||||
|
||||
Header 'Max-Forwards' not supported:<button class="button red" id="InvalidHeaderCORS" type="submit" onclick="makeCORSRequest('PUT', 'Max-Forwards', 'x');">Invalid Header CORS Request</button>
|
||||
Header 'Cache-Control' is supported:<button class="button green" id="InvalidHeaderCORS" type="submit" onclick="makeCORSRequest('PUT', 'Cache-Control', 'no-cache');">Valid Header CORS Request</button><br /><br />
|
||||
Header 'Max-Forwards' not supported:<button class="button red" id="InvalidHeaderCORS" type="submit" onclick="makeCORSRequest('PUT', 'Max-Forwards', '2');">Invalid Header CORS Request</button>
|
||||
Header 'Cache-Control' is supported:<button class="button green" id="ValidHeaderCORS" type="submit" onclick="makeCORSRequest('PUT', 'Cache-Control', 'no-cache');">Valid Header CORS Request</button><br /><br />
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -236,32 +236,32 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
{
|
||||
{
|
||||
new LogData {
|
||||
origin = "http://example.com",
|
||||
method = "PUT",
|
||||
headers = null,
|
||||
originLogMessage = "The request has an origin header: 'http://example.com'.",
|
||||
policyLogMessage = "Policy execution failed.",
|
||||
failureReason = "Request origin http://example.com does not have permission to access the resource."
|
||||
Origin = "http://example.com",
|
||||
Method = "PUT",
|
||||
Headers = null,
|
||||
OriginLogMessage = "The request has an origin header: 'http://example.com'.",
|
||||
PolicyLogMessage = "Policy execution failed.",
|
||||
FailureReason = "Request origin http://example.com does not have permission to access the resource."
|
||||
}
|
||||
},
|
||||
{
|
||||
new LogData {
|
||||
origin = "http://allowed.example.com",
|
||||
method = "DELETE",
|
||||
headers = null,
|
||||
originLogMessage = "The request has an origin header: 'http://allowed.example.com'.",
|
||||
policyLogMessage = "Policy execution failed.",
|
||||
failureReason = "Request method DELETE not allowed in CORS policy."
|
||||
Origin = "http://allowed.example.com",
|
||||
Method = "DELETE",
|
||||
Headers = null,
|
||||
OriginLogMessage = "The request has an origin header: 'http://allowed.example.com'.",
|
||||
PolicyLogMessage = "Policy execution failed.",
|
||||
FailureReason = "Request method DELETE not allowed in CORS policy."
|
||||
}
|
||||
},
|
||||
{
|
||||
new LogData {
|
||||
origin = "http://allowed.example.com",
|
||||
method = "PUT",
|
||||
headers = new[] { "test" },
|
||||
originLogMessage = "The request has an origin header: 'http://allowed.example.com'.",
|
||||
policyLogMessage = "Policy execution failed.",
|
||||
failureReason = "Request header 'test' not allowed in CORS policy."
|
||||
Origin = "http://allowed.example.com",
|
||||
Method = "PUT",
|
||||
Headers = new[] { "test" },
|
||||
OriginLogMessage = "The request has an origin header: 'http://allowed.example.com'.",
|
||||
PolicyLogMessage = "Policy execution failed.",
|
||||
FailureReason = "Request header 'test' not allowed in CORS policy."
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
@ -276,7 +276,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
|
||||
var corsService = new CorsService(new TestCorsOptions(), loggerFactory);
|
||||
var requestContext = GetHttpContext(method: "OPTIONS", origin: logData.origin, accessControlRequestMethod: logData.method, accessControlRequestHeaders: logData.headers);
|
||||
var requestContext = GetHttpContext(method: "OPTIONS", origin: logData.Origin, accessControlRequestMethod: logData.Method, accessControlRequestHeaders: logData.Headers);
|
||||
var policy = new CorsPolicy();
|
||||
policy.Origins.Add("http://allowed.example.com");
|
||||
policy.Methods.Add("PUT");
|
||||
|
|
@ -285,9 +285,9 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
var result = corsService.EvaluatePolicy(requestContext, policy);
|
||||
|
||||
Assert.Equal("The request is a preflight request.", sink.Writes[0].State.ToString());
|
||||
Assert.Equal(logData.originLogMessage, sink.Writes[1].State.ToString());
|
||||
Assert.Equal(logData.policyLogMessage, sink.Writes[2].State.ToString());
|
||||
Assert.Equal(logData.failureReason, sink.Writes[3].State.ToString());
|
||||
Assert.Equal(logData.OriginLogMessage, sink.Writes[1].State.ToString());
|
||||
Assert.Equal(logData.PolicyLogMessage, sink.Writes[2].State.ToString());
|
||||
Assert.Equal(logData.FailureReason, sink.Writes[3].State.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -1071,14 +1071,14 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
return context;
|
||||
}
|
||||
|
||||
public struct LogData
|
||||
public class LogData
|
||||
{
|
||||
public string origin { get; set; }
|
||||
public string method { get; set; }
|
||||
public string[] headers { get; set; }
|
||||
public string originLogMessage { get; set; }
|
||||
public string policyLogMessage { get; set; }
|
||||
public string failureReason { get; set; }
|
||||
public string Origin { get; set; }
|
||||
public string Method { get; set; }
|
||||
public string[] Headers { get; set; }
|
||||
public string OriginLogMessage { get; set; }
|
||||
public string PolicyLogMessage { get; set; }
|
||||
public string FailureReason { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue