diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index 982c0c8f5f..2d3d1caf5f 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -21,7 +21,7 @@ 2.0 - 50113 + 12345 \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 35480c1cc3..18f17ac0f7 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -28,7 +28,6 @@ namespace CookieSample { services.ConfigureOptions(options => { - options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; }); }); diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 84bb6d1c95..40f05e17c5 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -7,6 +7,7 @@ "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*" diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs new file mode 100644 index 0000000000..0957d9fd61 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs @@ -0,0 +1,114 @@ +// 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 Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingContext : BaseContext + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingContext( + HttpContext context, + TOptions options) + : base(context, options) + { + } + + /// + /// True if application code has called any of the Validate methods on this context. + /// + public bool IsValidated { get; private set; } + + /// + /// True if application code has called any of the SetError methods on this context. + /// + public bool HasError { get; private set; } + + /// + /// The error argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error" parameter. + /// + public string Error { get; private set; } + + /// + /// The optional errorDescription argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error_description" parameter. + /// + public string ErrorDescription { get; private set; } + + /// + /// The optional errorUri argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error_uri" parameter. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "error_uri is a string value in the protocol")] + public string ErrorUri { get; private set; } + + /// + /// Marks this context as validated by the application. IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// True if the validation has taken effect. + public virtual bool Validated() + { + IsValidated = true; + HasError = false; + return true; + } + + /// + /// Marks this context as not validated by the application. IsValidated and HasError become false as a result of calling. + /// + public virtual void Rejected() + { + IsValidated = false; + HasError = false; + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + public void SetError(string error) + { + SetError(error, null); + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + /// Assigned to the ErrorDescription property + public void SetError(string error, + string errorDescription) + { + SetError(error, errorDescription, null); + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + /// Assigned to the ErrorDescription property + /// Assigned to the ErrorUri property + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "error_uri is a string value in the protocol")] + public void SetError(string error, + string errorDescription, + string errorUri) + { + Error = error; + ErrorDescription = errorDescription; + ErrorUri = errorUri; + Rejected(); + HasError = true; + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs new file mode 100644 index 0000000000..c6528619bc --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs @@ -0,0 +1,58 @@ +// 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.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingTicketContext : BaseValidatingContext + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingTicketContext( + HttpContext context, + TOptions options, + AuthenticationTicket ticket) + : base(context, options) + { + Ticket = ticket; + } + + /// + /// Contains the identity and properties for the application to authenticate. If the Validated method + /// is invoked with an AuthenticationTicket or ClaimsIdentity argument, that new value is assigned to + /// this property in addition to changing IsValidated to true. + /// + public AuthenticationTicket Ticket { get; private set; } + + /// + /// Replaces the ticket information on this context and marks it as as validated by the application. + /// IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// Assigned to the Ticket property + /// True if the validation has taken effect. + public bool Validated(AuthenticationTicket ticket) + { + Ticket = ticket; + return Validated(); + } + + /// + /// Alters the ticket information on this context and marks it as as validated by the application. + /// IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// Assigned to the Ticket.Identity property + /// True if the validation has taken effect. + public bool Validated(ClaimsIdentity identity) + { + AuthenticationProperties properties = Ticket != null ? Ticket.Properties : new AuthenticationProperties(); + return Validated(new AuthenticationTicket(identity, properties)); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs new file mode 100644 index 0000000000..048d8f2927 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs @@ -0,0 +1,37 @@ +// 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.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// + public interface IOAuthBearerAuthenticationNotifications + { + /// + /// Invoked before the is created. Gives the application an + /// opportunity to find the identity from a different location, adjust, or reject the token. + /// + /// Contains the token string. + /// A representing the completed operation. + Task RequestToken(OAuthRequestTokenContext context); + + /// + /// Called each time a request identity has been validated by the middleware. By implementing this method the + /// application may alter or reject the identity which has arrived with the request. + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + Task ValidateIdentity(OAuthValidateIdentityContext context); + + /// + /// Called each time a challenge is being sent to the client. By implementing this method the application + /// may modify the challenge as needed. + /// + /// Contains the default challenge. + /// A representing the completed operation. + Task ApplyChallenge(OAuthChallengeContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs index a651767e8e..5817071536 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs @@ -3,7 +3,6 @@ using System; using System.Globalization; -using System.Net.Http; using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs new file mode 100644 index 0000000000..2c24f3ff1f --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs @@ -0,0 +1,73 @@ +// 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.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// OAuth bearer token middleware provider + /// + public class OAuthBearerAuthenticationNotifications : IOAuthBearerAuthenticationNotifications + { + /// + /// Initializes a new instance of the class + /// + public OAuthBearerAuthenticationNotifications() + { + OnRequestToken = context => Task.FromResult(null); + OnValidateIdentity = context => Task.FromResult(null); + OnApplyChallenge = context => + { + context.HttpContext.Response.Headers.AppendValues("WWW-Authenticate", context.Challenge); + return Task.FromResult(0); + }; + } + + /// + /// Handles processing OAuth bearer token. + /// + public Func OnRequestToken { get; set; } + + /// + /// Handles validating the identity produced from an OAuth bearer token. + /// + public Func OnValidateIdentity { get; set; } + + /// + /// Handles applying the authentication challenge to the response message. + /// + public Func OnApplyChallenge { get; set; } + + /// + /// Handles processing OAuth bearer token. + /// + /// + /// + public virtual Task RequestToken(OAuthRequestTokenContext context) + { + return OnRequestToken(context); + } + + /// + /// Handles validating the identity produced from an OAuth bearer token. + /// + /// + /// + public virtual Task ValidateIdentity(OAuthValidateIdentityContext context) + { + return OnValidateIdentity.Invoke(context); + } + + /// + /// Handles applying the authentication challenge to the response message. + /// + /// + /// + public Task ApplyChallenge(OAuthChallengeContext context) + { + return OnApplyChallenge(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs new file mode 100644 index 0000000000..6f50169143 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs @@ -0,0 +1,32 @@ +// 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 Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies the HTTP response header for the bearer authentication scheme. + /// + public class OAuthChallengeContext : BaseContext + { + /// + /// Initializes a new + /// + /// HTTP environment + /// The www-authenticate header value. + public OAuthChallengeContext( + HttpContext context, + string challenge) + : base(context) + { + Challenge = challenge; + } + + /// + /// The www-authenticate header value. + /// + public string Challenge { get; protected set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs index 5886d1b546..15d76c6eb3 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs @@ -8,7 +8,6 @@ using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Notifications; -using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.OAuth { diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs new file mode 100644 index 0000000000..785fa175d8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs @@ -0,0 +1,32 @@ +// 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 Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies the HTTP request header for the bearer authentication scheme. + /// + public class OAuthRequestTokenContext : BaseContext + { + /// + /// Initializes a new + /// + /// HTTP environment + /// The authorization header value. + public OAuthRequestTokenContext( + HttpContext context, + string token) + : base(context) + { + Token = token; + } + + /// + /// The authorization header value + /// + public string Token { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs new file mode 100644 index 0000000000..5dc04ffb40 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs @@ -0,0 +1,26 @@ +// 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 Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Contains the authentication ticket data from an OAuth bearer token. + /// + public class OAuthValidateIdentityContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + public OAuthValidateIdentityContext( + HttpContext context, + OAuthBearerAuthenticationOptions options, + AuthenticationTicket ticket) : base(context, options, ticket) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs new file mode 100644 index 0000000000..70f1f1e616 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs @@ -0,0 +1,17 @@ +// 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. + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Default values used by authorization server and bearer authentication. + /// + public static class OAuthBearerAuthenticationDefaults + { + /// + /// Default value for AuthenticationType property in the OAuthBearerAuthenticationOptions and + /// OAuthAuthorizationServerOptions. + /// + public const string AuthenticationType = "Bearer"; + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs new file mode 100644 index 0000000000..118598120e --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs @@ -0,0 +1,41 @@ +// 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.Security.OAuth; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods to add OAuth Bearer authentication capabilities to an HTTP application pipeline + /// + public static class OAuthBearerAuthenticationExtensions + { + public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.ConfigureOptions(configure); + } + + /// + /// Adds Bearer token processing to an HTTP application pipeline. This middleware understands appropriately + /// formatted and secured tokens which appear in the request header. If the Options.AuthenticationMode is Active, the + /// claims within the bearer token are added to the current request's IPrincipal User. If the Options.AuthenticationMode + /// is Passive, then the current request is not modified, but IAuthenticationManager AuthenticateAsync may be used at + /// any time to obtain the claims from the request's bearer token. + /// See also http://tools.ietf.org/html/rfc6749 + /// + /// The application builder + /// Options which control the processing of the bearer header. + /// The application builder + public static IApplicationBuilder UseOAuthBearerAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") + { + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs new file mode 100644 index 0000000000..b49db1f715 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs @@ -0,0 +1,126 @@ +// 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.Threading.Tasks; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.OAuth +{ + internal class OAuthBearerAuthenticationHandler : AuthenticationHandler + { + private readonly ILogger _logger; + private readonly string _challenge; + + public OAuthBearerAuthenticationHandler(ILogger logger, string challenge) + { + _logger = logger; + _challenge = challenge; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + try + { + // Find token in default location + string requestToken = null; + string authorization = Request.Headers.Get("Authorization"); + if (!string.IsNullOrEmpty(authorization)) + { + if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + requestToken = authorization.Substring("Bearer ".Length).Trim(); + } + } + + // Give application opportunity to find from a different location, adjust, or reject token + var requestTokenContext = new OAuthRequestTokenContext(Context, requestToken); + await Options.Notifications.RequestToken(requestTokenContext); + + // If no token found, no further work possible + if (string.IsNullOrEmpty(requestTokenContext.Token)) + { + return null; + } + + // Call provider to process the token into data + var tokenReceiveContext = new AuthenticationTokenReceiveContext( + Context, + Options.AccessTokenFormat, + requestTokenContext.Token); + + await Options.AccessTokenProvider.ReceiveAsync(tokenReceiveContext); + if (tokenReceiveContext.Ticket == null) + { + tokenReceiveContext.DeserializeTicket(tokenReceiveContext.Token); + } + + AuthenticationTicket ticket = tokenReceiveContext.Ticket; + if (ticket == null) + { + _logger.WriteWarning("invalid bearer token received"); + return null; + } + + // Validate expiration time if present + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; + + if (ticket.Properties.ExpiresUtc.HasValue && + ticket.Properties.ExpiresUtc.Value < currentUtc) + { + _logger.WriteWarning("expired bearer token received"); + return null; + } + + // Give application final opportunity to override results + var context = new OAuthValidateIdentityContext(Context, Options, ticket); + if (ticket != null && + ticket.Identity != null && + ticket.Identity.IsAuthenticated) + { + // bearer token with identity starts validated + context.Validated(); + } + + await Options.Notifications.ValidateIdentity(context); + if (!context.IsValidated) + { + return null; + } + + // resulting identity values go back to caller + return context.Ticket; + } + catch (Exception ex) + { + _logger.WriteError("Authentication failed", ex); + return null; + } + } + + protected override void ApplyResponseChallenge() + { + if (Response.StatusCode != 401) + { + return; + } + + if (ChallengeContext != null) + { + OAuthChallengeContext challengeContext = new OAuthChallengeContext(Context, _challenge); + Options.Notifications.ApplyChallenge(challengeContext); + } + } + + protected override void ApplyResponseGrant() + { + // N/A + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs new file mode 100644 index 0000000000..715d43b13f --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs @@ -0,0 +1,79 @@ +// 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 Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Bearer authentication middleware component which is added to an HTTP pipeline. This class is not + /// created by application code directly, instead it is added by calling the the IAppBuilder UseOAuthBearerAuthentication + /// extension method. + /// + public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + + private readonly string _challenge; + + /// + /// Bearer authentication component which is added to an HTTP pipeline. This constructor is not + /// called by application code directly, instead it is added by calling the the IAppBuilder UseOAuthBearerAuthentication + /// extension method. + /// + public OAuthBearerAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + IOptionsAccessor options, + IOptionsAction configureOptions) + : base(next, options, configureOptions) + { + _logger = loggerFactory.Create(); + + if (!string.IsNullOrWhiteSpace(Options.Challenge)) + { + _challenge = Options.Challenge; + } + else if (string.IsNullOrWhiteSpace(Options.Realm)) + { + _challenge = "Bearer"; + } + else + { + _challenge = "Bearer realm=\"" + Options.Realm + "\""; + } + + if (Options.Notifications == null) + { + Options.Notifications = new OAuthBearerAuthenticationNotifications(); + } + + if (Options.AccessTokenFormat == null) + { + var dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + this.GetType().FullName, Options.AuthenticationType, "v1"); + Options.AccessTokenFormat = new TicketDataFormat(dataProtector); + } + + if (Options.AccessTokenProvider == null) + { + Options.AccessTokenProvider = new AuthenticationTokenProvider(); + } + } + + /// + /// Called by the AuthenticationMiddleware base class to create a per-request handler. + /// + /// A new instance of the request handler + protected override AuthenticationHandler CreateHandler() + { + return new OAuthBearerAuthenticationHandler(_logger, _challenge); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs new file mode 100644 index 0000000000..d2f9b9190b --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs @@ -0,0 +1,66 @@ +// 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 Microsoft.AspNet.Security.Infrastructure; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Options class provides information needed to control Bearer Authentication middleware behavior + /// + public class OAuthBearerAuthenticationOptions : AuthenticationOptions + { + /// + /// Creates an instance of bearer authentication options with default values. + /// + public OAuthBearerAuthenticationOptions() : base() + { + SystemClock = new SystemClock(); + AuthenticationType = OAuthBearerAuthenticationDefaults.AuthenticationType; + } + + /// + /// Determines what realm value is included when the bearer middleware adds a response header to an unauthorized request. + /// If not assigned, the response header does not have a realm. + /// + public string Realm { get; set; } + + /// + /// Specifies the full challenge to send to the client, and should start with "Bearer". If a challenge is provided then the + /// Realm property is ignored. If no challenge is specified then one is created using "Bearer" and the value of the Realm + /// property. + /// + public string Challenge { get; set; } + + /// + /// The object provided by the application to process events raised by the bearer authentication middleware. + /// The application may implement the interface fully, or it may create an instance of OAuthBearerAuthenticationProvider + /// and assign delegates only to the events it wants to process. + /// + public IOAuthBearerAuthenticationNotifications Notifications { get; set; } + + /// + /// The data format used to un-protect the information contained in the access token. + /// If not provided by the application the default data protection provider depends on the host server. + /// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted + /// servers will use DPAPI data protection. If a different access token + /// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider + /// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server. + /// + public ISecureDataFormat AccessTokenFormat { get; set; } + + /// + /// Receives the bearer token the client application will be providing to web application. If not provided the token + /// produced on the server's default data protection by using the AccessTokenFormat. If a different access token + /// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider + /// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server. + /// + public IAuthenticationTokenProvider AccessTokenProvider { get; set; } + + /// + /// Used to know what the current clock time is when calculating or validating token expiration. When not assigned default is based on + /// DateTimeOffset.UtcNow. This is typically needed only for unit testing. + /// + public ISystemClock SystemClock { get; set; } + } +}