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) public void ConfigureServices(IServiceCollection services)
{ {
services.AddWebEncoders(); services.AddAuthentication();
services.AddDataProtection();
} }
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)

View File

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

View File

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

View File

@ -19,8 +19,7 @@ namespace CookieSample
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddWebEncoders(); services.AddAuthentication();
services.AddDataProtection();
services.Configure<ExternalAuthenticationOptions>(options => services.Configure<ExternalAuthenticationOptions>(options =>
{ {
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
@ -139,13 +138,13 @@ namespace CookieSample
OnGetUserInformationAsync = async (context) => OnGetUserInformationAsync = async (context) =>
{ {
// Get the GitHub user // 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.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 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(); userResponse.EnsureSuccessStatusCode();
var text = await userResponse.Content.ReadAsStringAsync(); var text = await userResponse.Content.ReadAsStringAsync();
JObject user = JObject.Parse(text); var user = JObject.Parse(text);
var identity = new ClaimsIdentity( var identity = new ClaimsIdentity(
context.Options.AuthenticationScheme, context.Options.AuthenticationScheme,
@ -184,7 +183,7 @@ namespace CookieSample
{ {
signoutApp.Run(async context => signoutApp.Run(async context =>
{ {
string authType = context.Request.Query["authscheme"]; var authType = context.Request.Query["authscheme"];
if (!string.IsNullOrEmpty(authType)) if (!string.IsNullOrEmpty(authType))
{ {
// By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo), // 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] IUrlEncoder urlEncoder,
[NotNull] IOptions<CookieAuthenticationOptions> options, [NotNull] IOptions<CookieAuthenticationOptions> options,
ConfigureOptions<CookieAuthenticationOptions> configureOptions) ConfigureOptions<CookieAuthenticationOptions> configureOptions)
: base(next, options, loggerFactory, configureOptions) : base(next, options, loggerFactory, urlEncoder, configureOptions)
{ {
if (Options.Notifications == null) 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) public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<CookieAuthenticationOptions> configure, string optionsName)
{ {
services.AddWebEncoders();
return services.Configure(configure, optionsName); 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) public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName)
{ {
services.AddWebEncoders();
return services.Configure<CookieAuthenticationOptions>(config, optionsName); return services.Configure<CookieAuthenticationOptions>(config, optionsName);
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -180,7 +180,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
ResponseMode = Options.ResponseMode, ResponseMode = Options.ResponseMode,
ResponseType = Options.ResponseType, ResponseType = Options.ResponseType,
Scope = Options.Scope, 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) if (Options.ProtocolValidator.RequireNonce)

View File

@ -17,6 +17,7 @@ using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Microsoft.IdentityModel.Protocols; using Microsoft.IdentityModel.Protocols;
using Microsoft.Framework.Internal; using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
@ -40,10 +41,11 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
[NotNull] RequestDelegate next, [NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory, [NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions, [NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<OpenIdConnectAuthenticationOptions> options, [NotNull] IOptions<OpenIdConnectAuthenticationOptions> options,
ConfigureOptions<OpenIdConnectAuthenticationOptions> configureOptions = null) 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)) 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(); var parameterBuilder = new StringBuilder();
foreach (var authorizationKey in authorizationParts) 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--; parameterBuilder.Length--;
var parameterString = parameterBuilder.ToString(); var parameterString = parameterBuilder.ToString();
@ -252,9 +252,9 @@ namespace Microsoft.AspNet.Authentication.Twitter
var canonicalizedRequestBuilder = new StringBuilder(); var canonicalizedRequestBuilder = new StringBuilder();
canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
canonicalizedRequestBuilder.Append("&"); canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(RequestTokenEndpoint)); canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(RequestTokenEndpoint));
canonicalizedRequestBuilder.Append("&"); canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString));
var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString()); var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString());
authorizationParts.Add("oauth_signature", signature); authorizationParts.Add("oauth_signature", signature);
@ -264,7 +264,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
foreach (var authorizationPart in authorizationParts) foreach (var authorizationPart in authorizationParts)
{ {
authorizationHeaderBuilder.AppendFormat( authorizationHeaderBuilder.AppendFormat(
"{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); "{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value));
} }
authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;
@ -306,7 +306,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
var parameterBuilder = new StringBuilder(); var parameterBuilder = new StringBuilder();
foreach (var authorizationKey in authorizationParts) 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--; parameterBuilder.Length--;
var parameterString = parameterBuilder.ToString(); var parameterString = parameterBuilder.ToString();
@ -314,9 +314,9 @@ namespace Microsoft.AspNet.Authentication.Twitter
var canonicalizedRequestBuilder = new StringBuilder(); var canonicalizedRequestBuilder = new StringBuilder();
canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
canonicalizedRequestBuilder.Append("&"); canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(AccessTokenEndpoint)); canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(AccessTokenEndpoint));
canonicalizedRequestBuilder.Append("&"); canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString));
var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString()); var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString());
authorizationParts.Add("oauth_signature", signature); authorizationParts.Add("oauth_signature", signature);
@ -327,7 +327,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
foreach (var authorizationPart in authorizationParts) foreach (var authorizationPart in authorizationParts)
{ {
authorizationHeaderBuilder.AppendFormat( authorizationHeaderBuilder.AppendFormat(
"{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); "{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value));
} }
authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;
@ -367,15 +367,15 @@ namespace Microsoft.AspNet.Authentication.Twitter
return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture); 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()) using (var algorithm = new HMACSHA1())
{ {
algorithm.Key = Encoding.ASCII.GetBytes( algorithm.Key = Encoding.ASCII.GetBytes(
string.Format(CultureInfo.InvariantCulture, string.Format(CultureInfo.InvariantCulture,
"{0}&{1}", "{0}&{1}",
Uri.EscapeDataString(consumerSecret), UrlEncoder.UrlEncode(consumerSecret),
string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret))); string.IsNullOrEmpty(tokenSecret) ? string.Empty : UrlEncoder.UrlEncode(tokenSecret)));
var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData)); var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData));
return Convert.ToBase64String(hash); return Convert.ToBase64String(hash);
} }

View File

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

View File

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

View File

@ -4,6 +4,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication 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="context">The utility object to observe the current request and response</param>
/// <param name="logger">The logging factory used to create loggers</param> /// <param name="logger">The logging factory used to create loggers</param>
/// <returns>async completion</returns> /// <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; 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.Internal;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Authentication namespace Microsoft.AspNet.Authentication
{ {
@ -19,6 +20,7 @@ namespace Microsoft.AspNet.Authentication
[NotNull] RequestDelegate next, [NotNull] RequestDelegate next,
[NotNull] IOptions<TOptions> options, [NotNull] IOptions<TOptions> options,
[NotNull] ILoggerFactory loggerFactory, [NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
ConfigureOptions<TOptions> configureOptions) ConfigureOptions<TOptions> configureOptions)
{ {
if (configureOptions != null) if (configureOptions != null)
@ -31,6 +33,7 @@ namespace Microsoft.AspNet.Authentication
Options = options.Options; Options = options.Options;
} }
Logger = loggerFactory.CreateLogger(this.GetType().FullName); Logger = loggerFactory.CreateLogger(this.GetType().FullName);
UrlEncoder = encoder;
_next = next; _next = next;
} }
@ -41,10 +44,12 @@ namespace Microsoft.AspNet.Authentication
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public IUrlEncoder UrlEncoder { get; set; }
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
{ {
var handler = CreateHandler(); var handler = CreateHandler();
await handler.Initialize(Options, context, Logger); await handler.Initialize(Options, context, Logger, UrlEncoder);
try try
{ {
if (!await handler.InvokeAsync()) if (!await handler.InvokeAsync())

View File

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

View File

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

View File

@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Authentication
{ {
public TestHandler(string scheme) 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; Options.AuthenticationScheme = scheme;
} }
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Authentication
{ {
public TestAutoHandler(string scheme, bool auto) 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.AuthenticationScheme = scheme;
Options.AutomaticAuthentication = auto; Options.AutomaticAuthentication = auto;
} }

View File

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

View File

@ -109,7 +109,7 @@ namespace Microsoft.AspNet.Authentication.Google
var transaction = await SendAsync(server, "https://example.com/challenge"); var transaction = await SendAsync(server, "https://example.com/challenge");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
var query = transaction.Response.Headers.Location.Query; 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] [Fact]
@ -124,7 +124,7 @@ namespace Microsoft.AspNet.Authentication.Google
var transaction = await SendAsync(server, "https://example.com/401"); var transaction = await SendAsync(server, "https://example.com/401");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
var query = transaction.Response.Headers.Location.Query; 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] [Fact]
@ -231,7 +231,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact] [Fact]
public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() 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 => var server = CreateServer(options =>
{ {
options.ClientId = "Test Id"; options.ClientId = "Test Id";
@ -284,7 +284,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server, 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); correlationKey + "=" + correlationValue);
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.Response.Headers.Location.ToString().ShouldBe("/me");
@ -308,7 +308,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact] [Fact]
public async Task ReplyPathWillRejectIfCodeIsInvalid() 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 => var server = CreateServer(options =>
{ {
options.ClientId = "Test Id"; options.ClientId = "Test Id";
@ -329,7 +329,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server, 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); correlationKey + "=" + correlationValue);
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied"); transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied");
@ -338,7 +338,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact] [Fact]
public async Task ReplyPathWillRejectIfAccessTokenIsMissing() 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 => var server = CreateServer(options =>
{ {
options.ClientId = "Test Id"; options.ClientId = "Test Id";
@ -359,7 +359,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server, 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); correlationKey + "=" + correlationValue);
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied"); transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied");
@ -368,7 +368,7 @@ namespace Microsoft.AspNet.Authentication.Google
[Fact] [Fact]
public async Task AuthenticatedEventCanGetRefreshToken() 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 => var server = CreateServer(options =>
{ {
options.ClientId = "Test Id"; options.ClientId = "Test Id";
@ -431,7 +431,7 @@ namespace Microsoft.AspNet.Authentication.Google
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server, 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); correlationKey + "=" + correlationValue);
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.Response.Headers.Location.ToString().ShouldBe("/me");
@ -532,8 +532,7 @@ namespace Microsoft.AspNet.Authentication.Google
}, },
services => services =>
{ {
services.AddWebEncoders(); services.AddAuthentication();
services.AddDataProtection();
services.Configure<ExternalAuthenticationOptions>(options => services.Configure<ExternalAuthenticationOptions>(options =>
{ {
options.SignInScheme = CookieAuthenticationScheme; options.SignInScheme = CookieAuthenticationScheme;
@ -614,7 +613,7 @@ namespace Microsoft.AspNet.Authentication.Google
public string FindClaimValue(string claimType) 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) if (claim == null)
{ {
return null; return null;

View File

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

View File

@ -19,6 +19,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.TestHost; using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.WebEncoders;
using Newtonsoft.Json; using Newtonsoft.Json;
using Shouldly; using Shouldly;
using Xunit; using Xunit;
@ -143,7 +144,7 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
var transaction = await SendAsync(server, 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); correlationKey + "=" + correlationValue);
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.Response.Headers.Location.ToString().ShouldBe("/me");
@ -177,8 +178,7 @@ namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount
}, },
services => services =>
{ {
services.AddWebEncoders(); services.AddAuthentication();
services.AddDataProtection();
services.Configure<ExternalAuthenticationOptions>(options => services.Configure<ExternalAuthenticationOptions>(options =>
{ {
options.SignInScheme = "External"; 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) 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.DependencyInjection;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
using Microsoft.IdentityModel.Protocols; using Microsoft.IdentityModel.Protocols;
using Shouldly; using Shouldly;
using Xunit; using Xunit;
@ -115,7 +116,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
var propertiesFormatter = new AuthenticationPropertiesFormater(); var propertiesFormatter = new AuthenticationPropertiesFormater();
var protectedProperties = propertiesFormatter.Protect(new AuthenticationProperties()); 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 code = Guid.NewGuid().ToString();
var message = var message =
new OpenIdConnectMessage new OpenIdConnectMessage
@ -565,9 +566,9 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
/// </summary> /// </summary>
public class CustomOpenIdConnectAuthenticationHandler : OpenIdConnectAuthenticationHandler 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) public override bool ShouldHandleScheme(string authenticationScheme)
@ -603,11 +604,12 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
RequestDelegate next, RequestDelegate next,
IDataProtectionProvider dataProtectionProvider, IDataProtectionProvider dataProtectionProvider,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IUrlEncoder encoder,
IOptions<ExternalAuthenticationOptions> externalOptions, IOptions<ExternalAuthenticationOptions> externalOptions,
IOptions<OpenIdConnectAuthenticationOptions> options, IOptions<OpenIdConnectAuthenticationOptions> options,
ConfigureOptions<OpenIdConnectAuthenticationOptions> configureOptions = null ConfigureOptions<OpenIdConnectAuthenticationOptions> configureOptions = null
) )
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) : base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions)
{ {
Logger = (loggerFactory as CustomLoggerFactory).Logger; Logger = (loggerFactory as CustomLoggerFactory).Logger;
} }

View File

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

View File

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