diff --git a/src/Microsoft.AspNet.Authentication.Cookies/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/ChunkingCookieManager.cs index 993d0e74ee..73beb79503 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/ChunkingCookieManager.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.Linq; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; +using Microsoft.Framework.Primitives; using Microsoft.Framework.WebEncoders; using Microsoft.Net.Http.Headers; @@ -151,7 +152,7 @@ namespace Microsoft.AspNet.Authentication.Cookies if (!ChunkSize.HasValue || ChunkSize.Value > templateLength + escapedValue.Length + (quoted ? 2 : 0)) { template.Value = quoted ? Quote(escapedValue) : escapedValue; - responseHeaders.AppendValues(Constants.Headers.SetCookie, template.ToString()); + responseHeaders.Append(Constants.Headers.SetCookie, template.ToString()); } else if (ChunkSize.Value < templateLength + (quoted ? 2 : 0) + 10) { @@ -171,7 +172,7 @@ namespace Microsoft.AspNet.Authentication.Cookies var cookieChunkCount = (int)Math.Ceiling(escapedValue.Length * 1.0 / dataSizePerCookie); template.Value = "chunks:" + cookieChunkCount.ToString(CultureInfo.InvariantCulture); - responseHeaders.AppendValues(Constants.Headers.SetCookie, template.ToString()); + responseHeaders.Append(Constants.Headers.SetCookie, template.ToString()); var chunks = new string[cookieChunkCount]; var offset = 0; @@ -186,7 +187,7 @@ namespace Microsoft.AspNet.Authentication.Cookies template.Value = quoted ? Quote(segment) : segment; chunks[chunkId - 1] = template.ToString(); } - responseHeaders.AppendValues(Constants.Headers.SetCookie, chunks); + responseHeaders.Append(Constants.Headers.SetCookie, chunks); } } @@ -233,10 +234,10 @@ namespace Microsoft.AspNet.Authentication.Cookies } var responseHeaders = context.Response.Headers; - var existingValues = responseHeaders.GetValues(Constants.Headers.SetCookie); - if (existingValues != null) + var existingValues = responseHeaders[Constants.Headers.SetCookie]; + if (!StringValues.IsNullOrEmpty(existingValues)) { - responseHeaders.SetValues(Constants.Headers.SetCookie, existingValues.Where(value => !rejectPredicate(value)).ToArray()); + responseHeaders[Constants.Headers.SetCookie] = existingValues.Where(value => !rejectPredicate(value)).ToArray(); } AppendResponseCookie( diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 8919d76809..d04af10481 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -11,14 +11,13 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Http.Features.Authentication; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; +using Microsoft.Framework.Primitives; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Authentication.Cookies { internal class CookieAuthenticationHandler : AuthenticationHandler { - private const string HeaderNameCacheControl = "Cache-Control"; - private const string HeaderNamePragma = "Pragma"; - private const string HeaderNameExpires = "Expires"; private const string HeaderValueNoCache = "no-cache"; private const string HeaderValueMinusOne = "-1"; private const string SessionIdClaim = "Microsoft.AspNet.Authentication.Cookies-SessionId"; @@ -344,15 +343,15 @@ namespace Microsoft.AspNet.Authentication.Cookies private void ApplyHeaders(bool shouldRedirectToReturnUrl = false) { - Response.Headers.Set(HeaderNameCacheControl, HeaderValueNoCache); - Response.Headers.Set(HeaderNamePragma, HeaderValueNoCache); - Response.Headers.Set(HeaderNameExpires, HeaderValueMinusOne); + Response.Headers[HeaderNames.CacheControl] = HeaderValueNoCache; + Response.Headers[HeaderNames.Pragma] = HeaderValueNoCache; + Response.Headers[HeaderNames.Expires] = HeaderValueMinusOne; if (shouldRedirectToReturnUrl && Response.StatusCode == 200) { var query = Request.Query; - var redirectUri = query.Get(Options.ReturnUrlParameter); - if (!string.IsNullOrEmpty(redirectUri) + var redirectUri = query[Options.ReturnUrlParameter]; + if (!StringValues.IsNullOrEmpty(redirectUri) && IsHostRelative(redirectUri)) { var redirectContext = new CookieApplyRedirectContext(Context, Options, redirectUri); diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index e5823ff3ab..52e7b10371 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Authentication.Facebook var payload = new JObject(); foreach (string key in form.Keys) { - payload.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, form[key]); + payload.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, (string)form[key]); } // The refresh token is not available. diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index 818ba20fba..94f58ac466 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; -using System.Security.Cryptography; using System.Security.Claims; +using System.Security.Cryptography; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; @@ -15,6 +15,7 @@ using Microsoft.AspNet.Http.Features.Authentication; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; +using Microsoft.Framework.Primitives; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.OAuth @@ -85,16 +86,16 @@ namespace Microsoft.AspNet.Authentication.OAuth var query = Request.Query; // TODO: Is this a standard error returned by servers? - var value = query.Get("error"); - if (!string.IsNullOrEmpty(value)) + var value = query["error"]; + if (!StringValues.IsNullOrEmpty(value)) { Logger.LogVerbose("Remote server returned an error: " + Request.QueryString); // TODO: Fail request rather than passing through? return null; } - var code = query.Get("code"); - var state = query.Get("state"); + var code = query["code"]; + var state = query["state"]; properties = Options.StateDataFormat.Unprotect(state); if (properties == null) @@ -108,7 +109,7 @@ namespace Microsoft.AspNet.Authentication.OAuth return new AuthenticationTicket(properties, Options.AuthenticationScheme); } - if (string.IsNullOrEmpty(code)) + if (StringValues.IsNullOrEmpty(code)) { // Null if the remote server returns an error. return new AuthenticationTicket(properties, Options.AuthenticationScheme); diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs index ffc0b9fc4f..8dad8dca3a 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer /// public OAuthBearerAuthenticationNotifications() { - ApplyChallenge = notification => { notification.HttpContext.Response.Headers.AppendValues("WWW-Authenticate", notification.Options.Challenge); return Task.FromResult(0); }; + ApplyChallenge = notification => { notification.HttpContext.Response.Headers.Append("WWW-Authenticate", notification.Options.Challenge); return Task.FromResult(0); }; AuthenticationFailed = notification => Task.FromResult(0); MessageReceived = notification => Task.FromResult(0); SecurityTokenReceived = notification => Task.FromResult(0); diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index ef04f14a1f..c72f0b1b33 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer if (string.IsNullOrEmpty(token)) { - var authorization = Request.Headers.Get("Authorization"); + string authorization = Request.Headers["Authorization"]; // If no authorization header found, nothing to process further if (string.IsNullOrEmpty(authorization)) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index 9e57c3fdf7..df1be78766 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Globalization; using System.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; @@ -246,7 +247,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase)) { - message = new OpenIdConnectMessage(Request.Query); + message = new OpenIdConnectMessage(Request.Query.Select(pair => new KeyValuePair(pair.Key, pair.Value))); // response_mode=query (explicit or not) and a response_type containing id_token // or token are not considered as a safe combination and MUST be rejected. @@ -267,7 +268,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect { var form = await Request.ReadFormAsync(); Request.Body.Seek(0, SeekOrigin.Begin); - message = new OpenIdConnectMessage(form); + message = new OpenIdConnectMessage(form.Select(pair => new KeyValuePair(pair.Key, pair.Value))); } if (message == null) diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index fb8f3aa254..7435e21875 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -16,6 +16,7 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; +using Microsoft.Framework.Primitives; namespace Microsoft.AspNet.Authentication.Twitter { @@ -61,21 +62,21 @@ namespace Microsoft.AspNet.Authentication.Twitter properties = requestToken.Properties; - var returnedToken = query.Get("oauth_token"); - if (string.IsNullOrEmpty(returnedToken)) + var returnedToken = query["oauth_token"]; + if (StringValues.IsNullOrEmpty(returnedToken)) { Logger.LogWarning("Missing oauth_token"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } - if (returnedToken != requestToken.Token) + if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal)) { Logger.LogWarning("Unmatched token"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } - var oauthVerifier = query.Get("oauth_verifier"); - if (string.IsNullOrEmpty(oauthVerifier)) + var oauthVerifier = query["oauth_verifier"]; + if (StringValues.IsNullOrEmpty(oauthVerifier)) { Logger.LogWarning("Missing or blank oauth_verifier"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs index 425fa1742f..84d496918a 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; new ChunkingCookieManager(null) { ChunkSize = null }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); - IList values = context.Response.Headers.GetValues("Set-Cookie"); + var values = context.Response.Headers["Set-Cookie"]; Assert.Equal(1, values.Count); Assert.Equal("TestCookie=" + testString + "; path=/", values[0]); } @@ -30,9 +30,9 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; new ChunkingCookieManager(null) { ChunkSize = 30 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); - IList values = context.Response.Headers.GetValues("Set-Cookie"); + var values = context.Response.Headers["Set-Cookie"]; Assert.Equal(9, values.Count); - Assert.Equal(new[] + Assert.Equal(new[] { "TestCookie=chunks:8; path=/", "TestCookieC1=abcdefgh; path=/", @@ -53,9 +53,9 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure string testString = "\"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; new ChunkingCookieManager(null) { ChunkSize = 32 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); - IList values = context.Response.Headers.GetValues("Set-Cookie"); + var values = context.Response.Headers["Set-Cookie"]; Assert.Equal(9, values.Count); - Assert.Equal(new[] + Assert.Equal(new[] { "TestCookie=chunks:8; path=/", "TestCookieC1=\"abcdefgh\"; path=/", @@ -73,7 +73,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure public void GetLargeChunkedCookie_Reassembled() { HttpContext context = new DefaultHttpContext(); - context.Request.Headers.AppendValues("Cookie", + context.Request.Headers["Cookie"] = new[] + { "TestCookie=chunks:7", "TestCookieC1=abcdefghi", "TestCookieC2=jklmnopqr", @@ -81,7 +82,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure "TestCookieC4=123456789", "TestCookieC5=ABCDEFGHI", "TestCookieC6=JKLMNOPQR", - "TestCookieC7=STUVWXYZ"); + "TestCookieC7=STUVWXYZ" + }; string result = new ChunkingCookieManager(null).GetRequestCookie(context, "TestCookie"); string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -92,7 +94,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure public void GetLargeChunkedCookieWithQuotes_Reassembled() { HttpContext context = new DefaultHttpContext(); - context.Request.Headers.AppendValues("Cookie", + context.Request.Headers["Cookie"] = new[] + { "TestCookie=chunks:7", "TestCookieC1=\"abcdefghi\"", "TestCookieC2=\"jklmnopqr\"", @@ -100,7 +103,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure "TestCookieC4=\"123456789\"", "TestCookieC5=\"ABCDEFGHI\"", "TestCookieC6=\"JKLMNOPQR\"", - "TestCookieC7=\"STUVWXYZ\""); + "TestCookieC7=\"STUVWXYZ\"" + }; string result = new ChunkingCookieManager(null).GetRequestCookie(context, "TestCookie"); string testString = "\"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; @@ -111,7 +115,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure public void GetLargeChunkedCookieWithMissingChunk_ThrowingEnabled_Throws() { HttpContext context = new DefaultHttpContext(); - context.Request.Headers.AppendValues("Cookie", + context.Request.Headers["Cookie"] = new[] + { "TestCookie=chunks:7", "TestCookieC1=abcdefghi", // Missing chunk "TestCookieC2=jklmnopqr", @@ -119,7 +124,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure "TestCookieC4=123456789", "TestCookieC5=ABCDEFGHI", "TestCookieC6=JKLMNOPQR", - "TestCookieC7=STUVWXYZ"); + "TestCookieC7=STUVWXYZ" + }; Assert.Throws(() => new ChunkingCookieManager(null).GetRequestCookie(context, "TestCookie")); } @@ -128,7 +134,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure public void GetLargeChunkedCookieWithMissingChunk_ThrowingDisabled_NotReassembled() { HttpContext context = new DefaultHttpContext(); - context.Request.Headers.AppendValues("Cookie", + context.Request.Headers["Cookie"] = new[] + { "TestCookie=chunks:7", "TestCookieC1=abcdefghi", // Missing chunk "TestCookieC2=jklmnopqr", @@ -136,7 +143,8 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure "TestCookieC4=123456789", "TestCookieC5=ABCDEFGHI", "TestCookieC6=JKLMNOPQR", - "TestCookieC7=STUVWXYZ"); + "TestCookieC7=STUVWXYZ" + }; string result = new ChunkingCookieManager(null) { ThrowForPartialCookies = false }.GetRequestCookie(context, "TestCookie"); string testString = "chunks:7"; @@ -147,10 +155,10 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure public void DeleteChunkedCookieWithOptions_AllDeleted() { HttpContext context = new DefaultHttpContext(); - context.Request.Headers.AppendValues("Cookie", "TestCookie=chunks:7"); + context.Request.Headers.Append("Cookie", "TestCookie=chunks:7"); new ChunkingCookieManager(null).DeleteCookie(context, "TestCookie", new CookieOptions() { Domain = "foo.com" }); - var cookies = context.Response.Headers.GetValues("Set-Cookie"); + var cookies = context.Response.Headers["Set-Cookie"]; Assert.Equal(8, cookies.Count); Assert.Equal(new[] {