diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index cc1dc91685..b002fc2d68 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -193,8 +193,8 @@ namespace Microsoft.AspNet.Authentication.Cookies _sessionKey = await Options.SessionStore.StoreAsync(model); var principal = new ClaimsPrincipal( new ClaimsIdentity( - new[] { new Claim(SessionIdClaim, _sessionKey) }, - Options.AuthenticationScheme)); + new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) }, + Options.ClaimsIssuer)); model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } var cookieValue = Options.TicketDataFormat.Protect(model); @@ -243,7 +243,7 @@ namespace Microsoft.AspNet.Authentication.Cookies await Options.SessionStore.RenewAsync(_sessionKey, model); var principal = new ClaimsPrincipal( new ClaimsIdentity( - new[] { new Claim(SessionIdClaim, _sessionKey) }, + new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) }, Options.AuthenticationScheme)); model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index aa306d683a..3549eec2d2 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -13,7 +13,6 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.WebUtilities; -using Microsoft.Framework.WebEncoders; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.Facebook @@ -65,34 +64,34 @@ namespace Microsoft.AspNet.Authentication.Facebook var context = new FacebookAuthenticatedContext(Context, Options, user, tokens); var identity = new ClaimsIdentity( - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.UserName)) { - identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Email)) { - identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Name)) { - identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.ClaimsIssuer)); // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. if (string.IsNullOrEmpty(context.UserName)) { - identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.ClaimsIssuer)); } } if (!string.IsNullOrEmpty(context.Link)) { - identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.ClaimsIssuer)); } context.Properties = properties; context.Principal = new ClaimsPrincipal(identity); @@ -104,7 +103,7 @@ namespace Microsoft.AspNet.Authentication.Facebook private string GenerateAppSecretProof(string accessToken) { - using (HMACSHA256 algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret))) + using (var algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret))) { var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); var builder = new StringBuilder(); @@ -124,4 +123,4 @@ namespace Microsoft.AspNet.Authentication.Facebook return string.Join(",", Options.Scope); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs index b54f657be5..621e77d830 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs @@ -33,39 +33,39 @@ namespace Microsoft.AspNet.Authentication.Google var context = new GoogleAuthenticatedContext(Context, Options, user, tokens); var identity = new ClaimsIdentity( - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, - ClaimValueTypes.String, Options.AuthenticationScheme)); + ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.GivenName)) { identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, - ClaimValueTypes.String, Options.AuthenticationScheme)); + ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.FamilyName)) { identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, - ClaimValueTypes.String, Options.AuthenticationScheme)); + ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Name)) { identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, - Options.AuthenticationScheme)); + Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Email)) { identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, - Options.AuthenticationScheme)); + Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Profile)) { identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, - Options.AuthenticationScheme)); + Options.ClaimsIssuer)); } context.Properties = properties; context.Principal = new ClaimsPrincipal(identity); @@ -120,4 +120,4 @@ namespace Microsoft.AspNet.Authentication.Google queryStrings[name] = value; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 2921b6b211..db7a3c9881 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -1,7 +1,6 @@ // 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 System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs index 1dab084f04..e65b800eda 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs @@ -1,12 +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; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Authentication.Google { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs index 4ecaabab6d..31484f9985 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -32,18 +32,18 @@ namespace Microsoft.AspNet.Authentication.MicrosoftAccount var identity = new ClaimsIdentity( new[] { - new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationScheme), - new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.AuthenticationScheme), - new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.AuthenticationScheme), - new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.AuthenticationScheme) + new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.ClaimsIssuer), + new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.ClaimsIssuer), + new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.ClaimsIssuer), + new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.ClaimsIssuer) }, - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrWhiteSpace(context.Email)) { - identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.ClaimsIssuer)); } context.Principal = new ClaimsPrincipal(identity); diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index e4357a68a6..70d4544a25 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -69,7 +69,7 @@ namespace Microsoft.AspNet.Authentication.OAuth if (Options.StateDataFormat == null) { var dataProtector = dataProtectionProvider.CreateProtector( - this.GetType().FullName, Options.AuthenticationScheme, "v1"); + GetType().FullName, Options.AuthenticationScheme, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs index bfbea1e29d..62296c4a96 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; @@ -106,11 +105,6 @@ namespace Microsoft.AspNet.Authentication.OAuth /// public string SignInScheme { get; set; } - /// - /// Gets or sets the issuer that should be used for any claims that are created - /// - public string ClaimsIssuer { get; set; } - /// /// Gets or sets the type used to secure data handled by the middleware. /// diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index c88d456043..b088519509 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -79,7 +79,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer // notify user token was received var securityTokenReceivedNotification = - new SecurityTokenReceivedNotification(Context, Options) + new SecurityTokenReceivedNotification(Context, Options) { ProtocolMessage = Context, SecurityToken = token, @@ -110,7 +110,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer } else { - IEnumerable issuers = new[] { _configuration.Issuer }; + var issuers = new[] { _configuration.Issuer }; validationParameters.ValidIssuers = (validationParameters.ValidIssuers == null ? issuers : validationParameters.ValidIssuers.Concat(issuers)); } @@ -122,8 +122,8 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer { if (validator.CanReadToken(token)) { - ClaimsPrincipal principal = validator.ValidateToken(token, validationParameters, out validatedToken); - AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); + var principal = validator.ValidateToken(token, validationParameters, out validatedToken); + var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) { ProtocolMessage = Context, diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index ed1242b95b..c76071b6ab 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -23,8 +23,6 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer /// public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware { - private readonly ILogger _logger; - /// /// Bearer authentication component which is added to an HTTP pipeline. This constructor is not /// called by application code directly, instead it is added by calling the the IAppBuilder UseOAuthBearerAuthentication @@ -72,7 +70,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer Options.MetadataAddress += ".well-known/openid-configuration"; } - HttpClient httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + var httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); httpClient.Timeout = Options.BackchannelTimeout; httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index 00cc96c7a7..e520406875 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Net.Http; -using Microsoft.AspNet.Authentication; using Microsoft.IdentityModel.Protocols; namespace Microsoft.AspNet.Authentication.OAuthBearer diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index cd09a14165..61ff95e2f4 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -78,7 +78,7 @@ namespace Microsoft.AspNet.Authentication.Twitter return new AuthenticationTicket(properties, Options.AuthenticationScheme); } - string oauthVerifier = query.Get("oauth_verifier"); + var oauthVerifier = query.Get("oauth_verifier"); if (string.IsNullOrWhiteSpace(oauthVerifier)) { Logger.LogWarning("Missing or blank oauth_verifier"); @@ -93,12 +93,12 @@ namespace Microsoft.AspNet.Authentication.Twitter new ClaimsIdentity( new[] { - new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), - new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), - new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), - new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme) + new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer), + new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer), + new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer), + new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer) }, - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType)); context.Properties = requestToken.Properties; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index 7cfd6138ff..188f903c49 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -35,6 +35,12 @@ namespace Microsoft.AspNet.Authentication Logger = loggerFactory.CreateLogger(this.GetType().FullName); UrlEncoder = encoder; + if (string.IsNullOrEmpty(Options.ClaimsIssuer)) + { + // Default to something reasonable + Options.ClaimsIssuer = Options.AuthenticationScheme; + } + _next = next; } diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs index b1c2bc263a..54f8a7a352 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs @@ -33,6 +33,11 @@ namespace Microsoft.AspNet.Authentication /// public bool AutomaticAuthentication { get; set; } + /// + /// Gets or sets the issuer that should be used for any claims that are created + /// + public string ClaimsIssuer { get; set; } + /// /// Additional information about the authentication type which is made available to the application. /// diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs index 723736973d..28d74196fa 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs @@ -1,7 +1,6 @@ // 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.Framework.Internal; diff --git a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs index ea7234b209..617fe14a16 100644 --- a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs @@ -1,9 +1,6 @@ // 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 System.Collections.Generic; -using System.Linq; using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; @@ -21,7 +18,7 @@ namespace Microsoft.AspNet.Authentication /// public static void AddUserPrincipal([NotNull] HttpContext context, [NotNull] ClaimsPrincipal principal) { - ClaimsPrincipal existingPrincipal = context.User; + var existingPrincipal = context.User; if (existingPrincipal != null) { foreach (var existingClaimsIdentity in existingPrincipal.Identities) diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index d35978aeea..c368365329 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -27,10 +27,10 @@ namespace Microsoft.AspNet.Authentication.Cookies [Fact] public async Task NormalRequestPassesThrough() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { }); - HttpResponseMessage response = await server.CreateClient().GetAsync("http://example.com/normal"); + var response = await server.CreateClient().GetAsync("http://example.com/normal"); response.StatusCode.ShouldBe(HttpStatusCode.OK); } @@ -39,13 +39,13 @@ namespace Microsoft.AspNet.Authentication.Cookies [InlineData(false)] public async Task ProtectedRequestShouldRedirectToLoginOnlyWhenAutomatic(bool auto) { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.AutomaticAuthentication = auto; }); - Transaction transaction = await SendAsync(server, "http://example.com/protected"); + var transaction = await SendAsync(server, "http://example.com/protected"); transaction.Response.StatusCode.ShouldBe(auto ? HttpStatusCode.Redirect : HttpStatusCode.Unauthorized); if (auto) @@ -61,13 +61,13 @@ namespace Microsoft.AspNet.Authentication.Cookies [InlineData(false)] public async Task ProtectedCustomRequestShouldRedirectToCustomLogin(bool auto) { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.AutomaticAuthentication = auto; }); - Transaction transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); + var transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); transaction.Response.StatusCode.ShouldBe(auto ? HttpStatusCode.Redirect : HttpStatusCode.Unauthorized); if (auto) @@ -102,15 +102,15 @@ namespace Microsoft.AspNet.Authentication.Cookies [Fact] public async Task SignInCausesDefaultCookieToBeCreated() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; }, SignInAsAlice); - Transaction transaction = await SendAsync(server, "http://example.com/testpath"); + var transaction = await SendAsync(server, "http://example.com/testpath"); - string setCookie = transaction.SetCookie; + var setCookie = transaction.SetCookie; setCookie.ShouldStartWith("TestCookie="); setCookie.ShouldContain("; path=/"); setCookie.ShouldContain("; HttpOnly"); @@ -122,7 +122,7 @@ namespace Microsoft.AspNet.Authentication.Cookies [Fact] public async Task SignInWrongAuthTypeThrows() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; @@ -134,7 +134,7 @@ namespace Microsoft.AspNet.Authentication.Cookies [Fact] public async Task SignOutWrongAuthTypeThrows() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; @@ -155,15 +155,15 @@ namespace Microsoft.AspNet.Authentication.Cookies string requestUri, bool shouldBeSecureOnly) { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; options.CookieSecure = cookieSecureOption; }, SignInAsAlice); - Transaction transaction = await SendAsync(server, requestUri); - string setCookie = transaction.SetCookie; + var transaction = await SendAsync(server, requestUri); + var setCookie = transaction.SetCookie; if (shouldBeSecureOnly) { @@ -187,9 +187,9 @@ namespace Microsoft.AspNet.Authentication.Cookies options.CookieHttpOnly = true; }, SignInAsAlice, new Uri("http://example.com/base")); - Transaction transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); + var transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); - string setCookie1 = transaction1.SetCookie; + var setCookie1 = transaction1.SetCookie; setCookie1.ShouldContain("TestCookie="); setCookie1.ShouldContain(" path=/foo"); @@ -197,16 +197,16 @@ namespace Microsoft.AspNet.Authentication.Cookies setCookie1.ShouldContain(" secure"); setCookie1.ShouldContain(" HttpOnly"); - TestServer server2 = CreateServer(options => + var server2 = CreateServer(options => { options.CookieName = "SecondCookie"; options.CookieSecure = CookieSecureOption.Never; options.CookieHttpOnly = false; }, SignInAsAlice, new Uri("http://example.com/base")); - Transaction transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); + var transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); - string setCookie2 = transaction2.SetCookie; + var setCookie2 = transaction2.SetCookie; setCookie2.ShouldContain("SecondCookie="); setCookie2.ShouldContain(" path=/base"); @@ -219,14 +219,14 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieContainsIdentity() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); } @@ -235,7 +235,7 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieAppliesClaimsTransform() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }, @@ -253,9 +253,9 @@ namespace Microsoft.AspNet.Authentication.Cookies return p; })); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); FindClaimValue(transaction2, "xform").ShouldBe("yup"); @@ -266,24 +266,24 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieStopsWorkingAfterExpiration() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); options.SlidingExpiration = false; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(7)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(7)); - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); transaction2.SetCookie.ShouldBe(null); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); @@ -297,7 +297,7 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieExpirationCanBeOverridenInSignin() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); @@ -311,17 +311,17 @@ namespace Microsoft.AspNet.Authentication.Cookies return Task.FromResult(null); }); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); transaction2.SetCookie.ShouldBe(null); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); @@ -335,7 +335,7 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieExpirationCanBeOverridenInEvent() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); @@ -349,17 +349,17 @@ namespace Microsoft.AspNet.Authentication.Cookies }; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); transaction2.SetCookie.ShouldBe(null); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); @@ -373,25 +373,25 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieIsRenewedWithSlidingExpiration() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); options.SlidingExpiration = true; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(4)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(4)); // transaction4 should arrive with a new SetCookie value - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(4)); @@ -410,13 +410,13 @@ namespace Microsoft.AspNet.Authentication.Cookies [Fact] public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.AutomaticAuthentication = true; }); - Transaction transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); + var transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); var responded = transaction.Response.Headers.GetValues("X-Responded-JSON"); @@ -429,9 +429,7 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieUsesPathBaseByDefault() { var clock = new TestClock(); - TestServer server = CreateServer(options => - { - }, + var server = CreateServer(options => { }, context => { Assert.Equal(new PathString("/base"), context.Request.PathBase); @@ -441,7 +439,7 @@ namespace Microsoft.AspNet.Authentication.Cookies }, new Uri("http://example.com/base")); - Transaction transaction1 = await SendAsync(server, "http://example.com/base/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/base/testpath"); Assert.True(transaction1.SetCookie.Contains("path=/base")); } @@ -449,15 +447,15 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieTurns401To403IfAuthenticated() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); } @@ -466,20 +464,20 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieTurns401ToAccessDeniedWhenSetAndIfAuthenticated() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.AccessDeniedPath = new PathString("/accessdenied"); }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - Uri location = transaction2.Response.Headers.Location; + var location = transaction2.Response.Headers.Location; location.LocalPath.ShouldBe("/accessdenied"); } @@ -487,21 +485,21 @@ namespace Microsoft.AspNet.Authentication.Cookies public async Task CookieDoesNothingTo401IfNotAuthenticated() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); } private static string FindClaimValue(Transaction transaction, string claimType) { - XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + var claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); if (claim == null) { return null; @@ -514,9 +512,9 @@ namespace Microsoft.AspNet.Authentication.Cookies var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Add("Cookie", cookie); - HttpResponseMessage response2 = await server.CreateClient().SendAsync(request); - string text = await response2.Content.ReadAsStringAsync(); - XElement me = XElement.Parse(text); + var response2 = await server.CreateClient().SendAsync(request); + var text = await response2.Content.ReadAsStringAsync(); + var me = XElement.Parse(text); return me; } @@ -525,6 +523,7 @@ namespace Microsoft.AspNet.Authentication.Cookies var server = TestServer.Create(app => { app.UseCookieAuthentication(configureOptions); + if (claimsTransform != null) { app.UseClaimsTransformation(); diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index 4977a9923a..6279c0a8ea 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -2,10 +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.Linq; using System.Net; -using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; @@ -29,8 +26,7 @@ namespace Microsoft.AspNet.Authentication.Facebook }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -58,7 +54,7 @@ namespace Microsoft.AspNet.Authentication.Facebook context.Authentication.Challenge("Facebook"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -75,8 +71,7 @@ namespace Microsoft.AspNet.Authentication.Facebook }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -96,7 +91,7 @@ namespace Microsoft.AspNet.Authentication.Facebook context.Authentication.Challenge("Facebook"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://www.facebook.com/v2.2/dialog/oauth"); @@ -125,34 +120,5 @@ namespace Microsoft.AspNet.Authentication.Facebook }, configureServices); } - - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - return transaction; - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index f44d4d3e73..7e1dc417b1 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -2,16 +2,12 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Claims; using System.Text; using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; @@ -28,8 +24,6 @@ namespace Microsoft.AspNet.Authentication.Google { public class GoogleMiddlewareTests { - private const string CookieAuthenticationScheme = "Cookie"; - [Fact] public async Task ChallengeWillTriggerRedirection() { @@ -38,7 +32,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.ToString(); location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); @@ -61,7 +55,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientSecret = "Test Secret"; options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/401"); + var transaction = await server.SendAsync("https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.ToString(); location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); @@ -79,7 +73,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); Console.WriteLine(transaction.SetCookie); transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); } @@ -93,7 +87,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientSecret = "Test Secret"; options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/401"); + var transaction = await server.SendAsync("https://example.com/401"); Console.WriteLine(transaction.SetCookie); transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); } @@ -106,7 +100,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email")); @@ -121,7 +115,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientSecret = "Test Secret"; options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/401"); + var transaction = await server.SendAsync("https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email")); @@ -155,7 +149,7 @@ namespace Microsoft.AspNet.Authentication.Google return Task.FromResult(null); }); - var transaction = await SendAsync(server, "https://example.com/challenge2"); + var transaction = await server.SendAsync("https://example.com/challenge2"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("scope=" + UrlEncoder.Default.UrlEncode("https://www.googleapis.com/auth/plus.login")); @@ -179,7 +173,7 @@ namespace Microsoft.AspNet.Authentication.Google } }; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -222,14 +216,16 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode"); + var transaction = await server.SendAsync("https://example.com/signin-google?code=TestCode"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError); } - [Fact] - public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() + [Theory] + [InlineData(null)] + [InlineData("CustomIssuer")] + public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string claimsIssuer) { var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => @@ -237,6 +233,7 @@ namespace Microsoft.AspNet.Authentication.Google options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; options.StateDataFormat = stateFormat; + options.ClaimsIssuer = claimsIssuer; options.BackchannelHttpHandler = new TestHttpMessageHandler { Sender = req => @@ -283,23 +280,24 @@ namespace Microsoft.AspNet.Authentication.Google properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.SetCookie.Count.ShouldBe(2); transaction.SetCookie[0].ShouldContain(correlationKey); - transaction.SetCookie[1].ShouldContain(".AspNet.Cookie"); + transaction.SetCookie[1].ShouldContain(".AspNet." + TestExtensions.CookieAuthenticationScheme); var authCookie = transaction.AuthenticationCookieValue; - transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction = await server.SendAsync("https://example.com/me", authCookie); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); - transaction.FindClaimValue(ClaimTypes.Name).ShouldBe("Test Name"); - transaction.FindClaimValue(ClaimTypes.NameIdentifier).ShouldBe("Test User ID"); - transaction.FindClaimValue(ClaimTypes.GivenName).ShouldBe("Test Given Name"); - transaction.FindClaimValue(ClaimTypes.Surname).ShouldBe("Test Family Name"); - transaction.FindClaimValue(ClaimTypes.Email).ShouldBe("Test email"); + var expectedIssuer = claimsIssuer ?? GoogleAuthenticationDefaults.AuthenticationScheme; + transaction.FindClaimValue(ClaimTypes.Name, expectedIssuer).ShouldBe("Test Name"); + transaction.FindClaimValue(ClaimTypes.NameIdentifier, expectedIssuer).ShouldBe("Test User ID"); + transaction.FindClaimValue(ClaimTypes.GivenName, expectedIssuer).ShouldBe("Test Given Name"); + transaction.FindClaimValue(ClaimTypes.Surname, expectedIssuer).ShouldBe("Test Family Name"); + transaction.FindClaimValue(ClaimTypes.Email, expectedIssuer).ShouldBe("Test email"); // Ensure claims transformation transaction.FindClaimValue("xform").ShouldBe("yup"); @@ -328,7 +326,7 @@ namespace Microsoft.AspNet.Authentication.Google properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -358,7 +356,7 @@ namespace Microsoft.AspNet.Authentication.Google properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -419,7 +417,7 @@ namespace Microsoft.AspNet.Authentication.Google OnAuthenticated = context => { var refreshToken = context.RefreshToken; - context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) }, "Google")); + context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Google") }, "Google")); return Task.FromResult(null); } }; @@ -430,17 +428,17 @@ namespace Microsoft.AspNet.Authentication.Google properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.SetCookie.Count.ShouldBe(2); transaction.SetCookie[0].ShouldContain(correlationKey); - transaction.SetCookie[1].ShouldContain(".AspNet.Cookie"); + transaction.SetCookie[1].ShouldContain(".AspNet." + TestExtensions.CookieAuthenticationScheme); var authCookie = transaction.AuthenticationCookieValue; - transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction = await server.SendAsync("https://example.com/me", authCookie); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } @@ -453,40 +451,13 @@ namespace Microsoft.AspNet.Authentication.Google return res; } - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - if (transaction.Response.Content != null && - transaction.Response.Content.Headers.ContentType != null && - transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") - { - transaction.ResponseElement = XElement.Parse(transaction.ResponseText); - } - return transaction; - } - private static TestServer CreateServer(Action configureOptions, Func testpath = null) { return TestServer.Create(app => { app.UseCookieAuthentication(options => { - options.AuthenticationScheme = CookieAuthenticationScheme; + options.AuthenticationScheme = TestExtensions.CookieAuthenticationScheme; options.AutomaticAuthentication = true; }); app.UseGoogleAuthentication(configureOptions); @@ -502,7 +473,7 @@ namespace Microsoft.AspNet.Authentication.Google } else if (req.Path == new PathString("/me")) { - Describe(res, context.User); + res.Describe(context.User); } else if (req.Path == new PathString("/unauthorized")) { @@ -535,7 +506,7 @@ namespace Microsoft.AspNet.Authentication.Google services.AddAuthentication(); services.Configure(options => { - options.SignInScheme = CookieAuthenticationScheme; + options.SignInScheme = TestExtensions.CookieAuthenticationScheme; }); services.ConfigureClaimsTransformation(p => { @@ -547,79 +518,5 @@ namespace Microsoft.AspNet.Authentication.Google }); } - private static void Describe(HttpResponse res, ClaimsPrincipal user) - { - res.StatusCode = 200; - res.ContentType = "text/xml"; - var xml = new XElement("xml"); - if (user != null) - { - foreach (var identity in user.Identities) - { - xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); - } - } - using (var memory = new MemoryStream()) - { - using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) - { - xml.WriteTo(writer); - } - res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); - } - } - - private class TestHttpMessageHandler : HttpMessageHandler - { - public Func Sender { get; set; } - - protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) - { - if (Sender != null) - { - return Task.FromResult(Sender(request)); - } - - return Task.FromResult(null); - } - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - - public IList SetCookie { get; set; } - - public string ResponseText { get; set; } - public XElement ResponseElement { get; set; } - - public string AuthenticationCookieValue - { - get - { - if (SetCookie != null && SetCookie.Count > 0) - { - var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.Cookie=")); - if (authCookie != null) - { - return authCookie.Substring(0, authCookie.IndexOf(';')); - } - } - - return null; - } - } - - public string FindClaimValue(string claimType) - { - var claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); - if (claim == null) - { - return null; - } - return claim.Attribute("value").Value; - } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 1382fc6401..2d6baba35c 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -1,16 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Net; using System.Net.Http; using System.Security.Claims; using System.Text; using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Authentication.MicrosoftAccount; using Microsoft.AspNet.Builder; @@ -43,13 +38,8 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount context.Response.Redirect(context.RedirectUri + "&custom=test"); } }; - }, - context => - { - context.Authentication.Challenge("Microsoft"); - return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -63,13 +53,8 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount { options.ClientId = "Test Client Id"; options.ClientSecret = "Test Client Secret"; - }, - context => - { - context.Authentication.Challenge("Microsoft"); - return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://login.live.com/oauth20_authorize.srf"); @@ -83,7 +68,7 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest")); + var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest")); var server = CreateServer( options => { @@ -127,15 +112,10 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount OnAuthenticated = context => { var refreshToken = context.RefreshToken; - context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) })); + context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft")); return Task.FromResult(null); } }; - }, - context => - { - Describe(context.Response, context.User); - return true; }); var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Microsoft"; @@ -143,34 +123,46 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.SetCookie.Count.ShouldBe(2); transaction.SetCookie[0].ShouldContain(correlationKey); - transaction.SetCookie[1].ShouldContain(".AspNet.External"); + transaction.SetCookie[1].ShouldContain(".AspNet." + TestExtensions.CookieAuthenticationScheme); var authCookie = transaction.AuthenticationCookieValue; - transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction = await server.SendAsync("https://example.com/me", authCookie); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } - private static TestServer CreateServer(Action configureOptions, Func handler) + private static TestServer CreateServer(Action configureOptions) { return TestServer.Create(app => { app.UseCookieAuthentication(options => { - options.AuthenticationScheme = "External"; + options.AuthenticationScheme = TestExtensions.CookieAuthenticationScheme; options.AutomaticAuthentication = true; }); app.UseMicrosoftAccountAuthentication(configureOptions); + app.Use(async (context, next) => { - if (handler == null || !handler(context)) + var req = context.Request; + var res = context.Response; + if (req.Path == new PathString("/challenge")) + { + context.Authentication.Challenge("Microsoft"); + res.StatusCode = 401; + } + else if (req.Path == new PathString("/me")) + { + res.Describe(context.User); + } + else { await next(); } @@ -181,38 +173,11 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount services.AddAuthentication(); services.Configure(options => { - options.SignInScheme = "External"; + options.SignInScheme = TestExtensions.CookieAuthenticationScheme; }); }); } - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - if (transaction.Response.Content != null && - transaction.Response.Content.Headers.ContentType != null && - transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") - { - transaction.ResponseElement = XElement.Parse(transaction.ResponseText); - } - return transaction; - } - private static HttpResponseMessage ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); @@ -220,78 +185,5 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } - - private static void Describe(HttpResponse res, ClaimsPrincipal principal) - { - res.StatusCode = 200; - res.ContentType = "text/xml"; - var xml = new XElement("xml"); - if (principal != null) - { - foreach (var identity in principal.Identities) - { - xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); - } - } - using (var memory = new MemoryStream()) - { - using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) - { - xml.WriteTo(writer); - } - res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); - } - } - - private class TestHttpMessageHandler : HttpMessageHandler - { - public Func Sender { get; set; } - - protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) - { - if (Sender != null) - { - return Task.FromResult(Sender(request)); - } - - return Task.FromResult(null); - } - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - public XElement ResponseElement { get; set; } - - public string AuthenticationCookieValue - { - get - { - if (SetCookie != null && SetCookie.Count > 0) - { - var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.External=")); - if (authCookie != null) - { - return authCookie.Substring(0, authCookie.IndexOf(';')); - } - } - - return null; - } - } - - public string FindClaimValue(string claimType) - { - XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); - if (claim == null) - { - return null; - } - return claim.Attribute("value").Value; - } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 7ae0db82b8..f21b00f79b 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -2,7 +2,6 @@ // 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.IdentityModel.Tokens; using System.Net; using System.Net.Http; @@ -36,7 +35,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer }; }); - string newBearerToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJodHRwczovL1R1c2hhclRlc3Qub25taWNyb3NvZnQuY29tL1RvZG9MaXN0U2VydmljZS1NYW51YWxKd3QiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9hZmJlY2UwMy1hZWFhLTRmM2YtODVlNy1jZTA4ZGQyMGNlNTAvIiwiaWF0IjoxNDE4MzMwNjE0LCJuYmYiOjE0MTgzMzA2MTQsImV4cCI6MTQxODMzNDUxNCwidmVyIjoiMS4wIiwidGlkIjoiYWZiZWNlMDMtYWVhYS00ZjNmLTg1ZTctY2UwOGRkMjBjZTUwIiwiYW1yIjpbInB3ZCJdLCJvaWQiOiI1Mzk3OTdjMi00MDE5LTQ2NTktOWRiNS03MmM0Yzc3NzhhMzMiLCJ1cG4iOiJWaWN0b3JAVHVzaGFyVGVzdC5vbm1pY3Jvc29mdC5jb20iLCJ1bmlxdWVfbmFtZSI6IlZpY3RvckBUdXNoYXJUZXN0Lm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IkQyMm9aMW9VTzEzTUFiQXZrdnFyd2REVE80WXZJdjlzMV9GNWlVOVUwYnciLCJmYW1pbHlfbmFtZSI6Ikd1cHRhIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImFwcGlkIjoiNjEzYjVhZjgtZjJjMy00MWI2LWExZGMtNDE2Yzk3ODAzMGI3IiwiYXBwaWRhY3IiOiIwIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiYWNyIjoiMSJ9.N_Kw1EhoVGrHbE6hOcm7ERdZ7paBQiNdObvp2c6T6n5CE8p0fZqmUd-ya_EqwElcD6SiKSiP7gj0gpNUnOJcBl_H2X8GseaeeMxBrZdsnDL8qecc6_ygHruwlPltnLTdka67s1Ow4fDSHaqhVTEk6lzGmNEcbNAyb0CxQxU6o7Fh0yHRiWoLsT8yqYk8nKzsHXfZBNby4aRo3_hXaa4i0SZLYfDGGYPdttG4vT_u54QGGd4Wzbonv2gjDlllOVGOwoJS6kfl1h8mk0qxdiIaT_ChbDWgkWvTB7bTvBE-EgHgV0XmAo0WtJeSxgjsG3KhhEPsONmqrSjhIUV4IVnF2w"; + var newBearerToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJodHRwczovL1R1c2hhclRlc3Qub25taWNyb3NvZnQuY29tL1RvZG9MaXN0U2VydmljZS1NYW51YWxKd3QiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9hZmJlY2UwMy1hZWFhLTRmM2YtODVlNy1jZTA4ZGQyMGNlNTAvIiwiaWF0IjoxNDE4MzMwNjE0LCJuYmYiOjE0MTgzMzA2MTQsImV4cCI6MTQxODMzNDUxNCwidmVyIjoiMS4wIiwidGlkIjoiYWZiZWNlMDMtYWVhYS00ZjNmLTg1ZTctY2UwOGRkMjBjZTUwIiwiYW1yIjpbInB3ZCJdLCJvaWQiOiI1Mzk3OTdjMi00MDE5LTQ2NTktOWRiNS03MmM0Yzc3NzhhMzMiLCJ1cG4iOiJWaWN0b3JAVHVzaGFyVGVzdC5vbm1pY3Jvc29mdC5jb20iLCJ1bmlxdWVfbmFtZSI6IlZpY3RvckBUdXNoYXJUZXN0Lm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IkQyMm9aMW9VTzEzTUFiQXZrdnFyd2REVE80WXZJdjlzMV9GNWlVOVUwYnciLCJmYW1pbHlfbmFtZSI6Ikd1cHRhIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImFwcGlkIjoiNjEzYjVhZjgtZjJjMy00MWI2LWExZGMtNDE2Yzk3ODAzMGI3IiwiYXBwaWRhY3IiOiIwIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiYWNyIjoiMSJ9.N_Kw1EhoVGrHbE6hOcm7ERdZ7paBQiNdObvp2c6T6n5CE8p0fZqmUd-ya_EqwElcD6SiKSiP7gj0gpNUnOJcBl_H2X8GseaeeMxBrZdsnDL8qecc6_ygHruwlPltnLTdka67s1Ow4fDSHaqhVTEk6lzGmNEcbNAyb0CxQxU6o7Fh0yHRiWoLsT8yqYk8nKzsHXfZBNby4aRo3_hXaa4i0SZLYfDGGYPdttG4vT_u54QGGd4Wzbonv2gjDlllOVGOwoJS6kfl1h8mk0qxdiIaT_ChbDWgkWvTB7bTvBE-EgHgV0XmAo0WtJeSxgjsG3KhhEPsONmqrSjhIUV4IVnF2w"; var response = await SendAsync(server, "http://example.com/oauth", newBearerToken); response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); } @@ -339,6 +338,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer services => services.AddAuthentication()); } + // TODO: see if we can share the TestExtensions SendAsync method (only diff is auth header) private static async Task SendAsync(TestServer server, string uri, string authorizationHeader = null) { var request = new HttpRequestMessage(HttpMethod.Get, uri); @@ -364,14 +364,5 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer return transaction; } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - public XElement ResponseElement { get; set; } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs index 3f18ee6b94..1e6bea793e 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs @@ -1,7 +1,6 @@ // 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.IdentityModel.Protocols; using System; namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect diff --git a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs index 01315805da..aa9e91e557 100644 --- a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs @@ -1,12 +1,10 @@ // 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.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Security.Principal; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Authentication; using Shouldly; using Xunit; @@ -17,7 +15,7 @@ namespace Microsoft.AspNet.Authentication [Fact] public void AddingToAnonymousIdentityDoesNotKeepAnonymousIdentity() { - HttpContext context = new DefaultHttpContext(); + var context = new DefaultHttpContext(); context.User.ShouldNotBe(null); context.User.Identity.IsAuthenticated.ShouldBe(false); @@ -36,7 +34,7 @@ namespace Microsoft.AspNet.Authentication [Fact] public void AddingExistingIdentityChangesDefaultButPreservesPrior() { - HttpContext context = new DefaultHttpContext(); + var context = new DefaultHttpContext(); context.User = new GenericPrincipal(new GenericIdentity("Test1", "Alpha"), null); context.User.Identity.AuthenticationType.ShouldBe("Alpha"); diff --git a/test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs b/test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs new file mode 100644 index 0000000000..b406f5813f --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs @@ -0,0 +1,73 @@ +// 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.IO; +using System.Linq; +using System.Net.Http; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.TestHost; + +namespace Microsoft.AspNet.Authentication +{ + public static class TestExtensions + { + public const string CookieAuthenticationScheme = "External"; + + public static async Task SendAsync(this TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + public static void Describe(this HttpResponse res, ClaimsPrincipal principal) + { + res.StatusCode = 200; + res.ContentType = "text/xml"; + var xml = new XElement("xml"); + if (principal != null) + { + foreach (var identity in principal.Identities) + { + xml.Add(identity.Claims.Select(claim => + new XElement("claim", new XAttribute("type", claim.Type), + new XAttribute("value", claim.Value), + new XAttribute("issuer", claim.Issuer)))); + } + } + using (var memory = new MemoryStream()) + { + using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) + { + xml.WriteTo(writer); + } + res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); + } + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs b/test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs new file mode 100644 index 0000000000..1a93b16df5 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs @@ -0,0 +1,24 @@ +// 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 System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Authentication +{ + public class TestHttpMessageHandler : HttpMessageHandler + { + public Func Sender { get; set; } + + protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + { + if (Sender != null) + { + return Task.FromResult(Sender(request)); + } + + return Task.FromResult(null); + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/Transaction.cs b/test/Microsoft.AspNet.Authentication.Test/Transaction.cs new file mode 100644 index 0000000000..e32c3b9261 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/Transaction.cs @@ -0,0 +1,50 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Xml.Linq; + +namespace Microsoft.AspNet.Authentication +{ + public class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + + public IList SetCookie { get; set; } + + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + + public string AuthenticationCookieValue + { + get + { + if (SetCookie != null && SetCookie.Count > 0) + { + var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme + "=")); + if (authCookie != null) + { + return authCookie.Substring(0, authCookie.IndexOf(';')); + } + } + + return null; + } + } + + public string FindClaimValue(string claimType, string issuer = null) + { + var claim = ResponseElement.Elements("claim") + .SingleOrDefault(elt => elt.Attribute("type").Value == claimType && + (issuer == null || elt.Attribute("issuer").Value == issuer)); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index 0ad84b7f10..abbe3d37fa 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.Linq; using System.Net; using System.Net.Http; using System.Text; @@ -57,7 +55,7 @@ namespace Microsoft.AspNet.Authentication.Twitter context.Authentication.Challenge("Twitter"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -95,7 +93,7 @@ namespace Microsoft.AspNet.Authentication.Twitter context.Authentication.Challenge("Twitter"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://twitter.com/oauth/authenticate?oauth_token="); @@ -130,49 +128,5 @@ namespace Microsoft.AspNet.Authentication.Twitter }); }); } - - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - return transaction; - } - - private class TestHttpMessageHandler : HttpMessageHandler - { - public Func Sender { get; set; } - - protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) - { - if (Sender != null) - { - return Task.FromResult(Sender(request)); - } - - return Task.FromResult(null); - } - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - } } }