Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Security.sln
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorizat
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization", "src\Microsoft.AspNet.Authorization\Microsoft.AspNet.Authorization.xproj", "{6AB3E514-5894-4131-9399-DC7D5284ADDB}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.CookiePolicy", "src\Microsoft.AspNet.CookiePolicy\Microsoft.AspNet.CookiePolicy.xproj", "{86183DC3-02A8-4A68-8B60-71ECEC066E79}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.CookiePolicy.Test", "test\Microsoft.AspNet.CookiePolicy.Test\Microsoft.AspNet.CookiePolicy.Test.xproj", "{1790E052-646F-4529-B90E-6FEA95520D69}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -242,6 +246,30 @@ Global
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x86.ActiveCfg = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x86.Build.0 = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|x86.ActiveCfg = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|x86.Build.0 = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Any CPU.Build.0 = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|x86.ActiveCfg = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|x86.Build.0 = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|x86.ActiveCfg = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|x86.Build.0 = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Any CPU.Build.0 = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|x86.ActiveCfg = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -263,5 +291,7 @@ Global
{2755BFE5-7421-4A31-A644-F817DF5CAA98} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2} = {7BF11F3A-60B6-4796-B504-579C67FFBA34}
{6AB3E514-5894-4131-9399-DC7D5284ADDB} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
{86183DC3-02A8-4A68-8B60-71ECEC066E79} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
{1790E052-646F-4529-B90E-6FEA95520D69} = {7BF11F3A-60B6-4796-B504-579C67FFBA34}
EndGlobalSection
EndGlobal
23 changes: 23 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/AppendCookieContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.AspNet.Http;

namespace Microsoft.AspNet.CookiePolicy
{
public class AppendCookieContext
{
public AppendCookieContext(HttpContext context, CookieOptions options, string name, string value)
{
Context = context;
CookieOptions = options;
CookieName = name;
CookieValue = value;
}

public HttpContext Context { get; }
public CookieOptions CookieOptions { get; }
public string CookieName { get; set; }
public string CookieValue { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.AspNet.CookiePolicy;

namespace Microsoft.AspNet.Builder
{
/// <summary>
/// Extension methods provided by the cookie policy middleware
/// </summary>
public static class CookiePolicyAppBuilderExtensions
{
/// <summary>
/// Adds a cookie policy middleware to your web application pipeline.
/// </summary>
/// <param name="app">The IApplicationBuilder passed to your configuration method</param>
/// <param name="options">The options for the middleware</param>
/// <returns>The original app parameter</returns>
public static IApplicationBuilder UseCookiePolicy(this IApplicationBuilder app, CookiePolicyOptions options)
{
return app.UseMiddleware<CookiePolicyMiddleware>(options);
}

/// <summary>
/// Adds a cookie policy middleware to your web application pipeline.
/// </summary>
/// <param name="app">The IApplicationBuilder passed to your configuration method</param>
/// <param name="configureOptions">Used to configure the options for the middleware</param>
/// <returns>The original app parameter</returns>
public static IApplicationBuilder UseCookiePolicy(this IApplicationBuilder app, Action<CookiePolicyOptions> configureOptions)
{
var options = new CookiePolicyOptions();
if (configureOptions != null)
{
configureOptions(options);
}
return app.UseCookiePolicy(options);
}
}
}
157 changes: 157 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/CookiePolicyMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Features.Internal;

namespace Microsoft.AspNet.CookiePolicy
{
public class CookiePolicyMiddleware
{
private readonly RequestDelegate _next;

public CookiePolicyMiddleware(
RequestDelegate next,
CookiePolicyOptions options)
{
Options = options;
_next = next;
}

public CookiePolicyOptions Options { get; set; }

public Task Invoke(HttpContext context)
{
// REVIEW: Do we need to check if there is a Cookie feature already present like SendFile??
Copy link
Member Author

Choose a reason for hiding this comment

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

This piece needs review, is it safe to blindly set the feature?

Copy link
Member

Choose a reason for hiding this comment

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

Consider wrapping the existing feature (if any) rather than just wrapping context.Response.Cookies. If none, default to a new ResponseCookiesFeature.

context.Features.Set<IResponseCookiesFeature>(new CookiesWrapperFeature(context, Options));

return _next(context);
}

private class CookiesWrapperFeature : IResponseCookiesFeature
{
public CookiesWrapperFeature(HttpContext context, CookiePolicyOptions options)
{
Wrapper = new CookiesWrapper(context, options, context.Response.Cookies);
}

public IResponseCookies Wrapper { get; }

public IResponseCookies Cookies
{
get
{
return Wrapper;
}
}
}

private class CookiesWrapper : IResponseCookies
{
public CookiesWrapper(HttpContext context, CookiePolicyOptions options, IResponseCookies cookies)
{
Context = context;
Cookies = cookies;
Policy = options;
}

public HttpContext Context { get; }

public IResponseCookies Cookies { get; }

public CookiePolicyOptions Policy { get; }

private bool PolicyRequiresCookieOptions()
{
return Policy.HttpOnly != HttpOnlyPolicy.None || Policy.Secure != SecurePolicy.None;
}

public void Append(string key, string value)
{
if (PolicyRequiresCookieOptions())
{
Append(key, value, new CookieOptions());
return;
}

Copy link
Member

Choose a reason for hiding this comment

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

nit: empty line.

if (Policy.OnAppendCookie != null)
{
var context = new AppendCookieContext(Context, options: null, name: key, value: value);
Copy link
Member

Choose a reason for hiding this comment

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

What if they want to add options in the callback?

Copy link
Member

Choose a reason for hiding this comment

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

I think you'd always call the other overload if the callback is set.

Policy.OnAppendCookie(context);
key = context.CookieName;
value = context.CookieValue;
}
Cookies.Append(key, value);
}

public void Append(string key, string value, CookieOptions options)
Copy link
Member

Choose a reason for hiding this comment

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

argument validation?

Copy link
Member Author

Choose a reason for hiding this comment

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

There didn't appear to be any argument validation in the base HttpAbstractions ResponseCookies so I just mimiced that behavior since we are just wrapping no?

Copy link
Member

Choose a reason for hiding this comment

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

There's at least a NotNull check on options.

{
ApplyPolicy(options);
if (Policy.OnAppendCookie != null)
{
var context = new AppendCookieContext(Context, options, key, value);
Policy.OnAppendCookie(context);
key = context.CookieName;
value = context.CookieValue;
}
Cookies.Append(key, value, options);
}

public void Delete(string key)
{
if (PolicyRequiresCookieOptions())
{
Delete(key, new CookieOptions());
return;
}


Copy link
Member

Choose a reason for hiding this comment

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

nit: empty line

if (Policy.OnDeleteCookie != null)
{
var context = new DeleteCookieContext(Context, options: null, name: key);
Policy.OnDeleteCookie(context);
key = context.CookieName;
}
Cookies.Delete(key);
}

public void Delete(string key, CookieOptions options)
{
ApplyPolicy(options);
if (Policy.OnDeleteCookie != null)
{
var context = new DeleteCookieContext(Context, options, key);
Policy.OnDeleteCookie(context);
key = context.CookieName;
}
Cookies.Delete(key, options);
}

private void ApplyPolicy(CookieOptions options)
{
switch (Policy.Secure)
{
case SecurePolicy.Always:
options.Secure = true;
break;
case SecurePolicy.SameAsRequest:
options.Secure = Context.Request.IsHttps;
break;
case SecurePolicy.None:
break;
}
switch (Policy.HttpOnly)
{
case HttpOnlyPolicy.Always:
options.HttpOnly = true;
break;
case HttpOnlyPolicy.None:
break;
}
Copy link
Member

Choose a reason for hiding this comment

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

default throw?

}
}
}
}
16 changes: 16 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/CookiePolicyOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace Microsoft.AspNet.CookiePolicy
{
public class CookiePolicyOptions
{
public HttpOnlyPolicy HttpOnly { get; set; } = HttpOnlyPolicy.None;
public SecurePolicy Secure { get; set; } = SecurePolicy.None;

public Action<AppendCookieContext> OnAppendCookie { get; set; }
public Action<DeleteCookieContext> OnDeleteCookie { get; set; }
}
}
21 changes: 21 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/DeleteCookieContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.AspNet.Http;

namespace Microsoft.AspNet.CookiePolicy
{
public class DeleteCookieContext
{
public DeleteCookieContext(HttpContext context, CookieOptions options, string name)
{
Context = context;
CookieOptions = options;
CookieName = name;
}

public HttpContext Context { get; }
public CookieOptions CookieOptions { get; }
public string CookieName { get; set; }
}
}
11 changes: 11 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/HttpOnlyPolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.AspNet.CookiePolicy
{
public enum HttpOnlyPolicy
{
None,
Always
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>86183dc3-02a8-4a68-8b60-71ecec066e79</ProjectGuid>
<RootNamespace>Microsoft.AspNet.CookiePolicy</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>

<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
8 changes: 8 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Reflection;
using System.Resources;

[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: NeutralResourcesLanguage("en-us")]
12 changes: 12 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/SecurePolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.AspNet.CookiePolicy
{
public enum SecurePolicy
{
None,
Always,
SameAsRequest
}
}
18 changes: 18 additions & 0 deletions src/Microsoft.AspNet.CookiePolicy/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "1.0.0-*",
"description": "ASP.NET 5 cookie policy classes.",
"repository": {
"type": "git",
"url": "git://github.com/aspnet/security"
},
"dependencies": {
"Microsoft.AspNet.Http.Abstractions": "1.0.0-*",
"Microsoft.AspNet.Http.Features": "1.0.0-*",
Copy link
Member

Choose a reason for hiding this comment

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

Remove transitive dependencies on Abstractions, Features.

"Microsoft.AspNet.Http": "1.0.0-*",
"Microsoft.Framework.OptionsModel": "1.0.0-*"
},
"frameworks": {
"dnx451": { },
"dnxcore50": { }
}
}
Loading