Switch to IUrlEncoder, introduce AddAuthentication

This commit is contained in:
Hao Kung 2015-04-23 22:49:47 -07:00
parent 30d350da26
commit 87c31c5526
30 changed files with 106 additions and 80 deletions

View File

@ -11,8 +11,7 @@ namespace CookieSample
{
public void ConfigureServices(IServiceCollection services)
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)

View File

@ -12,8 +12,7 @@ namespace CookieSessionSample
{
public void ConfigureServices(IServiceCollection services)
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)

View File

@ -13,8 +13,7 @@ namespace OpenIdConnectSample
{
public void ConfigureServices(IServiceCollection services)
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
services.Configure<ExternalAuthenticationOptions>(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

View File

@ -19,8 +19,7 @@ namespace CookieSample
{
public void ConfigureServices(IServiceCollection services)
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
services.Configure<ExternalAuthenticationOptions>(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
@ -139,13 +138,13 @@ namespace CookieSample
OnGetUserInformationAsync = async (context) =>
{
// Get the GitHub user
HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
var userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted);
var userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted);
userResponse.EnsureSuccessStatusCode();
var text = await userResponse.Content.ReadAsStringAsync();
JObject user = JObject.Parse(text);
var user = JObject.Parse(text);
var identity = new ClaimsIdentity(
context.Options.AuthenticationScheme,
@ -184,7 +183,7 @@ namespace CookieSample
{
signoutApp.Run(async context =>
{
string authType = context.Request.Query["authscheme"];
var authType = context.Request.Query["authscheme"];
if (!string.IsNullOrEmpty(authType))
{
// By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo),

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
[NotNull] IUrlEncoder urlEncoder,
[NotNull] IOptions<CookieAuthenticationOptions> options,
ConfigureOptions<CookieAuthenticationOptions> configureOptions)
: base(next, options, loggerFactory, configureOptions)
: base(next, options, loggerFactory, urlEncoder, configureOptions)
{
if (Options.Notifications == null)
{

View File

@ -20,7 +20,6 @@ namespace Microsoft.Framework.DependencyInjection
public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<CookieAuthenticationOptions> configure, string optionsName)
{
services.AddWebEncoders();
return services.Configure(configure, optionsName);
}
@ -31,7 +30,6 @@ namespace Microsoft.Framework.DependencyInjection
public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName)
{
services.AddWebEncoders();
return services.Configure<CookieAuthenticationOptions>(config, optionsName);
}
}

View File

@ -8,13 +8,12 @@ using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Http.Collections;
using Microsoft.AspNet.Http.Extensions;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.WebUtilities;
using Microsoft.Framework.Logging;
using Microsoft.Framework.WebEncoders;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNet.Authentication.Facebook
@ -53,7 +52,7 @@ namespace Microsoft.AspNet.Authentication.Facebook
protected override async Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens)
{
var graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken);
var graphAddress = Options.UserInformationEndpoint + "?access_token=" + UrlEncoder.UrlEncode(tokens.AccessToken);
if (Options.SendAppSecretProof)
{
graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(tokens.AccessToken);

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.Facebook
{
@ -28,10 +29,11 @@ namespace Microsoft.AspNet.Authentication.Facebook
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<FacebookAuthenticationOptions> options,
ConfigureOptions<FacebookAuthenticationOptions> configureOptions = null)
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
: base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions)
{
if (string.IsNullOrWhiteSpace(Options.AppId))
{

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.Google
{
@ -29,10 +30,11 @@ namespace Microsoft.AspNet.Authentication.Google
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<GoogleAuthenticationOptions> options,
ConfigureOptions<GoogleAuthenticationOptions> configureOptions = null)
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
: base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions)
{
if (Options.Notifications == null)
{

View File

@ -7,6 +7,7 @@ using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.MicrosoftAccount
{
@ -26,10 +27,11 @@ namespace Microsoft.AspNet.Authentication.MicrosoftAccount
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<MicrosoftAccountAuthenticationOptions> options,
ConfigureOptions<MicrosoftAccountAuthenticationOptions> configureOptions = null)
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
: base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions)
{
if (Options.Notifications == null)
{

View File

@ -11,6 +11,7 @@ using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.OAuth
{
@ -33,10 +34,11 @@ namespace Microsoft.AspNet.Authentication.OAuth
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<TOptions> options,
ConfigureOptions<TOptions> configureOptions = null)
: base(next, options, loggerFactory, configureOptions)
: base(next, options, loggerFactory, encoder, configureOptions)
{
// todo: review error handling
if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme))

View File

@ -11,6 +11,7 @@ using Microsoft.AspNet.Builder;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
using Microsoft.IdentityModel.Protocols;
namespace Microsoft.AspNet.Authentication.OAuthBearer
@ -32,9 +33,10 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
public OAuthBearerAuthenticationMiddleware(
[NotNull] RequestDelegate next,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<OAuthBearerAuthenticationOptions> options,
ConfigureOptions<OAuthBearerAuthenticationOptions> configureOptions)
: base(next, options, loggerFactory, configureOptions)
: base(next, options, loggerFactory, encoder, configureOptions)
{
if (Options.Notifications == null)
{

View File

@ -180,7 +180,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
ResponseMode = Options.ResponseMode,
ResponseType = Options.ResponseType,
Scope = Options.Scope,
State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties))
State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + UrlEncoder.UrlEncode(Options.StateDataFormat.Protect(properties))
};
if (Options.ProtocolValidator.RequireNonce)

View File

@ -17,6 +17,7 @@ using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.IdentityModel.Protocols;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
@ -40,10 +41,11 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<OpenIdConnectAuthenticationOptions> options,
ConfigureOptions<OpenIdConnectAuthenticationOptions> configureOptions = null)
: base(next, options, loggerFactory, configureOptions)
: base(next, options, loggerFactory, encoder, configureOptions)
{
if (string.IsNullOrEmpty(Options.SignInScheme) && !string.IsNullOrEmpty(externalOptions.Options.SignInScheme))
{

View File

@ -244,7 +244,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
var parameterBuilder = new StringBuilder();
foreach (var authorizationKey in authorizationParts)
{
parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value));
parameterBuilder.AppendFormat("{0}={1}&", UrlEncoder.UrlEncode(authorizationKey.Key), UrlEncoder.UrlEncode(authorizationKey.Value));
}
parameterBuilder.Length--;
var parameterString = parameterBuilder.ToString();
@ -252,9 +252,9 @@ namespace Microsoft.AspNet.Authentication.Twitter
var canonicalizedRequestBuilder = new StringBuilder();
canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(RequestTokenEndpoint));
canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(RequestTokenEndpoint));
canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString));
canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString));
var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString());
authorizationParts.Add("oauth_signature", signature);
@ -264,7 +264,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
foreach (var authorizationPart in authorizationParts)
{
authorizationHeaderBuilder.AppendFormat(
"{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value));
"{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value));
}
authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;
@ -306,7 +306,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
var parameterBuilder = new StringBuilder();
foreach (var authorizationKey in authorizationParts)
{
parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value));
parameterBuilder.AppendFormat("{0}={1}&", UrlEncoder.UrlEncode(authorizationKey.Key), UrlEncoder.UrlEncode(authorizationKey.Value));
}
parameterBuilder.Length--;
var parameterString = parameterBuilder.ToString();
@ -314,9 +314,9 @@ namespace Microsoft.AspNet.Authentication.Twitter
var canonicalizedRequestBuilder = new StringBuilder();
canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(AccessTokenEndpoint));
canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(AccessTokenEndpoint));
canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString));
canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString));
var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString());
authorizationParts.Add("oauth_signature", signature);
@ -327,7 +327,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
foreach (var authorizationPart in authorizationParts)
{
authorizationHeaderBuilder.AppendFormat(
"{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value));
"{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value));
}
authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;
@ -367,15 +367,15 @@ namespace Microsoft.AspNet.Authentication.Twitter
return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture);
}
private static string ComputeSignature(string consumerSecret, string tokenSecret, string signatureData)
private string ComputeSignature(string consumerSecret, string tokenSecret, string signatureData)
{
using (var algorithm = new HMACSHA1())
{
algorithm.Key = Encoding.ASCII.GetBytes(
string.Format(CultureInfo.InvariantCulture,
"{0}&{1}",
Uri.EscapeDataString(consumerSecret),
string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret)));
UrlEncoder.UrlEncode(consumerSecret),
string.IsNullOrEmpty(tokenSecret) ? string.Empty : UrlEncoder.UrlEncode(tokenSecret)));
var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData));
return Convert.ToBase64String(hash);
}

View File

@ -13,6 +13,7 @@ using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.Twitter
{
@ -36,10 +37,11 @@ namespace Microsoft.AspNet.Authentication.Twitter
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<TwitterAuthenticationOptions> options,
ConfigureOptions<TwitterAuthenticationOptions> configureOptions = null)
: base(next, options, loggerFactory, configureOptions)
: base(next, options, loggerFactory, encoder, configureOptions)
{
if (string.IsNullOrWhiteSpace(Options.ConsumerSecret))
{

View File

@ -10,6 +10,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication
{
@ -50,6 +51,8 @@ namespace Microsoft.AspNet.Authentication
protected ILogger Logger { get; private set; }
protected IUrlEncoder UrlEncoder { get; private set; }
internal AuthenticationOptions BaseOptions
{
get { return _baseOptions; }
@ -61,12 +64,13 @@ namespace Microsoft.AspNet.Authentication
public bool Faulted { get; set; }
protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger)
protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger, [NotNull] IUrlEncoder encoder)
{
_baseOptions = options;
Context = context;
RequestPathBase = Request.PathBase;
Logger = logger;
UrlEncoder = encoder;
RegisterAuthenticationHandler();

View File

@ -4,6 +4,7 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Logging;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication
{
@ -22,10 +23,10 @@ namespace Microsoft.AspNet.Authentication
/// <param name="context">The utility object to observe the current request and response</param>
/// <param name="logger">The logging factory used to create loggers</param>
/// <returns>async completion</returns>
public Task Initialize(TOptions options, HttpContext context, ILogger logger)
public Task Initialize(TOptions options, HttpContext context, ILogger logger, IUrlEncoder encoder)
{
Options = options;
return BaseInitializeAsync(options, context, logger);
return BaseInitializeAsync(options, context, logger, encoder);
}
}
}

View File

@ -8,6 +8,7 @@ using Microsoft.AspNet.Http;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication
{
@ -19,6 +20,7 @@ namespace Microsoft.AspNet.Authentication
[NotNull] RequestDelegate next,
[NotNull] IOptions<TOptions> options,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
ConfigureOptions<TOptions> configureOptions)
{
if (configureOptions != null)
@ -31,6 +33,7 @@ namespace Microsoft.AspNet.Authentication
Options = options.Options;
}
Logger = loggerFactory.CreateLogger(this.GetType().FullName);
UrlEncoder = encoder;
_next = next;
}
@ -41,10 +44,12 @@ namespace Microsoft.AspNet.Authentication
public ILogger Logger { get; set; }
public IUrlEncoder UrlEncoder { get; set; }
public async Task Invoke(HttpContext context)
{
var handler = CreateHandler();
await handler.Initialize(Options, context, Logger);
await handler.Initialize(Options, context, Logger, UrlEncoder);
try
{
if (!await handler.InvokeAsync())

View File

@ -3,7 +3,6 @@
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Authentication;
using Microsoft.Framework.Internal;
@ -11,6 +10,13 @@ namespace Microsoft.Framework.DependencyInjection
{
public static class AuthenticationServiceCollectionExtensions
{
public static IServiceCollection AddAuthentication([NotNull] this IServiceCollection services)
{
services.AddWebEncoders();
services.AddDataProtection();
return services;
}
public static IServiceCollection ConfigureClaimsTransformation([NotNull] this IServiceCollection services, [NotNull] Action<ClaimsTransformationOptions> configure)
{
return services.Configure(configure);

View File

@ -2,12 +2,13 @@
"version": "1.0.0-*",
"description": "ASP.NET 5 common types used by the various authentication middleware.",
"dependencies": {
"Microsoft.AspNet.DataProtection.Interfaces": "1.0.0-*",
"Microsoft.AspNet.DataProtection": "1.0.0-*",
"Microsoft.AspNet.Http": "1.0.0-*",
"Microsoft.AspNet.Http.Extensions": "1.0.0-*",
"Microsoft.Framework.Logging.Interfaces": "1.0.0-*",
"Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" },
"Microsoft.Framework.OptionsModel": "1.0.0-*"
"Microsoft.Framework.OptionsModel": "1.0.0-*",
"Microsoft.Framework.WebEncoders": "1.0.0-*"
},
"frameworks": {
"dnx451": { },

View File

@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Authentication
{
public TestHandler(string scheme)
{
Initialize(new TestOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"));
Initialize(new TestOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"), Framework.WebEncoders.UrlEncoder.Default);
Options.AuthenticationScheme = scheme;
}
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Authentication
{
public TestAutoHandler(string scheme, bool auto)
{
Initialize(new TestAutoOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"));
Initialize(new TestAutoOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"), Framework.WebEncoders.UrlEncoder.Default);
Options.AuthenticationScheme = scheme;
Options.AutomaticAuthentication = auto;
}

View File

@ -573,8 +573,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
},
services =>
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
if (claimsTransform != null)
{
services.ConfigureClaimsTransformation(claimsTransform);

View File

@ -109,7 +109,7 @@ namespace Microsoft.AspNet.Authentication.Google
var transaction = await SendAsync(server, "https://example.com/challenge");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
var query = transaction.Response.Headers.Location.Query;
query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email"));
query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email"));
}
[Fact]
@ -124,7 +124,7 @@ namespace Microsoft.AspNet.Authentication.Google
var transaction = await SendAsync(server, "https://example.com/401");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
var query = transaction.Response.Headers.Location.Query;
query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email"));
query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email"));
}
[Fact]
@ -231,7 +231,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact]
public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState()
{
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var server = CreateServer(options =>
{
options.ClientId = "Test Id";
@ -284,7 +284,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server,
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
"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");
@ -308,7 +308,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact]
public async Task ReplyPathWillRejectIfCodeIsInvalid()
{
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var server = CreateServer(options =>
{
options.ClientId = "Test Id";
@ -329,7 +329,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server,
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
"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().ShouldContain("error=access_denied");
@ -338,7 +338,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact]
public async Task ReplyPathWillRejectIfAccessTokenIsMissing()
{
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var server = CreateServer(options =>
{
options.ClientId = "Test Id";
@ -359,7 +359,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server,
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
"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().ShouldContain("error=access_denied");
@ -368,7 +368,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact]
public async Task AuthenticatedEventCanGetRefreshToken()
{
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
var server = CreateServer(options =>
{
options.ClientId = "Test Id";
@ -431,7 +431,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server,
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
"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");
@ -532,8 +532,7 @@ namespace Microsoft.AspNet.Authentication.Google
},
services =>
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
services.Configure<ExternalAuthenticationOptions>(options =>
{
options.SignInScheme = CookieAuthenticationScheme;
@ -614,7 +613,7 @@ namespace Microsoft.AspNet.Authentication.Google
public string FindClaimValue(string claimType)
{
XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType);
var claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType);
if (claim == null)
{
return null;

View File

@ -13,5 +13,8 @@
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -19,6 +19,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.WebEncoders;
using Newtonsoft.Json;
using Shouldly;
using Xunit;
@ -143,7 +144,7 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount
properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server,
"https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state),
"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");
@ -177,8 +178,7 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount
},
services =>
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
services.Configure<ExternalAuthenticationOptions>(options =>
{
options.SignInScheme = "External";

View File

@ -336,7 +336,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
}
});
},
services => services.AddDataProtection());
services => services.AddAuthentication());
}
private static async Task<Transaction> SendAsync(TestServer server, string uri, string authorizationHeader = null)

View File

@ -20,6 +20,7 @@ using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
using Microsoft.IdentityModel.Protocols;
using Shouldly;
using Xunit;
@ -115,7 +116,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
var propertiesFormatter = new AuthenticationPropertiesFormater();
var protectedProperties = propertiesFormatter.Protect(new AuthenticationProperties());
var state = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(protectedProperties);
var state = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + UrlEncoder.Default.UrlEncode(protectedProperties);
var code = Guid.NewGuid().ToString();
var message =
new OpenIdConnectMessage
@ -565,9 +566,9 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
/// </summary>
public class CustomOpenIdConnectAuthenticationHandler : OpenIdConnectAuthenticationHandler
{
public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context, ILogger logger)
public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context, ILogger logger, IUrlEncoder encoder)
{
await base.BaseInitializeAsync(options, context, logger);
await base.BaseInitializeAsync(options, context, logger, encoder);
}
public override bool ShouldHandleScheme(string authenticationScheme)
@ -603,11 +604,12 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
RequestDelegate next,
IDataProtectionProvider dataProtectionProvider,
ILoggerFactory loggerFactory,
IUrlEncoder encoder,
IOptions<ExternalAuthenticationOptions> externalOptions,
IOptions<OpenIdConnectAuthenticationOptions> options,
ConfigureOptions<OpenIdConnectAuthenticationOptions> configureOptions = null
)
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
: base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions)
{
Logger = (loggerFactory as CustomLoggerFactory).Logger;
}

View File

@ -22,6 +22,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.WebEncoders;
using Newtonsoft.Json;
using Shouldly;
using Xunit;
@ -75,7 +76,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
});
var transaction = await SendAsync(server, "https://example.com/challenge");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.Query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile"));
transaction.Response.Headers.Location.Query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile"));
}
[Fact]
@ -92,8 +93,8 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
var transaction = await SendAsync(server, "https://example.com/challenge");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
var query = transaction.Response.Headers.Location.Query;
query.ShouldContain("scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login"));
query.ShouldContain("response_type=" + Uri.EscapeDataString("id_token"));
query.ShouldContain("scope=" + UrlEncoder.Default.UrlEncode("https://www.googleapis.com/auth/plus.login"));
query.ShouldContain("response_type=" + UrlEncoder.Default.UrlEncode("id_token"));
}
[Fact]
@ -148,7 +149,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
var transaction = await SendAsync(server, "https://example.com/signout");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("https://example.com/logout"));
transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(UrlEncoder.Default.UrlEncode("https://example.com/logout"));
}
[Fact]
@ -163,7 +164,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
var transaction = await SendAsync(server, "https://example.com/signout_with_specific_redirect_uri");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("http://www.example.com/specific_redirect_uri"));
transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(UrlEncoder.Default.UrlEncode("http://www.example.com/specific_redirect_uri"));
}
[Fact]
@ -234,8 +235,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
},
services =>
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
services.Configure<ExternalAuthenticationOptions>(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

View File

@ -123,8 +123,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
},
services =>
{
services.AddWebEncoders();
services.AddDataProtection();
services.AddAuthentication();
services.Configure<ExternalAuthenticationOptions>(options =>
{
options.SignInScheme = "External";