Move logger to base handler and moar var

This commit is contained in:
Hao Kung 2015-04-22 12:23:54 -07:00
parent 6072e3b1b8
commit 30d350da26
27 changed files with 169 additions and 227 deletions

View File

@ -22,18 +22,11 @@ namespace Microsoft.AspNet.Authentication.Cookies
private const string HeaderValueMinusOne = "-1";
private const string SessionIdClaim = "Microsoft.AspNet.Authentication.Cookies-SessionId";
private readonly ILogger _logger;
private bool _shouldRenew;
private DateTimeOffset _renewIssuedUtc;
private DateTimeOffset _renewExpiresUtc;
private string _sessionKey;
public CookieAuthenticationHandler([NotNull] ILogger logger)
{
_logger = logger;
}
protected override AuthenticationTicket AuthenticateCore()
{
return AuthenticateCoreAsync().GetAwaiter().GetResult();
@ -54,7 +47,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
if (ticket == null)
{
_logger.LogWarning(@"Unprotect ticket failed");
Logger.LogWarning(@"Unprotect ticket failed");
return null;
}
@ -63,14 +56,14 @@ namespace Microsoft.AspNet.Authentication.Cookies
Claim claim = ticket.Principal.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim));
if (claim == null)
{
_logger.LogWarning(@"SessionId missing");
Logger.LogWarning(@"SessionId missing");
return null;
}
_sessionKey = claim.Value;
ticket = await Options.SessionStore.RetrieveAsync(_sessionKey);
if (ticket == null)
{
_logger.LogWarning(@"Identity missing in session store");
Logger.LogWarning(@"Identity missing in session store");
return null;
}
}

View File

@ -15,8 +15,6 @@ namespace Microsoft.AspNet.Authentication.Cookies
{
public class CookieAuthenticationMiddleware : AuthenticationMiddleware<CookieAuthenticationOptions>
{
private readonly ILogger _logger;
public CookieAuthenticationMiddleware(
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
@ -24,7 +22,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
[NotNull] IUrlEncoder urlEncoder,
[NotNull] IOptions<CookieAuthenticationOptions> options,
ConfigureOptions<CookieAuthenticationOptions> configureOptions)
: base(next, options, configureOptions)
: base(next, options, loggerFactory, configureOptions)
{
if (Options.Notifications == null)
{
@ -36,7 +34,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
}
if (Options.TicketDataFormat == null)
{
IDataProtector dataProtector = dataProtectionProvider.CreateProtector(
var dataProtector = dataProtectionProvider.CreateProtector(
typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationScheme, "v2");
Options.TicketDataFormat = new TicketDataFormat(dataProtector);
}
@ -44,13 +42,11 @@ namespace Microsoft.AspNet.Authentication.Cookies
{
Options.CookieManager = new ChunkingCookieManager(urlEncoder);
}
_logger = loggerFactory.CreateLogger(typeof(CookieAuthenticationMiddleware).FullName);
}
protected override AuthenticationHandler<CookieAuthenticationOptions> CreateHandler()
{
return new CookieAuthenticationHandler(_logger);
return new CookieAuthenticationHandler();
}
}
}

View File

@ -21,8 +21,8 @@ namespace Microsoft.AspNet.Authentication.Facebook
{
internal class FacebookAuthenticationHandler : OAuthAuthenticationHandler<FacebookAuthenticationOptions, IFacebookAuthenticationNotifications>
{
public FacebookAuthenticationHandler(HttpClient httpClient, ILogger logger)
: base(httpClient, logger)
public FacebookAuthenticationHandler(HttpClient httpClient)
: base(httpClient)
{
}
@ -39,9 +39,9 @@ namespace Microsoft.AspNet.Authentication.Facebook
var tokenResponse = await Backchannel.GetAsync(Options.TokenEndpoint + queryBuilder.ToString(), Context.RequestAborted);
tokenResponse.EnsureSuccessStatusCode();
string oauthTokenResponse = await tokenResponse.Content.ReadAsStringAsync();
var oauthTokenResponse = await tokenResponse.Content.ReadAsStringAsync();
IFormCollection form = new FormCollection(FormReader.ReadForm(oauthTokenResponse));
var form = new FormCollection(FormReader.ReadForm(oauthTokenResponse));
var response = new JObject();
foreach (string key in form.Keys)
{
@ -53,7 +53,7 @@ namespace Microsoft.AspNet.Authentication.Facebook
protected override async Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens)
{
string graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken);
var graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken);
if (Options.SendAppSecretProof)
{
graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(tokens.AccessToken);
@ -61,8 +61,8 @@ namespace Microsoft.AspNet.Authentication.Facebook
var graphResponse = await Backchannel.GetAsync(graphAddress, Context.RequestAborted);
graphResponse.EnsureSuccessStatusCode();
string text = await graphResponse.Content.ReadAsStringAsync();
JObject user = JObject.Parse(text);
var text = await graphResponse.Content.ReadAsStringAsync();
var user = JObject.Parse(text);
var context = new FacebookAuthenticatedContext(Context, Options, user, tokens);
var identity = new ClaimsIdentity(
@ -107,8 +107,8 @@ namespace Microsoft.AspNet.Authentication.Facebook
{
using (HMACSHA256 algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret)))
{
byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken));
StringBuilder builder = new StringBuilder();
var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken));
var builder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
builder.Append(hash[i].ToString("x2", CultureInfo.InvariantCulture));

View File

@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Authentication.Facebook
/// <returns>An <see cref="AuthenticationHandler"/> configured with the <see cref="FacebookAuthenticationOptions"/> supplied to the constructor.</returns>
protected override AuthenticationHandler<FacebookAuthenticationOptions> CreateHandler()
{
return new FacebookAuthenticationHandler(Backchannel, Logger);
return new FacebookAuthenticationHandler(Backchannel);
}
}
}
}

View File

@ -33,4 +33,4 @@ namespace Microsoft.Framework.DependencyInjection
return services.Configure<FacebookAuthenticationOptions>(config, optionsName);
}
}
}
}

View File

@ -10,27 +10,26 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.WebUtilities;
using Microsoft.Framework.Logging;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNet.Authentication.Google
{
internal class GoogleAuthenticationHandler : OAuthAuthenticationHandler<GoogleAuthenticationOptions, IGoogleAuthenticationNotifications>
{
public GoogleAuthenticationHandler(HttpClient httpClient, ILogger logger)
: base(httpClient, logger)
public GoogleAuthenticationHandler(HttpClient httpClient)
: base(httpClient)
{
}
protected override async Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens)
{
// Get the Google user
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
HttpResponseMessage graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted);
var graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted);
graphResponse.EnsureSuccessStatusCode();
var text = await graphResponse.Content.ReadAsStringAsync();
JObject user = JObject.Parse(text);
var user = JObject.Parse(text);
var context = new GoogleAuthenticatedContext(Context, Options, user, tokens);
var identity = new ClaimsIdentity(
@ -79,7 +78,7 @@ namespace Microsoft.AspNet.Authentication.Google
// TODO: Abstract this properties override pattern into the base class?
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
{
string scope = FormatScope();
var scope = FormatScope();
var queryStrings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
queryStrings.Add("response_type", "code");
@ -92,10 +91,10 @@ namespace Microsoft.AspNet.Authentication.Google
AddQueryString(queryStrings, properties, "approval_prompt");
AddQueryString(queryStrings, properties, "login_hint");
string state = Options.StateDataFormat.Protect(properties);
var state = Options.StateDataFormat.Protect(properties);
queryStrings.Add("state", state);
string authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings);
var authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings);
return authorizationEndpoint;
}

View File

@ -56,7 +56,7 @@ namespace Microsoft.AspNet.Authentication.Google
/// <returns>An <see cref="AuthenticationHandler"/> configured with the <see cref="GoogleAuthenticationOptions"/> supplied to the constructor.</returns>
protected override AuthenticationHandler<GoogleAuthenticationOptions> CreateHandler()
{
return new GoogleAuthenticationHandler(Backchannel, Logger);
return new GoogleAuthenticationHandler(Backchannel);
}
}
}
}

View File

@ -33,4 +33,4 @@ namespace Microsoft.AspNet.Authentication.Google
/// </summary>
public string AccessType { get; set; }
}
}
}

View File

@ -1,35 +1,31 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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 System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.Framework.Logging;
using Microsoft.AspNet.Http.Authentication;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNet.Authentication.MicrosoftAccount
{
internal class MicrosoftAccountAuthenticationHandler : OAuthAuthenticationHandler<MicrosoftAccountAuthenticationOptions, IMicrosoftAccountAuthenticationNotifications>
{
public MicrosoftAccountAuthenticationHandler(HttpClient httpClient, ILogger logger)
: base(httpClient, logger)
public MicrosoftAccountAuthenticationHandler(HttpClient httpClient)
: base(httpClient)
{
}
protected override async Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
HttpResponseMessage graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted);
var graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted);
graphResponse.EnsureSuccessStatusCode();
string accountString = await graphResponse.Content.ReadAsStringAsync();
JObject accountInformation = JObject.Parse(accountString);
var accountString = await graphResponse.Content.ReadAsStringAsync();
var accountInformation = JObject.Parse(accountString);
var context = new MicrosoftAccountAuthenticatedContext(Context, Options, accountInformation, tokens);
context.Properties = properties;

View File

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.DataProtection;
@ -50,7 +49,7 @@ namespace Microsoft.AspNet.Authentication.MicrosoftAccount
/// <returns>An <see cref="AuthenticationHandler"/> configured with the <see cref="MicrosoftAccountAuthenticationOptions"/> supplied to the constructor.</returns>
protected override AuthenticationHandler<MicrosoftAccountAuthenticationOptions> CreateHandler()
{
return new MicrosoftAccountAuthenticationHandler(Backchannel, Logger);
return new MicrosoftAccountAuthenticationHandler(Backchannel);
}
}
}

View File

@ -19,16 +19,13 @@ namespace Microsoft.AspNet.Authentication.OAuth
where TOptions : OAuthAuthenticationOptions<TNotifications>
where TNotifications : IOAuthAuthenticationNotifications
{
public OAuthAuthenticationHandler(HttpClient backchannel, ILogger logger)
public OAuthAuthenticationHandler(HttpClient backchannel)
{
Backchannel = backchannel;
Logger = logger;
}
protected HttpClient Backchannel { get; private set; }
protected ILogger Logger { get; private set; }
public override async Task<bool> InvokeAsync()
{
if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path)
@ -107,7 +104,7 @@ namespace Microsoft.AspNet.Authentication.OAuth
}
// OAuth2 10.12 CSRF
if (!ValidateCorrelationId(properties, Logger))
if (!ValidateCorrelationId(properties))
{
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
}

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Authentication.OAuth
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<TOptions> options,
ConfigureOptions<TOptions> configureOptions = null)
: base(next, options, configureOptions)
: base(next, options, loggerFactory, configureOptions)
{
// todo: review error handling
if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme))
@ -64,11 +64,9 @@ namespace Microsoft.AspNet.Authentication.OAuth
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "TokenEndpoint"));
}
Logger = loggerFactory.CreateLogger(this.GetType().FullName);
if (Options.StateDataFormat == null)
{
IDataProtector dataProtector = dataProtectionProvider.CreateProtector(
var dataProtector = dataProtectionProvider.CreateProtector(
this.GetType().FullName, Options.AuthenticationScheme, "v1");
Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
}
@ -90,15 +88,13 @@ namespace Microsoft.AspNet.Authentication.OAuth
protected HttpClient Backchannel { get; private set; }
protected ILogger Logger { get; private set; }
/// <summary>
/// Provides the <see cref="AuthenticationHandler"/> object for processing authentication-related requests.
/// </summary>
/// <returns>An <see cref="AuthenticationHandler"/> configured with the <see cref="OAuthAuthenticationOptions"/> supplied to the constructor.</returns>
protected override AuthenticationHandler<TOptions> CreateHandler()
{
return new OAuthAuthenticationHandler<TOptions, TNotifications>(Backchannel, Logger);
return new OAuthAuthenticationHandler<TOptions, TNotifications>(Backchannel);
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")]

View File

@ -17,14 +17,8 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
{
public class OAuthBearerAuthenticationHandler : AuthenticationHandler<OAuthBearerAuthenticationOptions>
{
private readonly ILogger _logger;
private OpenIdConnectConfiguration _configuration;
public OAuthBearerAuthenticationHandler(ILogger logger)
{
_logger = logger;
}
protected override AuthenticationTicket AuthenticateCore()
{
return AuthenticateCoreAsync().GetAwaiter().GetResult();
@ -63,7 +57,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
if (string.IsNullOrEmpty(token))
{
string authorization = Request.Headers.Get("Authorization");
var authorization = Request.Headers.Get("Authorization");
// If no authorization header found, nothing to process further
if (string.IsNullOrEmpty(authorization))
@ -155,7 +149,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
}
catch (Exception ex)
{
_logger.LogError("Exception occurred while processing message", ex);
Logger.LogError("Exception occurred while processing message", ex);
// Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification.
if (Options.RefreshOnIssuerKeyNotFound && ex.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException)))

View File

@ -34,9 +34,8 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IOptions<OAuthBearerAuthenticationOptions> options,
ConfigureOptions<OAuthBearerAuthenticationOptions> configureOptions)
: base(next, options, configureOptions)
: base(next, options, loggerFactory, configureOptions)
{
_logger = loggerFactory.CreateLogger<OAuthBearerAuthenticationMiddleware>();
if (Options.Notifications == null)
{
Options.Notifications = new OAuthBearerAuthenticationNotifications();
@ -86,7 +85,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer
/// <returns>A new instance of the request handler</returns>
protected override AuthenticationHandler<OAuthBearerAuthenticationOptions> CreateHandler()
{
return new OAuthBearerAuthenticationHandler(_logger);
return new OAuthBearerAuthenticationHandler();
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")]

View File

@ -23,18 +23,8 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
private const string NonceProperty = "N";
private const string UriSchemeDelimiter = "://";
private readonly ILogger _logger;
private OpenIdConnectConfiguration _configuration;
/// <summary>
/// Creates a new OpenIdConnectAuthenticationHandler
/// </summary>
/// <param name="logger"></param>
public OpenIdConnectAuthenticationHandler(ILogger logger)
{
_logger = logger;
}
private string CurrentUri
{
get
@ -67,7 +57,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
_configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);
}
OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage()
var openIdConnectMessage = new OpenIdConnectMessage()
{
IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty),
RequestType = OpenIdConnectRequestType.LogoutRequest,
@ -95,10 +85,10 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
if (!notification.HandledResponse)
{
string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl();
var redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl();
if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
{
_logger.LogWarning(Resources.OIDCH_0051_RedirectUriLogoutIsNotWellFormed, redirectUri);
Logger.LogWarning(Resources.OIDCH_0051_RedirectUriLogoutIsNotWellFormed, redirectUri);
}
Response.Redirect(redirectUri);
@ -118,28 +108,25 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <remarks>Uses log id's OIDCH-0026 - OIDCH-0050, next num: 37</remarks>
protected override async Task ApplyResponseChallengeAsync()
{
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug(Resources.OIDCH_0026_ApplyResponseChallengeAsync, this.GetType());
}
Logger.LogDebug(Resources.OIDCH_0026_ApplyResponseChallengeAsync, this.GetType());
if (ShouldConvertChallengeToForbidden())
{
_logger.LogDebug(Resources.OIDCH_0027_401_ConvertedTo_403);
Logger.LogDebug(Resources.OIDCH_0027_401_ConvertedTo_403);
Response.StatusCode = 403;
return;
}
if (Response.StatusCode != 401)
{
_logger.LogDebug(Resources.OIDCH_0028_StatusCodeNot401, Response.StatusCode);
Logger.LogDebug(Resources.OIDCH_0028_StatusCodeNot401, Response.StatusCode);
return;
}
// When Automatic should redirect on 401 even if there wasn't an explicit challenge.
if (ChallengeContext == null && !Options.AutomaticAuthentication)
{
_logger.LogDebug(Resources.OIDCH_0029_ChallengeContextEqualsNull);
Logger.LogDebug(Resources.OIDCH_0029_ChallengeContextEqualsNull);
return;
}
@ -158,17 +145,17 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
if (!string.IsNullOrWhiteSpace(properties.RedirectUri))
{
_logger.LogDebug(Resources.OIDCH_0030_Using_Properties_RedirectUri, properties.RedirectUri);
Logger.LogDebug(Resources.OIDCH_0030_Using_Properties_RedirectUri, properties.RedirectUri);
}
else if (Options.DefaultToCurrentUriOnRedirect)
{
_logger.LogDebug(Resources.OIDCH_0032_UsingCurrentUriRedirectUri, CurrentUri);
Logger.LogDebug(Resources.OIDCH_0032_UsingCurrentUriRedirectUri, CurrentUri);
properties.RedirectUri = CurrentUri;
}
if (!string.IsNullOrWhiteSpace(Options.RedirectUri))
{
_logger.LogDebug(Resources.OIDCH_0031_Using_Options_RedirectUri, Options.RedirectUri);
Logger.LogDebug(Resources.OIDCH_0031_Using_Options_RedirectUri, Options.RedirectUri);
}
// When redeeming a 'code' for an AccessToken, this value is needed
@ -203,7 +190,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
if (!Options.NonceCache.TryAddNonce(message.Nonce))
{
_logger.LogError(Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce);
Logger.LogError(Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce);
throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce));
}
}
@ -221,19 +208,19 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
await Options.Notifications.RedirectToIdentityProvider(redirectToIdentityProviderNotification);
if (redirectToIdentityProviderNotification.HandledResponse)
{
_logger.LogInformation(Resources.OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse);
Logger.LogInformation(Resources.OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse);
return;
}
else if (redirectToIdentityProviderNotification.Skipped)
{
_logger.LogInformation(Resources.OIDCH_0035_RedirectToIdentityProviderNotificationSkipped);
Logger.LogInformation(Resources.OIDCH_0035_RedirectToIdentityProviderNotificationSkipped);
return;
}
string redirectUri = redirectToIdentityProviderNotification.ProtocolMessage.CreateAuthenticationRequestUrl();
var redirectUri = redirectToIdentityProviderNotification.ProtocolMessage.CreateAuthenticationRequestUrl();
if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
{
_logger.LogWarning(Resources.OIDCH_0036_UriIsNotWellFormed, redirectUri);
Logger.LogWarning(Resources.OIDCH_0036_UriIsNotWellFormed, redirectUri);
}
Response.Redirect(redirectUri);
@ -251,10 +238,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <remarks>Uses log id's OIDCH-0000 - OIDCH-0025</remarks>
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
{
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug(Resources.OIDCH_0000_AuthenticateCoreAsync, this.GetType());
}
Logger.LogDebug(Resources.OIDCH_0000_AuthenticateCoreAsync, this.GetType());
// Allow login to be constrained to a specific path. Need to make this runtime configurable.
if (Options.CallbackPath.HasValue && Options.CallbackPath != (Request.PathBase + Request.Path))
@ -271,7 +255,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
&& Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase)
&& Request.Body.CanRead)
{
IFormCollection form = await Request.ReadFormAsync();
var form = await Request.ReadFormAsync();
Request.Body.Seek(0, SeekOrigin.Begin);
message = new OpenIdConnectMessage(form);
}
@ -283,9 +267,9 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
try
{
if (_logger.IsEnabled(LogLevel.Debug))
if (Logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug(Resources.OIDCH_0001_MessageReceived, message.BuildRedirectUrl());
Logger.LogDebug(Resources.OIDCH_0001_MessageReceived, message.BuildRedirectUrl());
}
var messageReceivedNotification =
@ -297,34 +281,34 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
await Options.Notifications.MessageReceived(messageReceivedNotification);
if (messageReceivedNotification.HandledResponse)
{
_logger.LogInformation(Resources.OIDCH_0002_MessageReceivedNotificationHandledResponse);
Logger.LogInformation(Resources.OIDCH_0002_MessageReceivedNotificationHandledResponse);
return messageReceivedNotification.AuthenticationTicket;
}
if (messageReceivedNotification.Skipped)
{
_logger.LogInformation(Resources.OIDCH_0003_MessageReceivedNotificationSkipped);
Logger.LogInformation(Resources.OIDCH_0003_MessageReceivedNotificationSkipped);
return null;
}
// runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we should process.
if (string.IsNullOrWhiteSpace(message.State))
{
_logger.LogError(Resources.OIDCH_0004_MessageStateIsNullOrWhiteSpace);
Logger.LogError(Resources.OIDCH_0004_MessageStateIsNullOrWhiteSpace);
return null;
}
var properties = GetPropertiesFromState(message.State);
if (properties == null)
{
_logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid);
Logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid);
return null;
}
// devs will need to hook AuthenticationFailedNotification to avoid having 'raw' runtime errors displayed to users.
if (!string.IsNullOrWhiteSpace(message.Error))
{
_logger.LogError(Resources.OIDCH_0006_MessageErrorNotNull, message.Error);
Logger.LogError(Resources.OIDCH_0006_MessageErrorNotNull, message.Error);
throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0006_MessageErrorNotNull, message.Error));
}
@ -333,14 +317,14 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
if (_configuration == null && Options.ConfigurationManager != null)
{
_logger.LogDebug(Resources.OIDCH_0007_UpdatingConfiguration);
Logger.LogDebug(Resources.OIDCH_0007_UpdatingConfiguration);
_configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);
}
// OpenIdConnect protocol allows a Code to be received without the id_token
if (!string.IsNullOrWhiteSpace(message.IdToken))
{
_logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken);
Logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken);
var securityTokenReceivedNotification =
new SecurityTokenReceivedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options)
{
@ -350,18 +334,18 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification);
if (securityTokenReceivedNotification.HandledResponse)
{
_logger.LogInformation(Resources.OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse);
Logger.LogInformation(Resources.OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse);
return securityTokenReceivedNotification.AuthenticationTicket;
}
if (securityTokenReceivedNotification.Skipped)
{
_logger.LogInformation(Resources.OIDCH_0009_SecurityTokenReceivedNotificationSkipped);
Logger.LogInformation(Resources.OIDCH_0009_SecurityTokenReceivedNotificationSkipped);
return null;
}
// Copy and augment to avoid cross request race conditions for updated configurations.
TokenValidationParameters validationParameters = Options.TokenValidationParameters.Clone();
var validationParameters = Options.TokenValidationParameters.Clone();
if (_configuration != null)
{
if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer))
@ -386,7 +370,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
jwt = validatedToken as JwtSecurityToken;
if (jwt == null)
{
_logger.LogError(Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType());
Logger.LogError(Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType());
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType()));
}
}
@ -394,7 +378,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
if (validatedToken == null)
{
_logger.LogError(Resources.OIDCH_0011_UnableToValidateToken, message.IdToken);
Logger.LogError(Resources.OIDCH_0011_UnableToValidateToken, message.IdToken);
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0011_UnableToValidateToken, message.IdToken));
}
@ -412,13 +396,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
// Rename?
if (Options.UseTokenLifetime)
{
DateTime issued = validatedToken.ValidFrom;
var issued = validatedToken.ValidFrom;
if (issued != DateTime.MinValue)
{
ticket.Properties.IssuedUtc = issued;
}
DateTime expires = validatedToken.ValidTo;
var expires = validatedToken.ValidTo;
if (expires != DateTime.MinValue)
{
ticket.Properties.ExpiresUtc = expires;
@ -435,13 +419,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification);
if (securityTokenValidatedNotification.HandledResponse)
{
_logger.LogInformation(Resources.OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse);
Logger.LogInformation(Resources.OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse);
return securityTokenValidatedNotification.AuthenticationTicket;
}
if (securityTokenValidatedNotification.Skipped)
{
_logger.LogInformation(Resources.OIDCH_0013_SecurityTokenValidatedNotificationSkipped);
Logger.LogInformation(Resources.OIDCH_0013_SecurityTokenValidatedNotificationSkipped);
return null;
}
@ -470,7 +454,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
if (message.Code != null)
{
_logger.LogDebug(Resources.OIDCH_0014_CodeReceived, message.Code);
Logger.LogDebug(Resources.OIDCH_0014_CodeReceived, message.Code);
if (ticket == null)
{
ticket = new AuthenticationTicket(properties, Options.AuthenticationScheme);
@ -489,13 +473,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification);
if (authorizationCodeReceivedNotification.HandledResponse)
{
_logger.LogInformation(Resources.OIDCH_0015_CodeReceivedNotificationHandledResponse);
Logger.LogInformation(Resources.OIDCH_0015_CodeReceivedNotificationHandledResponse);
return authorizationCodeReceivedNotification.AuthenticationTicket;
}
if (authorizationCodeReceivedNotification.Skipped)
{
_logger.LogInformation(Resources.OIDCH_0016_CodeReceivedNotificationSkipped);
Logger.LogInformation(Resources.OIDCH_0016_CodeReceivedNotificationSkipped);
return null;
}
}
@ -504,7 +488,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
}
catch (Exception exception)
{
_logger.LogError(Resources.OIDCH_0017_ExceptionOccurredWhileProcessingMessage, exception);
Logger.LogError(Resources.OIDCH_0017_ExceptionOccurredWhileProcessingMessage, exception);
// Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification.
if (Options.RefreshOnIssuerKeyNotFound && exception.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException)))
@ -522,13 +506,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
await Options.Notifications.AuthenticationFailed(authenticationFailedNotification);
if (authenticationFailedNotification.HandledResponse)
{
_logger.LogInformation(Resources.OIDCH_0018_AuthenticationFailedNotificationHandledResponse);
Logger.LogInformation(Resources.OIDCH_0018_AuthenticationFailedNotificationHandledResponse);
return authenticationFailedNotification.AuthenticationTicket;
}
if (authenticationFailedNotification.Skipped)
{
_logger.LogInformation(Resources.OIDCH_0019_AuthenticationFailedNotificationSkipped);
Logger.LogInformation(Resources.OIDCH_0019_AuthenticationFailedNotificationSkipped);
return null;
}
@ -579,7 +563,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
try
{
string nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length));
var nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length));
if (nonceDecodedValue == nonce)
{
var cookieOptions = new CookieOptions
@ -594,7 +578,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
}
catch (Exception ex)
{
_logger.LogWarning("Failed to un-protect the nonce cookie.", ex);
Logger.LogWarning("Failed to un-protect the nonce cookie.", ex);
}
}
}
@ -605,13 +589,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
private AuthenticationProperties GetPropertiesFromState(string state)
{
// assume a well formed query string: <a=b&>OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey=kasjd;fljasldkjflksdj<&c=d>
int startIndex = 0;
var startIndex = 0;
if (string.IsNullOrWhiteSpace(state) || (startIndex = state.IndexOf(OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey, StringComparison.Ordinal)) == -1)
{
return null;
}
int authenticationIndex = startIndex + OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey.Length;
var authenticationIndex = startIndex + OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey.Length;
if (authenticationIndex == -1 || authenticationIndex == state.Length || state[authenticationIndex] != '=')
{
return null;
@ -619,7 +603,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
// scan rest of string looking for '&'
authenticationIndex++;
int endIndex = state.Substring(authenticationIndex, state.Length - authenticationIndex).IndexOf("&", StringComparison.Ordinal);
var endIndex = state.Substring(authenticationIndex, state.Length - authenticationIndex).IndexOf("&", StringComparison.Ordinal);
// -1 => no other parameters are after the AuthenticationPropertiesKey
if (endIndex == -1)
@ -643,8 +627,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
private async Task<bool> InvokeReplyPathAsync()
{
AuthenticationTicket ticket = await AuthenticateAsync();
var ticket = await AuthenticateAsync();
if (ticket != null)
{
if (ticket.Principal != null)

View File

@ -25,8 +25,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// </summary>
public class OpenIdConnectAuthenticationMiddleware : AuthenticationMiddleware<OpenIdConnectAuthenticationOptions>
{
private readonly ILogger _logger;
/// <summary>
/// Initializes a <see cref="OpenIdConnectAuthenticationMiddleware"/>
/// </summary>
@ -45,9 +43,8 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<OpenIdConnectAuthenticationOptions> options,
ConfigureOptions<OpenIdConnectAuthenticationOptions> configureOptions = null)
: base(next, options, configureOptions)
: base(next, options, loggerFactory, configureOptions)
{
_logger = loggerFactory.CreateLogger<OpenIdConnectAuthenticationMiddleware>();
if (string.IsNullOrEmpty(Options.SignInScheme) && !string.IsNullOrEmpty(externalOptions.Options.SignInScheme))
{
Options.SignInScheme = externalOptions.Options.SignInScheme;
@ -120,7 +117,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
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
Options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(Options.MetadataAddress, httpClient);
@ -134,13 +131,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <returns>An <see cref="AuthenticationHandler"/> configured with the <see cref="OpenIdConnectAuthenticationOptions"/> supplied to the constructor.</returns>
protected override AuthenticationHandler<OpenIdConnectAuthenticationOptions> CreateHandler()
{
return new OpenIdConnectAuthenticationHandler(_logger);
return new OpenIdConnectAuthenticationHandler();
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")]
private static HttpMessageHandler ResolveHttpMessageHandler(OpenIdConnectAuthenticationOptions options)
{
HttpMessageHandler handler = options.BackchannelHttpHandler ??
var handler = options.BackchannelHttpHandler ??
#if DNX451
new WebRequestHandler();
// If they provided a validator, apply it or fail.

View File

@ -38,7 +38,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <remarks>
/// Defaults:
/// <para>AddNonceToRequest: true.</para>
/// <para>AuthenticationMode: <see cref="AuthenticationMode.Active"/>.</para>
/// <para>BackchannelTimeout: 1 minute.</para>
/// <para>Caption: <see cref="OpenIdConnectAuthenticationDefaults.Caption"/>.</para>
/// <para>ProtocolValidator: new <see cref="OpenIdConnectProtocolValidator"/>.</para>

View File

@ -12,7 +12,6 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Collections;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Authentication.Twitter.Messages;
using Microsoft.AspNet.WebUtilities;
using Microsoft.Framework.Logging;
@ -28,12 +27,10 @@ namespace Microsoft.AspNet.Authentication.Twitter
private const string AccessTokenEndpoint = "https://api.twitter.com/oauth/access_token";
private readonly HttpClient _httpClient;
private readonly ILogger _logger;
public TwitterAuthenticationHandler(HttpClient httpClient, ILogger logger)
public TwitterAuthenticationHandler(HttpClient httpClient)
{
_httpClient = httpClient;
_logger = logger;
}
public override async Task<bool> InvokeAsync()
@ -55,40 +52,40 @@ namespace Microsoft.AspNet.Authentication.Twitter
AuthenticationProperties properties = null;
try
{
IReadableStringCollection query = Request.Query;
string protectedRequestToken = Request.Cookies[StateCookie];
var query = Request.Query;
var protectedRequestToken = Request.Cookies[StateCookie];
RequestToken requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken);
var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken);
if (requestToken == null)
{
_logger.LogWarning("Invalid state");
Logger.LogWarning("Invalid state");
return null;
}
properties = requestToken.Properties;
string returnedToken = query.Get("oauth_token");
var returnedToken = query.Get("oauth_token");
if (string.IsNullOrWhiteSpace(returnedToken))
{
_logger.LogWarning("Missing oauth_token");
Logger.LogWarning("Missing oauth_token");
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
}
if (returnedToken != requestToken.Token)
{
_logger.LogWarning("Unmatched token");
Logger.LogWarning("Unmatched token");
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
}
string oauthVerifier = query.Get("oauth_verifier");
if (string.IsNullOrWhiteSpace(oauthVerifier))
{
_logger.LogWarning("Missing or blank oauth_verifier");
Logger.LogWarning("Missing or blank oauth_verifier");
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
}
AccessToken accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier);
var accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier);
var context = new TwitterAuthenticatedContext(Context, accessToken.UserId, accessToken.ScreenName, accessToken.Token, accessToken.TokenSecret);
@ -120,7 +117,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
}
catch (Exception ex)
{
_logger.LogError("Authentication failed", ex);
Logger.LogError("Authentication failed", ex);
return new AuthenticationTicket(properties, Options.AuthenticationScheme);
}
}
@ -148,8 +145,8 @@ namespace Microsoft.AspNet.Authentication.Twitter
return;
}
string requestPrefix = Request.Scheme + "://" + Request.Host;
string callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath;
var requestPrefix = Request.Scheme + "://" + Request.Host;
var callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath;
AuthenticationProperties properties;
if (ChallengeContext == null)
@ -165,11 +162,11 @@ namespace Microsoft.AspNet.Authentication.Twitter
properties.RedirectUri = requestPrefix + Request.PathBase + Request.Path + Request.QueryString;
}
RequestToken requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, callBackUrl, properties);
var requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, callBackUrl, properties);
if (requestToken.CallbackConfirmed)
{
string twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token;
var twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token;
var cookieOptions = new CookieOptions
{
@ -186,16 +183,16 @@ namespace Microsoft.AspNet.Authentication.Twitter
}
else
{
_logger.LogError("requestToken CallbackConfirmed!=true");
Logger.LogError("requestToken CallbackConfirmed!=true");
}
}
public async Task<bool> InvokeReturnPathAsync()
{
AuthenticationTicket model = await AuthenticateAsync();
var model = await AuthenticateAsync();
if (model == null)
{
_logger.LogWarning("Invalid return state, unable to redirect.");
Logger.LogWarning("Invalid return state, unable to redirect.");
Response.StatusCode = 500;
return true;
}
@ -230,9 +227,9 @@ namespace Microsoft.AspNet.Authentication.Twitter
private async Task<RequestToken> ObtainRequestTokenAsync(string consumerKey, string consumerSecret, string callBackUri, AuthenticationProperties properties)
{
_logger.LogVerbose("ObtainRequestToken");
Logger.LogVerbose("ObtainRequestToken");
string nonce = Guid.NewGuid().ToString("N");
var nonce = Guid.NewGuid().ToString("N");
var authorizationParts = new SortedDictionary<string, string>
{
@ -250,7 +247,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value));
}
parameterBuilder.Length--;
string parameterString = parameterBuilder.ToString();
var parameterString = parameterBuilder.ToString();
var canonicalizedRequestBuilder = new StringBuilder();
canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
@ -259,7 +256,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString));
string signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString());
var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString());
authorizationParts.Add("oauth_signature", signature);
var authorizationHeaderBuilder = new StringBuilder();
@ -274,11 +271,11 @@ namespace Microsoft.AspNet.Authentication.Twitter
var request = new HttpRequestMessage(HttpMethod.Post, RequestTokenEndpoint);
request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString());
HttpResponseMessage response = await _httpClient.SendAsync(request, Context.RequestAborted);
var response = await _httpClient.SendAsync(request, Context.RequestAborted);
response.EnsureSuccessStatusCode();
string responseText = await response.Content.ReadAsStringAsync();
IFormCollection responseParameters = new FormCollection(FormReader.ReadForm(responseText));
var responseParameters = new FormCollection(FormReader.ReadForm(responseText));
if (string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.Ordinal))
{
return new RequestToken { Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Properties = properties };
@ -291,9 +288,9 @@ namespace Microsoft.AspNet.Authentication.Twitter
{
// https://dev.twitter.com/docs/api/1/post/oauth/access_token
_logger.LogVerbose("ObtainAccessToken");
Logger.LogVerbose("ObtainAccessToken");
string nonce = Guid.NewGuid().ToString("N");
var nonce = Guid.NewGuid().ToString("N");
var authorizationParts = new SortedDictionary<string, string>
{
@ -312,7 +309,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value));
}
parameterBuilder.Length--;
string parameterString = parameterBuilder.ToString();
var parameterString = parameterBuilder.ToString();
var canonicalizedRequestBuilder = new StringBuilder();
canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
@ -321,7 +318,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
canonicalizedRequestBuilder.Append("&");
canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString));
string signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString());
var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString());
authorizationParts.Add("oauth_signature", signature);
authorizationParts.Remove("oauth_verifier");
@ -344,17 +341,16 @@ namespace Microsoft.AspNet.Authentication.Twitter
request.Content = new FormUrlEncodedContent(formPairs);
HttpResponseMessage response = await _httpClient.SendAsync(request, Context.RequestAborted);
var response = await _httpClient.SendAsync(request, Context.RequestAborted);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("AccessToken request failed with a status code of " + response.StatusCode);
Logger.LogError("AccessToken request failed with a status code of " + response.StatusCode);
response.EnsureSuccessStatusCode(); // throw
}
string responseText = await response.Content.ReadAsStringAsync();
IFormCollection responseParameters = new FormCollection(FormReader.ReadForm(responseText));
var responseText = await response.Content.ReadAsStringAsync();
var responseParameters = new FormCollection(FormReader.ReadForm(responseText));
return new AccessToken
{
@ -367,7 +363,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
private static string GenerateTimeStamp()
{
TimeSpan secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch;
var secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch;
return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture);
}
@ -380,7 +376,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
"{0}&{1}",
Uri.EscapeDataString(consumerSecret),
string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret)));
byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData));
var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData));
return Convert.ToBase64String(hash);
}
}
@ -390,4 +386,4 @@ namespace Microsoft.AspNet.Authentication.Twitter
// N/A - No SignIn or SignOut support.
}
}
}
}

View File

@ -22,7 +22,6 @@ namespace Microsoft.AspNet.Authentication.Twitter
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")]
public class TwitterAuthenticationMiddleware : AuthenticationMiddleware<TwitterAuthenticationOptions>
{
private readonly ILogger _logger;
private readonly HttpClient _httpClient;
/// <summary>
@ -40,7 +39,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
[NotNull] IOptions<ExternalAuthenticationOptions> externalOptions,
[NotNull] IOptions<TwitterAuthenticationOptions> options,
ConfigureOptions<TwitterAuthenticationOptions> configureOptions = null)
: base(next, options, configureOptions)
: base(next, options, loggerFactory, configureOptions)
{
if (string.IsNullOrWhiteSpace(Options.ConsumerSecret))
{
@ -51,8 +50,6 @@ namespace Microsoft.AspNet.Authentication.Twitter
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerKey"));
}
_logger = loggerFactory.CreateLogger(typeof(TwitterAuthenticationMiddleware).FullName);
if (Options.Notifications == null)
{
Options.Notifications = new TwitterAuthenticationNotifications();
@ -90,7 +87,7 @@ namespace Microsoft.AspNet.Authentication.Twitter
/// <returns>An <see cref="AuthenticationHandler"/> configured with the <see cref="TwitterAuthenticationOptions"/> supplied to the constructor.</returns>
protected override AuthenticationHandler<TwitterAuthenticationOptions> CreateHandler()
{
return new TwitterAuthenticationHandler(_httpClient, _logger);
return new TwitterAuthenticationHandler(_httpClient);
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")]

View File

@ -2,8 +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.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
@ -50,6 +48,8 @@ namespace Microsoft.AspNet.Authentication
protected PathString RequestPathBase { get; private set; }
protected ILogger Logger { get; private set; }
internal AuthenticationOptions BaseOptions
{
get { return _baseOptions; }
@ -61,11 +61,12 @@ namespace Microsoft.AspNet.Authentication
public bool Faulted { get; set; }
protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpContext context)
protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger)
{
_baseOptions = options;
Context = context;
RequestPathBase = Request.PathBase;
Logger = logger;
RegisterAuthenticationHandler();
@ -414,13 +415,13 @@ namespace Microsoft.AspNet.Authentication
Response.Cookies.Append(correlationKey, correlationId, cookieOptions);
}
protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties, [NotNull] ILogger logger)
protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties)
{
var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme;
var correlationCookie = Request.Cookies[correlationKey];
if (string.IsNullOrWhiteSpace(correlationCookie))
{
logger.LogWarning("{0} cookie not found.", correlationKey);
Logger.LogWarning("{0} cookie not found.", correlationKey);
return false;
}
@ -436,7 +437,7 @@ namespace Microsoft.AspNet.Authentication
correlationKey,
out correlationExtra))
{
logger.LogWarning("{0} state property not found.", correlationKey);
Logger.LogWarning("{0} state property not found.", correlationKey);
return false;
}
@ -444,7 +445,7 @@ namespace Microsoft.AspNet.Authentication
if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal))
{
logger.LogWarning("{0} correlation cookie and state property mismatch.", correlationKey);
Logger.LogWarning("{0} correlation cookie and state property mismatch.", correlationKey);
return false;
}
@ -464,5 +465,4 @@ namespace Microsoft.AspNet.Authentication
auth.Handler = PriorHandler;
}
}
}
}

View File

@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Logging;
namespace Microsoft.AspNet.Authentication
{
@ -19,11 +20,12 @@ namespace Microsoft.AspNet.Authentication
/// </summary>
/// <param name="options">The original options passed by the application control behavior</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>
/// <returns>async completion</returns>
public Task Initialize(TOptions options, HttpContext context)
public Task Initialize(TOptions options, HttpContext context, ILogger logger)
{
Options = options;
return BaseInitializeAsync(options, context);
return BaseInitializeAsync(options, context, logger);
}
}
}

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Authentication
@ -17,6 +18,7 @@ namespace Microsoft.AspNet.Authentication
protected AuthenticationMiddleware(
[NotNull] RequestDelegate next,
[NotNull] IOptions<TOptions> options,
[NotNull] ILoggerFactory loggerFactory,
ConfigureOptions<TOptions> configureOptions)
{
if (configureOptions != null)
@ -28,6 +30,8 @@ namespace Microsoft.AspNet.Authentication
{
Options = options.Options;
}
Logger = loggerFactory.CreateLogger(this.GetType().FullName);
_next = next;
}
@ -35,10 +39,12 @@ namespace Microsoft.AspNet.Authentication
public TOptions Options { get; set; }
public ILogger Logger { get; set; }
public async Task Invoke(HttpContext context)
{
AuthenticationHandler<TOptions> handler = CreateHandler();
await handler.Initialize(Options, context);
var handler = CreateHandler();
await handler.Initialize(Options, context, Logger);
try
{
if (!await handler.InvokeAsync())

View File

@ -75,4 +75,4 @@ namespace Microsoft.AspNet.Authorization
return any ? policyBuilder.Build() : null;
}
}
}
}

View File

@ -3,6 +3,7 @@
using System;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Logging;
using Xunit;
namespace Microsoft.AspNet.Authentication
@ -13,12 +14,10 @@ namespace Microsoft.AspNet.Authentication
public void ShouldHandleSchemeAreDeterminedOnlyByMatchingAuthenticationScheme()
{
var handler = new TestHandler("Alpha");
bool passiveNoMatch = handler.ShouldHandleScheme("Beta");
var passiveNoMatch = handler.ShouldHandleScheme("Beta");
handler = new TestHandler("Alpha");
bool passiveWithMatch = handler.ShouldHandleScheme("Alpha");
var passiveWithMatch = handler.ShouldHandleScheme("Alpha");
Assert.False(passiveNoMatch);
Assert.True(passiveWithMatch);
@ -56,7 +55,7 @@ namespace Microsoft.AspNet.Authentication
{
public TestHandler(string scheme)
{
Initialize(new TestOptions(), new DefaultHttpContext());
Initialize(new TestOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"));
Options.AuthenticationScheme = scheme;
}
@ -90,7 +89,7 @@ namespace Microsoft.AspNet.Authentication
{
public TestAutoHandler(string scheme, bool auto)
{
Initialize(new TestAutoOptions(), new DefaultHttpContext());
Initialize(new TestAutoOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"));
Options.AuthenticationScheme = scheme;
Options.AutomaticAuthentication = auto;
}

View File

@ -226,6 +226,8 @@ namespace Microsoft.AspNet.Authentication.Google
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
}
[Fact]
public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState()
{

View File

@ -565,14 +565,9 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
/// </summary>
public class CustomOpenIdConnectAuthenticationHandler : OpenIdConnectAuthenticationHandler
{
public CustomOpenIdConnectAuthenticationHandler(ILogger logger)
: base(logger)
public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context, ILogger logger)
{
}
public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context)
{
await base.BaseInitializeAsync(options, context);
await base.BaseInitializeAsync(options, context, logger);
}
public override bool ShouldHandleScheme(string authenticationScheme)
@ -619,13 +614,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
protected override AuthenticationHandler<OpenIdConnectAuthenticationOptions> CreateHandler()
{
return new CustomOpenIdConnectAuthenticationHandler(Logger);
}
public ILogger Logger
{
get;
set;
return new CustomOpenIdConnectAuthenticationHandler();
}
}

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>