Use DI activated options for auth middlewares
UseXXX() now use DI activated options Use ExternalAuthenticationOptions instead of DefaultSignInAs
This commit is contained in:
parent
23c024ef41
commit
3426034bcb
|
|
@ -9,9 +9,9 @@ namespace CookieSample
|
|||
{
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions()
|
||||
app.UseServices(services => { });
|
||||
app.UseCookieAuthentication(options =>
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
app.Run(async context =>
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ namespace CookieSessionSample
|
|||
{
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions()
|
||||
app.UseServices(services => { });
|
||||
app.UseCookieAuthentication(options =>
|
||||
{
|
||||
SessionStore = new MemoryCacheSessionStore(),
|
||||
options.SessionStore = new MemoryCacheSessionStore();
|
||||
});
|
||||
|
||||
app.Run(async context =>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>8c73d216-332d-41d8-bfd0-45bc4bc36552</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<OutputType>Web</OutputType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(OutputType) == 'Console'">
|
||||
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<DevelopmentServerPort>50113</DevelopmentServerPort>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -14,6 +14,7 @@ using Microsoft.AspNet.Security.MicrosoftAccount;
|
|||
using Microsoft.AspNet.Security.OAuth;
|
||||
using Microsoft.AspNet.Security.Twitter;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace CookieSample
|
||||
{
|
||||
|
|
@ -23,39 +24,48 @@ namespace CookieSample
|
|||
{
|
||||
app.UseErrorPage();
|
||||
|
||||
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
|
||||
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions()
|
||||
app.UseServices(services =>
|
||||
{
|
||||
LoginPath = new PathString("/login"),
|
||||
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
|
||||
{
|
||||
|
||||
options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType;
|
||||
});
|
||||
});
|
||||
|
||||
app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
|
||||
app.UseCookieAuthentication(options =>
|
||||
{
|
||||
options.LoginPath = new PathString("/login");
|
||||
});
|
||||
|
||||
app.UseFacebookAuthentication(options =>
|
||||
{
|
||||
AppId = "569522623154478",
|
||||
AppSecret = "a124463c4719c94b4228d9a240e5dc1a",
|
||||
options.AppId = "569522623154478";
|
||||
options.AppSecret = "a124463c4719c94b4228d9a240e5dc1a";
|
||||
});
|
||||
|
||||
app.UseOAuthAuthentication(new OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>("Google-AccessToken")
|
||||
app.UseOAuthAuthentication("Google-AccessToken", options =>
|
||||
{
|
||||
ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com",
|
||||
ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f",
|
||||
CallbackPath = new PathString("/signin-google-token"),
|
||||
AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint,
|
||||
TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint,
|
||||
Scope = { "openid", "profile", "email" },
|
||||
options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com";
|
||||
options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f";
|
||||
options.CallbackPath = new PathString("/signin-google-token");
|
||||
options.AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint;
|
||||
options.TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint;
|
||||
options.Scope.Add("openid");
|
||||
options.Scope.Add("profile");
|
||||
options.Scope.Add("email");
|
||||
});
|
||||
|
||||
app.UseGoogleAuthentication(new GoogleAuthenticationOptions()
|
||||
app.UseGoogleAuthentication(options =>
|
||||
{
|
||||
ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com",
|
||||
ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f",
|
||||
options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com";
|
||||
options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f";
|
||||
});
|
||||
|
||||
app.UseTwitterAuthentication(new TwitterAuthenticationOptions()
|
||||
app.UseTwitterAuthentication(options =>
|
||||
{
|
||||
ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g",
|
||||
ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI",
|
||||
options.ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g";
|
||||
options.ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI";
|
||||
});
|
||||
|
||||
/*
|
||||
|
|
@ -75,43 +85,43 @@ namespace CookieSample
|
|||
The sample app can then be run via:
|
||||
k web
|
||||
*/
|
||||
app.UseOAuthAuthentication(new OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>("Microsoft-AccessToken")
|
||||
app.UseOAuthAuthentication("Microsoft-AccessToken", options =>
|
||||
{
|
||||
Caption = "MicrosoftAccount-AccessToken - Requires project changes",
|
||||
ClientId = "00000000480FF62E",
|
||||
ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr",
|
||||
CallbackPath = new PathString("/signin-microsoft-token"),
|
||||
AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint,
|
||||
TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint,
|
||||
Scope = { "wl.basic" },
|
||||
options.Caption = "MicrosoftAccount-AccessToken - Requires project changes";
|
||||
options.ClientId = "00000000480FF62E";
|
||||
options.ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr";
|
||||
options.CallbackPath = new PathString("/signin-microsoft-token");
|
||||
options.AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint;
|
||||
options.TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint;
|
||||
options.Scope.Add("wl.basic");
|
||||
});
|
||||
|
||||
app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions()
|
||||
app.UseMicrosoftAccountAuthentication(options =>
|
||||
{
|
||||
Caption = "MicrosoftAccount - Requires project changes",
|
||||
ClientId = "00000000480FF62E",
|
||||
ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr",
|
||||
options.Caption = "MicrosoftAccount - Requires project changes";
|
||||
options.ClientId = "00000000480FF62E";
|
||||
options.ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr";
|
||||
});
|
||||
|
||||
app.UseOAuthAuthentication(new OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>("GitHub-AccessToken")
|
||||
app.UseOAuthAuthentication("GitHub-AccessToken", options =>
|
||||
{
|
||||
ClientId = "8c0c5a572abe8fe89588",
|
||||
ClientSecret = "e1d95eaf03461d27acd6f49d4fc7bf19d6ac8cda",
|
||||
CallbackPath = new PathString("/signin-github-token"),
|
||||
AuthorizationEndpoint = "https://github.com/login/oauth/authorize",
|
||||
TokenEndpoint = "https://github.com/login/oauth/access_token",
|
||||
options.ClientId = "8c0c5a572abe8fe89588";
|
||||
options.ClientSecret = "e1d95eaf03461d27acd6f49d4fc7bf19d6ac8cda";
|
||||
options.CallbackPath = new PathString("/signin-github-token");
|
||||
options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
|
||||
options.TokenEndpoint = "https://github.com/login/oauth/access_token";
|
||||
});
|
||||
|
||||
app.UseOAuthAuthentication(new OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>("GitHub")
|
||||
app.UseOAuthAuthentication("GitHub", options =>
|
||||
{
|
||||
ClientId = "49e302895d8b09ea5656",
|
||||
ClientSecret = "98f1bf028608901e9df91d64ee61536fe562064b",
|
||||
CallbackPath = new PathString("/signin-github"),
|
||||
AuthorizationEndpoint = "https://github.com/login/oauth/authorize",
|
||||
TokenEndpoint = "https://github.com/login/oauth/access_token",
|
||||
UserInformationEndpoint = "https://api.github.com/user",
|
||||
options.ClientId = "49e302895d8b09ea5656";
|
||||
options.ClientSecret = "98f1bf028608901e9df91d64ee61536fe562064b";
|
||||
options.CallbackPath = new PathString("/signin-github");
|
||||
options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
|
||||
options.TokenEndpoint = "https://github.com/login/oauth/access_token";
|
||||
options.UserInformationEndpoint = "https://api.github.com/user";
|
||||
// Retrieving user information is unique to each provider.
|
||||
Notifications = new OAuthAuthenticationNotifications()
|
||||
options.Notifications = new OAuthAuthenticationNotifications()
|
||||
{
|
||||
OnGetUserInformationAsync = async (context) =>
|
||||
{
|
||||
|
|
@ -153,7 +163,7 @@ namespace CookieSample
|
|||
|
||||
context.Identity = identity;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// Choose an authentication type
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@
|
|||
"Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*",
|
||||
"Microsoft.AspNet.Security.Twitter": "1.0.0-*",
|
||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
||||
"Microsoft.Framework.DependencyInjection": "1.0.0-*"
|
||||
"Microsoft.Framework.DependencyInjection": "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*"
|
||||
},
|
||||
"commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" },
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Security.Cookies;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
|
|
@ -10,15 +13,25 @@ namespace Microsoft.AspNet.Builder
|
|||
/// </summary>
|
||||
public static class CookieAuthenticationExtensions
|
||||
{
|
||||
public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<CookieAuthenticationOptions> configure)
|
||||
{
|
||||
return services.ConfigureOptions(configure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a cookie-based authentication middleware to your web application pipeline.
|
||||
/// </summary>
|
||||
/// <param name="app">The IApplicationBuilder passed to your configuration method</param>
|
||||
/// <param name="options">An options class that controls the middleware behavior</param>
|
||||
/// <param name="configureOptions">Used to configure the options for the middleware</param>
|
||||
/// <param name="optionsName">The name of the options class that controls the middleware behavior, null will use the default options</param>
|
||||
/// <returns>The original app parameter</returns>
|
||||
public static IApplicationBuilder UseCookieAuthentication([NotNull] this IApplicationBuilder app, [NotNull] CookieAuthenticationOptions options)
|
||||
public static IApplicationBuilder UseCookieAuthentication([NotNull] this IApplicationBuilder app, Action<CookieAuthenticationOptions> configureOptions = null, string optionsName = "")
|
||||
{
|
||||
return app.UseMiddleware<CookieAuthenticationMiddleware>(options);
|
||||
return app.UseMiddleware<CookieAuthenticationMiddleware>(
|
||||
new OptionsAction<CookieAuthenticationOptions>(configureOptions ?? (o => { }))
|
||||
{
|
||||
Name = optionsName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ 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.Cookies
|
||||
{
|
||||
|
|
@ -16,8 +17,12 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public CookieAuthenticationMiddleware(RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, CookieAuthenticationOptions options)
|
||||
: base(next, options)
|
||||
public CookieAuthenticationMiddleware(RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
IOptionsAccessor<CookieAuthenticationOptions> options,
|
||||
IOptionsAction<CookieAuthenticationOptions> configureOptions)
|
||||
: base(next, options, configureOptions)
|
||||
{
|
||||
if (Options.Notifications == null)
|
||||
{
|
||||
|
|
@ -27,11 +32,11 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
{
|
||||
Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationType;
|
||||
}
|
||||
if (options.TicketDataFormat == null)
|
||||
if (Options.TicketDataFormat == null)
|
||||
{
|
||||
IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider,
|
||||
typeof(CookieAuthenticationMiddleware).FullName, options.AuthenticationType, "v1");
|
||||
options.TicketDataFormat = new TicketDataFormat(dataProtector);
|
||||
typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1");
|
||||
Options.TicketDataFormat = new TicketDataFormat(dataProtector);
|
||||
}
|
||||
if (Options.CookieManager == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
/// Create an instance of the options initialized with the default values
|
||||
/// </summary>
|
||||
public CookieAuthenticationOptions()
|
||||
: base(CookieAuthenticationDefaults.AuthenticationType)
|
||||
{
|
||||
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType;
|
||||
ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
|
||||
CookiePath = "/";
|
||||
ExpireTimeSpan = TimeSpan.FromDays(14);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Security.Facebook;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
|
|
@ -10,35 +13,23 @@ namespace Microsoft.AspNet.Builder
|
|||
/// </summary>
|
||||
public static class FacebookAuthenticationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Authenticate users using Facebook.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="appId">The appId assigned by Facebook.</param>
|
||||
/// <param name="appSecret">The appSecret assigned by Facebook.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string appId, [NotNull] string appSecret)
|
||||
public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<FacebookAuthenticationOptions> configure)
|
||||
{
|
||||
return app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
|
||||
{
|
||||
AppId = appId,
|
||||
AppSecret = appSecret,
|
||||
});
|
||||
return services.ConfigureOptions(configure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate users using Facebook.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="options">The middleware configuration options.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, [NotNull] FacebookAuthenticationOptions options)
|
||||
public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, Action<FacebookAuthenticationOptions> configureOptions = null, string optionsName = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.SignInAsAuthenticationType))
|
||||
{
|
||||
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
|
||||
}
|
||||
return app.UseMiddleware<FacebookAuthenticationMiddleware>(options);
|
||||
return app.UseMiddleware<FacebookAuthenticationMiddleware>(
|
||||
new OptionsAction<FacebookAuthenticationOptions>(configureOptions ?? (o => { }))
|
||||
{
|
||||
Name = optionsName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNet.Security.DataProtection;
|
|||
using Microsoft.AspNet.Security.Infrastructure;
|
||||
using Microsoft.AspNet.Security.OAuth;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Facebook
|
||||
{
|
||||
|
|
@ -27,8 +28,10 @@ namespace Microsoft.AspNet.Security.Facebook
|
|||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
FacebookAuthenticationOptions options)
|
||||
: base(next, dataProtectionProvider, loggerFactory, options)
|
||||
IOptionsAccessor<ExternalAuthenticationOptions> externalOptions,
|
||||
IOptionsAccessor<FacebookAuthenticationOptions> options,
|
||||
IOptionsAction<FacebookAuthenticationOptions> configureOptions = null)
|
||||
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Options.AppId))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ namespace Microsoft.AspNet.Security.Facebook
|
|||
/// Initializes a new <see cref="FacebookAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public FacebookAuthenticationOptions()
|
||||
: base(FacebookAuthenticationDefaults.AuthenticationType)
|
||||
{
|
||||
AuthenticationType = FacebookAuthenticationDefaults.AuthenticationType;
|
||||
Caption = AuthenticationType;
|
||||
CallbackPath = new PathString("/signin-facebook");
|
||||
SendAppSecretProof = true;
|
||||
AuthorizationEndpoint = FacebookAuthenticationDefaults.AuthorizationEndpoint;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
"Microsoft.AspNet.Security.OAuth": "1.0.0-*",
|
||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.4"
|
||||
},
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Security.Google;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
|
|
@ -10,36 +13,25 @@ namespace Microsoft.AspNet.Builder
|
|||
/// </summary>
|
||||
public static class GoogleAuthenticationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Authenticate users using Google OAuth 2.0.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="clientId">The google assigned client id.</param>
|
||||
/// <param name="clientSecret">The google assigned client secret.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string clientId, [NotNull] string clientSecret)
|
||||
public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<GoogleAuthenticationOptions> configure)
|
||||
{
|
||||
return app.UseGoogleAuthentication(
|
||||
new GoogleAuthenticationOptions
|
||||
{
|
||||
ClientId = clientId,
|
||||
ClientSecret = clientSecret
|
||||
});
|
||||
return services.ConfigureOptions(configure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate users using Google OAuth 2.0.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="options">Middleware configuration options.</param>
|
||||
/// <param name="configureOptions">Used to configure Middleware options.</param>
|
||||
/// <param name="optionsName">Name of the options instance to be used</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, [NotNull] GoogleAuthenticationOptions options)
|
||||
public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, Action<GoogleAuthenticationOptions> configureOptions = null, string optionsName = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.SignInAsAuthenticationType))
|
||||
{
|
||||
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
|
||||
}
|
||||
return app.UseMiddleware<GoogleAuthenticationMiddleware>(options);
|
||||
return app.UseMiddleware<GoogleAuthenticationMiddleware>(
|
||||
new OptionsAction<GoogleAuthenticationOptions>(configureOptions ?? (o => { }))
|
||||
{
|
||||
Name = optionsName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNet.Security.DataProtection;
|
|||
using Microsoft.AspNet.Security.Infrastructure;
|
||||
using Microsoft.AspNet.Security.OAuth;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Google
|
||||
{
|
||||
|
|
@ -31,8 +32,10 @@ namespace Microsoft.AspNet.Security.Google
|
|||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
GoogleAuthenticationOptions options)
|
||||
: base(next, dataProtectionProvider, loggerFactory, options)
|
||||
IOptionsAccessor<ExternalAuthenticationOptions> externalOptions,
|
||||
IOptionsAccessor<GoogleAuthenticationOptions> options,
|
||||
IOptionsAction<GoogleAuthenticationOptions> configureOptions = null)
|
||||
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
|
||||
{
|
||||
if (Options.Notifications == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ namespace Microsoft.AspNet.Security.Google
|
|||
/// Initializes a new <see cref="GoogleAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public GoogleAuthenticationOptions()
|
||||
: base(GoogleAuthenticationDefaults.AuthenticationType)
|
||||
{
|
||||
AuthenticationType = GoogleAuthenticationDefaults.AuthenticationType;
|
||||
Caption = AuthenticationType;
|
||||
CallbackPath = new PathString("/signin-google");
|
||||
AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
"Microsoft.AspNet.Security.OAuth": "1.0.0-*",
|
||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.4"
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.4",
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Security.MicrosoftAccount;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
|
|
@ -10,36 +13,18 @@ namespace Microsoft.AspNet.Builder
|
|||
/// </summary>
|
||||
public static class MicrosoftAccountAuthenticationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Authenticate users using Microsoft Account.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="clientId">The application client ID assigned by the Microsoft authentication service.</param>
|
||||
/// <param name="clientSecret">The application client secret assigned by the Microsoft authentication service.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string clientId, [NotNull] string clientSecret)
|
||||
public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<MicrosoftAccountAuthenticationOptions> configure)
|
||||
{
|
||||
return app.UseMicrosoftAccountAuthentication(
|
||||
new MicrosoftAccountAuthenticationOptions
|
||||
{
|
||||
ClientId = clientId,
|
||||
ClientSecret = clientSecret,
|
||||
});
|
||||
return services.ConfigureOptions(configure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate users using Microsoft Account.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="options">The middleware configuration options.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, [NotNull] MicrosoftAccountAuthenticationOptions options)
|
||||
public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, Action<MicrosoftAccountAuthenticationOptions> configureOptions = null, string optionsName = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.SignInAsAuthenticationType))
|
||||
{
|
||||
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
|
||||
}
|
||||
return app.UseMiddleware<MicrosoftAccountAuthenticationMiddleware>(options);
|
||||
return app.UseMiddleware<MicrosoftAccountAuthenticationMiddleware>(
|
||||
new OptionsAction<MicrosoftAccountAuthenticationOptions>(configureOptions ?? (o => { }))
|
||||
{
|
||||
Name = optionsName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNet.Security.DataProtection;
|
|||
using Microsoft.AspNet.Security.Infrastructure;
|
||||
using Microsoft.AspNet.Security.OAuth;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Security.MicrosoftAccount
|
||||
{
|
||||
|
|
@ -27,8 +28,10 @@ namespace Microsoft.AspNet.Security.MicrosoftAccount
|
|||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
MicrosoftAccountAuthenticationOptions options)
|
||||
: base(next, dataProtectionProvider, loggerFactory, options)
|
||||
IOptionsAccessor<ExternalAuthenticationOptions> externalOptions,
|
||||
IOptionsAccessor<MicrosoftAccountAuthenticationOptions> options,
|
||||
IOptionsAction<MicrosoftAccountAuthenticationOptions> configureOptions = null)
|
||||
: base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions)
|
||||
{
|
||||
if (Options.Notifications == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ namespace Microsoft.AspNet.Security.MicrosoftAccount
|
|||
/// Initializes a new <see cref="MicrosoftAccountAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public MicrosoftAccountAuthenticationOptions()
|
||||
: base(MicrosoftAccountAuthenticationDefaults.AuthenticationType)
|
||||
{
|
||||
AuthenticationType = MicrosoftAccountAuthenticationDefaults.AuthenticationType;
|
||||
Caption = AuthenticationType;
|
||||
CallbackPath = new PathString("/signin-microsoft");
|
||||
AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
"Microsoft.AspNet.Security.OAuth": "1.0.0-*",
|
||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.4"
|
||||
},
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Security.OAuth;
|
||||
using Microsoft.AspNet.Security.Infrastructure;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
|
|
@ -18,17 +20,21 @@ namespace Microsoft.AspNet.Builder
|
|||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method.</param>
|
||||
/// <param name="options">The middleware configuration options.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] OAuthAuthenticationOptions<IOAuthAuthenticationNotifications> options)
|
||||
public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType, Action<OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>> configureOptions = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.SignInAsAuthenticationType))
|
||||
{
|
||||
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
|
||||
}
|
||||
if (options.Notifications == null)
|
||||
{
|
||||
options.Notifications = new OAuthAuthenticationNotifications();
|
||||
}
|
||||
return app.UseMiddleware<OAuthAuthenticationMiddleware<OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>, IOAuthAuthenticationNotifications>>(options);
|
||||
return app.UseMiddleware<OAuthAuthenticationMiddleware<OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>, IOAuthAuthenticationNotifications>>(
|
||||
new OptionsAction<OAuthAuthenticationOptions<IOAuthAuthenticationNotifications>>(options =>
|
||||
{
|
||||
options.AuthenticationType = authenticationType;
|
||||
options.Caption = authenticationType;
|
||||
if (configureOptions != null)
|
||||
{
|
||||
configureOptions(options);
|
||||
}
|
||||
})
|
||||
{
|
||||
Name = authenticationType,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ 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
|
||||
{
|
||||
|
|
@ -18,7 +19,7 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")]
|
||||
public class OAuthAuthenticationMiddleware<TOptions, TNotifications> : AuthenticationMiddleware<TOptions>
|
||||
where TOptions : OAuthAuthenticationOptions<TNotifications>
|
||||
where TOptions : OAuthAuthenticationOptions<TNotifications>, new()
|
||||
where TNotifications : IOAuthAuthenticationNotifications
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -32,9 +33,16 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
TOptions options)
|
||||
: base(next, options)
|
||||
IOptionsAccessor<ExternalAuthenticationOptions> externalOptions,
|
||||
IOptionsAccessor<TOptions> options,
|
||||
IOptionsAction<TOptions> configureOptions = null)
|
||||
: base(next, options, configureOptions)
|
||||
{
|
||||
// todo: review error handling
|
||||
if (string.IsNullOrWhiteSpace(Options.AuthenticationType))
|
||||
{
|
||||
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthenticationType"));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(Options.ClientId))
|
||||
{
|
||||
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId"));
|
||||
|
|
@ -57,7 +65,7 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
if (Options.StateDataFormat == null)
|
||||
{
|
||||
IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider,
|
||||
this.GetType().FullName, options.AuthenticationType, "v1");
|
||||
this.GetType().FullName, Options.AuthenticationType, "v1");
|
||||
Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +73,15 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET OAuth middleware");
|
||||
Backchannel.Timeout = Options.BackchannelTimeout;
|
||||
Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
|
||||
|
||||
if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType))
|
||||
{
|
||||
Options.SignInAsAuthenticationType = externalOptions.Options.SignInAsAuthenticationType;
|
||||
}
|
||||
if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType))
|
||||
{
|
||||
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInAsAuthenticationType"));
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpClient Backchannel { get; private set; }
|
||||
|
|
|
|||
|
|
@ -18,10 +18,8 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
/// <summary>
|
||||
/// Initializes a new <see cref="OAuthAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public OAuthAuthenticationOptions([NotNull] string authenticationType)
|
||||
: base(authenticationType)
|
||||
public OAuthAuthenticationOptions()
|
||||
{
|
||||
Caption = authenticationType;
|
||||
AuthenticationMode = AuthenticationMode.Passive;
|
||||
Scope = new List<string>();
|
||||
BackchannelTimeout = TimeSpan.FromSeconds(60);
|
||||
|
|
@ -69,9 +67,6 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
/// <summary>
|
||||
/// Get or sets the text that the user can display on a sign in user interface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default value is the authentication type.
|
||||
/// </remarks>
|
||||
public string Caption
|
||||
{
|
||||
get { return Description.Caption; }
|
||||
|
|
|
|||
|
|
@ -8,14 +8,6 @@ namespace Microsoft.AspNet.Security.OAuth
|
|||
/// </summary>
|
||||
public class OAuthAuthenticationOptions<TNotifications> : OAuthAuthenticationOptions where TNotifications : IOAuthAuthenticationNotifications
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OAuthAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public OAuthAuthenticationOptions([NotNull] string authenticationType)
|
||||
: base(authenticationType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IOAuthAuthenticationNotifications"/> used to handle authentication events.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
// 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;
|
||||
using Microsoft.AspNet.Security.Twitter;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
|
|
@ -10,36 +14,18 @@ namespace Microsoft.AspNet.Builder
|
|||
/// </summary>
|
||||
public static class TwitterAuthenticationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Authenticate users using Twitter
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method</param>
|
||||
/// <param name="consumerKey">The Twitter-issued consumer key</param>
|
||||
/// <param name="consumerSecret">The Twitter-issued consumer secret</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/></returns>
|
||||
public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string consumerKey, [NotNull] string consumerSecret)
|
||||
public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action<TwitterAuthenticationOptions> configure)
|
||||
{
|
||||
return app.UseTwitterAuthentication(
|
||||
new TwitterAuthenticationOptions
|
||||
{
|
||||
ConsumerKey = consumerKey,
|
||||
ConsumerSecret = consumerSecret,
|
||||
});
|
||||
return services.ConfigureOptions(configure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate users using Twitter
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> passed to the configure method</param>
|
||||
/// <param name="options">Middleware configuration options</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/></returns>
|
||||
public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, [NotNull] TwitterAuthenticationOptions options)
|
||||
public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, Action<TwitterAuthenticationOptions> configureOptions = null, string optionsName = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.SignInAsAuthenticationType))
|
||||
{
|
||||
options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
|
||||
}
|
||||
return app.UseMiddleware<TwitterAuthenticationMiddleware>(options);
|
||||
return app.UseMiddleware<TwitterAuthenticationMiddleware>(
|
||||
new OptionsAction<TwitterAuthenticationOptions>(configureOptions ?? (o => { }))
|
||||
{
|
||||
Name = optionsName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Microsoft.AspNet.Security.DataProtection;
|
|||
using Microsoft.AspNet.Security.Infrastructure;
|
||||
using Microsoft.AspNet.Security.Twitter.Messages;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Twitter
|
||||
{
|
||||
|
|
@ -35,8 +36,10 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
TwitterAuthenticationOptions options)
|
||||
: base(next, options)
|
||||
IOptionsAccessor<ExternalAuthenticationOptions> externalOptions,
|
||||
IOptionsAccessor<TwitterAuthenticationOptions> options,
|
||||
IOptionsAction<TwitterAuthenticationOptions> configureOptions = null)
|
||||
: base(next, options, configureOptions)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Options.ConsumerSecret))
|
||||
{
|
||||
|
|
@ -56,13 +59,22 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
if (Options.StateDataFormat == null)
|
||||
{
|
||||
IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider,
|
||||
typeof(TwitterAuthenticationMiddleware).FullName, options.AuthenticationType, "v1");
|
||||
typeof(TwitterAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1");
|
||||
Options.StateDataFormat = new SecureDataFormat<RequestToken>(
|
||||
Serializers.RequestToken,
|
||||
dataProtector,
|
||||
TextEncodings.Base64Url);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType))
|
||||
{
|
||||
Options.SignInAsAuthenticationType = externalOptions.Options.SignInAsAuthenticationType;
|
||||
}
|
||||
if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType))
|
||||
{
|
||||
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInAsAuthenticationType"));
|
||||
}
|
||||
|
||||
_httpClient = new HttpClient(ResolveHttpMessageHandler(Options));
|
||||
_httpClient.Timeout = Options.BackchannelTimeout;
|
||||
_httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
/// Initializes a new instance of the <see cref="TwitterAuthenticationOptions"/> class.
|
||||
/// </summary>
|
||||
public TwitterAuthenticationOptions()
|
||||
: base(TwitterAuthenticationDefaults.AuthenticationType)
|
||||
{
|
||||
Caption = TwitterAuthenticationDefaults.AuthenticationType;
|
||||
AuthenticationType = TwitterAuthenticationDefaults.AuthenticationType;
|
||||
Caption = AuthenticationType;
|
||||
CallbackPath = new PathString("/signin-twitter");
|
||||
AuthenticationMode = AuthenticationMode.Passive;
|
||||
BackchannelTimeout = TimeSpan.FromSeconds(60);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"Microsoft.AspNet.Security.DataProtection": "1.0.0-*",
|
||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.4"
|
||||
},
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -17,17 +17,6 @@ namespace Microsoft.AspNet.Security
|
|||
{
|
||||
private string _authenticationType;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize properties of AuthenticationOptions base class
|
||||
/// </summary>
|
||||
/// <param name="authenticationType">Assigned to the AuthenticationType property</param>
|
||||
protected AuthenticationOptions(string authenticationType)
|
||||
{
|
||||
Description = new AuthenticationDescription();
|
||||
AuthenticationType = authenticationType;
|
||||
AuthenticationMode = AuthenticationMode.Active;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The AuthenticationType in the options corresponds to the IIdentity AuthenticationType property. A different
|
||||
/// value may be assigned in order to use the same authentication middleware type more than once in a pipeline.
|
||||
|
|
@ -47,11 +36,11 @@ namespace Microsoft.AspNet.Security
|
|||
/// alter 401 Unauthorized responses going out. If Passive the authentication middleware will only provide
|
||||
/// identity and alter responses when explicitly indicated by the AuthenticationType.
|
||||
/// </summary>
|
||||
public AuthenticationMode AuthenticationMode { get; set; }
|
||||
public AuthenticationMode AuthenticationMode { get; set; } = AuthenticationMode.Active;
|
||||
|
||||
/// <summary>
|
||||
/// Additional information about the authentication type which is made available to the application.
|
||||
/// </summary>
|
||||
public AuthenticationDescription Description { get; set; }
|
||||
public AuthenticationDescription Description { get; set; } = new AuthenticationDescription();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extensions methods for app.Property values that are only needed by implementations of authentication middleware.
|
||||
/// </summary>
|
||||
public static class BuilderSecurityExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the previously set AuthenticationType that external sign in middleware should use when the
|
||||
/// browser navigates back to their return url.
|
||||
/// </summary>
|
||||
/// <param name="app">App builder passed to the application startup code</param>
|
||||
/// <returns></returns>
|
||||
public static string GetDefaultSignInAsAuthenticationType([NotNull] this IApplicationBuilder app)
|
||||
{
|
||||
object value;
|
||||
if (app.Properties.TryGetValue(Constants.DefaultSignInAsAuthenticationType, out value))
|
||||
{
|
||||
var authenticationType = value as string;
|
||||
if (!string.IsNullOrEmpty(authenticationType))
|
||||
{
|
||||
return authenticationType;
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException(Resources.Exception_MissingDefaultSignInAsAuthenticationType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by middleware to change the name of the AuthenticationType that external middleware should use
|
||||
/// when the browser navigates back to their return url.
|
||||
/// </summary>
|
||||
/// <param name="app">App builder passed to the application startup code</param>
|
||||
/// <param name="authenticationType">AuthenticationType that external middleware should sign in as.</param>
|
||||
public static void SetDefaultSignInAsAuthenticationType([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType)
|
||||
{
|
||||
app.Properties[Constants.DefaultSignInAsAuthenticationType] = authenticationType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// String constants used only by the Security assembly
|
||||
/// </summary>
|
||||
internal static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Used by middleware extension methods to coordinate the default value Options property SignInAsAuthenticationType
|
||||
/// </summary>
|
||||
internal const string DefaultSignInAsAuthenticationType = "Microsoft.AspNet.Security.DefaultSignInAsAuthenticationType";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNet.Security
|
||||
{
|
||||
public class ExternalAuthenticationOptions
|
||||
{
|
||||
public string SignInAsAuthenticationType { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -6,19 +6,30 @@ using System;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Infrastructure
|
||||
{
|
||||
public abstract class AuthenticationMiddleware<TOptions> where TOptions : AuthenticationOptions
|
||||
public abstract class AuthenticationMiddleware<TOptions> where TOptions : AuthenticationOptions, new()
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] TOptions options)
|
||||
protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOptionsAccessor<TOptions> options, IOptionsAction<TOptions> configureOptions)
|
||||
{
|
||||
Options = options;
|
||||
if (configureOptions != null)
|
||||
{
|
||||
Options = options.GetNamedOptions(configureOptions.Name);
|
||||
configureOptions.Invoke(Options);
|
||||
}
|
||||
else
|
||||
{
|
||||
Options = options.Options;
|
||||
}
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public string AuthenticationType { get; set; }
|
||||
|
||||
public TOptions Options { get; set; }
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
|
|
|
|||
|
|
@ -123,9 +123,6 @@
|
|||
<data name="Exception_UnhookAuthenticationStateType" xml:space="preserve">
|
||||
<value>The state passed to UnhookAuthentication may only be the return value from HookAuthentication.</value>
|
||||
</data>
|
||||
<data name="Exception_MissingDefaultSignInAsAuthenticationType" xml:space="preserve">
|
||||
<value>A default value for SignInAsAuthenticationType was not found in IApplicationBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.</value>
|
||||
</data>
|
||||
<data name="Exception_AuthenticationTokenDoesNotProvideSyncMethods" xml:space="preserve">
|
||||
<value>The AuthenticationTokenProvider's required synchronous events have not been registered.</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
"Microsoft.AspNet.PipelineCore": "1.0.0-*",
|
||||
"Microsoft.AspNet.Security.DataProtection": "1.0.0-*",
|
||||
"Microsoft.Framework.DependencyInjection": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging": "1.0.0-*"
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ using Microsoft.AspNet.Http.Security;
|
|||
using Microsoft.AspNet.TestHost;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Cookies
|
||||
{
|
||||
|
|
@ -26,7 +28,7 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
[Fact]
|
||||
public async Task NormalRequestPassesThrough()
|
||||
{
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
});
|
||||
HttpResponseMessage response = await server.CreateClient().GetAsync("http://example.com/normal");
|
||||
|
|
@ -36,9 +38,9 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
[Fact]
|
||||
public async Task ProtectedRequestShouldRedirectToLogin()
|
||||
{
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
LoginPath = new PathString("/login")
|
||||
options.LoginPath = new PathString("/login");
|
||||
});
|
||||
|
||||
Transaction transaction = await SendAsync(server, "http://example.com/protected");
|
||||
|
|
@ -53,9 +55,9 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
[Fact]
|
||||
public async Task ProtectedCustomRequestShouldRedirectToCustomLogin()
|
||||
{
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
LoginPath = new PathString("/login")
|
||||
options.LoginPath = new PathString("/login");
|
||||
});
|
||||
|
||||
Transaction transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect");
|
||||
|
|
@ -77,10 +79,10 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
[Fact]
|
||||
public async Task SignInCausesDefaultCookieToBeCreated()
|
||||
{
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
LoginPath = new PathString("/login"),
|
||||
CookieName = "TestCookie",
|
||||
options.LoginPath = new PathString("/login");
|
||||
options.CookieName = "TestCookie";
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction = await SendAsync(server, "http://example.com/testpath");
|
||||
|
|
@ -106,11 +108,11 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
string requestUri,
|
||||
bool shouldBeSecureOnly)
|
||||
{
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
LoginPath = new PathString("/login"),
|
||||
CookieName = "TestCookie",
|
||||
CookieSecure = cookieSecureOption
|
||||
options.LoginPath = new PathString("/login");
|
||||
options.CookieName = "TestCookie";
|
||||
options.CookieSecure = cookieSecureOption;
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction = await SendAsync(server, requestUri);
|
||||
|
|
@ -129,22 +131,22 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
[Fact]
|
||||
public async Task CookieOptionsAlterSetCookieHeader()
|
||||
{
|
||||
TestServer server1 = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server1 = CreateServer(options =>
|
||||
{
|
||||
CookieName = "TestCookie",
|
||||
CookiePath = "/foo",
|
||||
CookieDomain = "another.com",
|
||||
CookieSecure = CookieSecureOption.Always,
|
||||
CookieHttpOnly = true,
|
||||
options.CookieName = "TestCookie";
|
||||
options.CookiePath = "/foo";
|
||||
options.CookieDomain = "another.com";
|
||||
options.CookieSecure = CookieSecureOption.Always;
|
||||
options.CookieHttpOnly = true;
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction1 = await SendAsync(server1, "http://example.com/testpath");
|
||||
|
||||
TestServer server2 = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server2 = CreateServer(options =>
|
||||
{
|
||||
CookieName = "SecondCookie",
|
||||
CookieSecure = CookieSecureOption.Never,
|
||||
CookieHttpOnly = false,
|
||||
options.CookieName = "SecondCookie";
|
||||
options.CookieSecure = CookieSecureOption.Never;
|
||||
options.CookieHttpOnly = false;
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction2 = await SendAsync(server2, "http://example.com/testpath");
|
||||
|
|
@ -168,9 +170,9 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
public async Task CookieContainsIdentity()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
SystemClock = clock
|
||||
options.SystemClock = clock;
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
|
||||
|
|
@ -184,11 +186,11 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
public async Task CookieStopsWorkingAfterExpiration()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
SystemClock = clock,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(10),
|
||||
SlidingExpiration = false,
|
||||
options.SystemClock = clock;
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
options.SlidingExpiration = false;
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
|
||||
|
|
@ -215,11 +217,11 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
public async Task CookieExpirationCanBeOverridenInSignin()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
SystemClock = clock,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(10),
|
||||
SlidingExpiration = false,
|
||||
options.SystemClock = clock;
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
options.SlidingExpiration = false;
|
||||
},
|
||||
context =>
|
||||
{
|
||||
|
|
@ -253,18 +255,18 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
public async Task CookieExpirationCanBeOverridenInEvent()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
SystemClock = clock,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(10),
|
||||
SlidingExpiration = false,
|
||||
Notifications = new CookieAuthenticationNotifications()
|
||||
options.SystemClock = clock;
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
options.SlidingExpiration = false;
|
||||
options.Notifications = new CookieAuthenticationNotifications()
|
||||
{
|
||||
OnResponseSignIn = context =>
|
||||
{
|
||||
context.Properties.ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5));
|
||||
}
|
||||
}
|
||||
};
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
|
||||
|
|
@ -291,11 +293,11 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
public async Task CookieIsRenewedWithSlidingExpiration()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
SystemClock = clock,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(10),
|
||||
SlidingExpiration = true,
|
||||
options.SystemClock = clock;
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
options.SlidingExpiration = true;
|
||||
}, SignInAsAlice);
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
|
||||
|
|
@ -328,9 +330,9 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
[Fact]
|
||||
public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred()
|
||||
{
|
||||
TestServer server = CreateServer(new CookieAuthenticationOptions
|
||||
TestServer server = CreateServer(options =>
|
||||
{
|
||||
LoginPath = new PathString("/login")
|
||||
options.LoginPath = new PathString("/login");
|
||||
});
|
||||
|
||||
Transaction transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true);
|
||||
|
|
@ -363,11 +365,12 @@ namespace Microsoft.AspNet.Security.Cookies
|
|||
return me;
|
||||
}
|
||||
|
||||
private static TestServer CreateServer(CookieAuthenticationOptions options, Func<HttpContext, Task> testpath = null)
|
||||
private static TestServer CreateServer(Action<CookieAuthenticationOptions> configureOptions, Func<HttpContext, Task> testpath = null)
|
||||
{
|
||||
return TestServer.Create(app =>
|
||||
{
|
||||
app.UseCookieAuthentication(options);
|
||||
app.UseServices(services => { });
|
||||
app.UseCookieAuthentication(configureOptions);
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var req = context.Request;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using Microsoft.AspNet.Http.Security;
|
|||
using Microsoft.AspNet.Security.Cookies;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -23,20 +24,35 @@ namespace Microsoft.AspNet.Security.Facebook
|
|||
[Fact]
|
||||
public async Task ChallengeWillTriggerApplyRedirectEvent()
|
||||
{
|
||||
var options = new FacebookAuthenticationOptions()
|
||||
{
|
||||
AppId = "Test App Id",
|
||||
AppSecret = "Test App Secret",
|
||||
Notifications = new FacebookAuthenticationNotifications
|
||||
{
|
||||
OnApplyRedirect = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(
|
||||
app => app.UseFacebookAuthentication(options),
|
||||
app =>
|
||||
{
|
||||
app.UseServices(services =>
|
||||
{
|
||||
services.ConfigureFacebookAuthentication(options =>
|
||||
{
|
||||
options.AppId = "Test App Id";
|
||||
options.AppSecret = "Test App Secret";
|
||||
options.Notifications = new FacebookAuthenticationNotifications
|
||||
{
|
||||
OnApplyRedirect = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
};
|
||||
});
|
||||
services.ConfigureCookieAuthentication(options =>
|
||||
{
|
||||
options.AuthenticationType = "External";
|
||||
});
|
||||
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
|
||||
{
|
||||
options.SignInAsAuthenticationType = "External";
|
||||
});
|
||||
});
|
||||
app.UseFacebookAuthentication();
|
||||
app.UseCookieAuthentication();
|
||||
},
|
||||
context =>
|
||||
{
|
||||
context.Response.Challenge("Facebook");
|
||||
|
|
@ -52,7 +68,27 @@ namespace Microsoft.AspNet.Security.Facebook
|
|||
public async Task ChallengeWillTriggerRedirection()
|
||||
{
|
||||
var server = CreateServer(
|
||||
app => app.UseFacebookAuthentication("Test App Id", "Test App Secret"),
|
||||
app =>
|
||||
{
|
||||
app.UseServices(services =>
|
||||
{
|
||||
services.ConfigureFacebookAuthentication(options =>
|
||||
{
|
||||
options.AppId = "Test App Id";
|
||||
options.AppSecret = "Test App Secret";
|
||||
});
|
||||
services.ConfigureCookieAuthentication(options =>
|
||||
{
|
||||
options.AuthenticationType = "External";
|
||||
});
|
||||
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
|
||||
{
|
||||
options.SignInAsAuthenticationType = "External";
|
||||
});
|
||||
});
|
||||
app.UseFacebookAuthentication();
|
||||
app.UseCookieAuthentication();
|
||||
},
|
||||
context =>
|
||||
{
|
||||
context.Response.Challenge("Facebook");
|
||||
|
|
@ -73,11 +109,6 @@ namespace Microsoft.AspNet.Security.Facebook
|
|||
{
|
||||
return TestServer.Create(app =>
|
||||
{
|
||||
app.SetDefaultSignInAsAuthenticationType("External");
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions()
|
||||
{
|
||||
AuthenticationType = "External"
|
||||
});
|
||||
if (configure != null)
|
||||
{
|
||||
configure(app);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ using Microsoft.AspNet.TestHost;
|
|||
using Newtonsoft.Json;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.AspNet.Security.DataProtection;
|
||||
using Microsoft.AspNet.Security.DataHandler;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Google
|
||||
{
|
||||
|
|
@ -29,10 +33,10 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ChallengeWillTriggerRedirection()
|
||||
{
|
||||
var server = CreateServer(new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret"
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/challenge");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
|
|
@ -51,11 +55,11 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task Challenge401WillTriggerRedirection()
|
||||
{
|
||||
var server = CreateServer(new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
AuthenticationMode = AuthenticationMode.Active,
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.AuthenticationMode = AuthenticationMode.Active;
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/401");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
|
|
@ -70,10 +74,10 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ChallengeWillSetCorrelationCookie()
|
||||
{
|
||||
var server = CreateServer(new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret"
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/challenge");
|
||||
Console.WriteLine(transaction.SetCookie);
|
||||
|
|
@ -83,11 +87,11 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task Challenge401WillSetCorrelationCookie()
|
||||
{
|
||||
var server = CreateServer(new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
AuthenticationMode = AuthenticationMode.Active,
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.AuthenticationMode = AuthenticationMode.Active;
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/401");
|
||||
Console.WriteLine(transaction.SetCookie);
|
||||
|
|
@ -97,10 +101,11 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ChallengeWillSetDefaultScope()
|
||||
{
|
||||
var server = CreateServer(new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret"
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.AuthenticationMode = AuthenticationMode.Active;
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/challenge");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
|
|
@ -111,11 +116,11 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task Challenge401WillSetDefaultScope()
|
||||
{
|
||||
var server = CreateServer(new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
AuthenticationMode = AuthenticationMode.Active,
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.AuthenticationMode = AuthenticationMode.Active;
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/401");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
|
|
@ -126,13 +131,12 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ChallengeWillUseOptionsScope()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
};
|
||||
options.Scope.Add("https://www.googleapis.com/auth/plus.login");
|
||||
var server = CreateServer(options);
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.Scope.Add("https://www.googleapis.com/auth/plus.login");
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/challenge");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
var query = transaction.Response.Headers.Location.Query;
|
||||
|
|
@ -142,13 +146,12 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ChallengeWillUseAuthenticationPropertiesAsParameters()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret"
|
||||
};
|
||||
var server = CreateServer(options,
|
||||
context =>
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
},
|
||||
context =>
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
|
|
@ -179,19 +182,18 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ChallengeWillTriggerApplyRedirectEvent()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
Notifications = new GoogleAuthenticationNotifications
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.Notifications = new GoogleAuthenticationNotifications
|
||||
{
|
||||
OnApplyRedirect = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(options);
|
||||
};
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/challenge");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
var query = transaction.Response.Headers.Location.Query;
|
||||
|
|
@ -201,12 +203,11 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ReplyPathWithoutStateQueryStringWillBeRejected()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret"
|
||||
};
|
||||
var server = CreateServer(options);
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
});
|
||||
var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode");
|
||||
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
|
||||
}
|
||||
|
|
@ -214,57 +215,58 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest"));
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.StateDataFormat = stateFormat;
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = async req =>
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
access_token = "Test Access Token",
|
||||
expire_in = 3600,
|
||||
token_type = "Bearer"
|
||||
});
|
||||
}
|
||||
else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
id = "Test User ID",
|
||||
displayName = "Test Name",
|
||||
name = new
|
||||
{
|
||||
familyName = "Test Family Name",
|
||||
givenName = "Test Given Name"
|
||||
},
|
||||
url = "Profile link",
|
||||
emails = new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
value = "Test email",
|
||||
type = "account"
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
access_token = "Test Access Token",
|
||||
expire_in = 3600,
|
||||
token_type = "Bearer"
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(options);
|
||||
else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
id = "Test User ID",
|
||||
displayName = "Test Name",
|
||||
name = new
|
||||
{
|
||||
familyName = "Test Family Name",
|
||||
givenName = "Test Given Name"
|
||||
},
|
||||
url = "Profile link",
|
||||
emails = new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
value = "Test email",
|
||||
type = "account"
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
});
|
||||
var properties = new AuthenticationProperties();
|
||||
var correlationKey = ".AspNet.Correlation.Google";
|
||||
var correlationValue = "TestCorrelationId";
|
||||
properties.Dictionary.Add(correlationKey, correlationValue);
|
||||
properties.RedirectUri = "/me";
|
||||
var state = options.StateDataFormat.Protect(properties);
|
||||
var state = stateFormat.Protect(properties);
|
||||
var transaction = await SendAsync(server,
|
||||
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
|
||||
correlationKey + "=" + correlationValue);
|
||||
|
|
@ -287,25 +289,26 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ReplyPathWillRejectIfCodeIsInvalid()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest"));
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.StateDataFormat = stateFormat;
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = req =>
|
||||
{
|
||||
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest));
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(options);
|
||||
};
|
||||
});
|
||||
var properties = new AuthenticationProperties();
|
||||
var correlationKey = ".AspNet.Correlation.Google";
|
||||
var correlationValue = "TestCorrelationId";
|
||||
properties.Dictionary.Add(correlationKey, correlationValue);
|
||||
properties.RedirectUri = "/me";
|
||||
var state = options.StateDataFormat.Protect(properties);
|
||||
var state = stateFormat.Protect(properties);
|
||||
var transaction = await SendAsync(server,
|
||||
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
|
||||
correlationKey + "=" + correlationValue);
|
||||
|
|
@ -316,25 +319,26 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task ReplyPathWillRejectIfAccessTokenIsMissing()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest"));
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.StateDataFormat = stateFormat;
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = async req =>
|
||||
Sender = req =>
|
||||
{
|
||||
return await ReturnJsonResponse(new object());
|
||||
return ReturnJsonResponse(new object());
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(options);
|
||||
};
|
||||
});
|
||||
var properties = new AuthenticationProperties();
|
||||
var correlationKey = ".AspNet.Correlation.Google";
|
||||
var correlationValue = "TestCorrelationId";
|
||||
properties.Dictionary.Add(correlationKey, correlationValue);
|
||||
properties.RedirectUri = "/me";
|
||||
var state = options.StateDataFormat.Protect(properties);
|
||||
var state = stateFormat.Protect(properties);
|
||||
var transaction = await SendAsync(server,
|
||||
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
|
||||
correlationKey + "=" + correlationValue);
|
||||
|
|
@ -345,11 +349,13 @@ namespace Microsoft.AspNet.Security.Google
|
|||
[Fact]
|
||||
public async Task AuthenticatedEventCanGetRefreshToken()
|
||||
{
|
||||
var options = new GoogleAuthenticationOptions()
|
||||
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest"));
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
ClientId = "Test Id",
|
||||
ClientSecret = "Test Secret",
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
options.ClientId = "Test Id";
|
||||
options.ClientSecret = "Test Secret";
|
||||
options.StateDataFormat = stateFormat;
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = async req =>
|
||||
{
|
||||
|
|
@ -388,8 +394,8 @@ namespace Microsoft.AspNet.Security.Google
|
|||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
Notifications = new GoogleAuthenticationNotifications()
|
||||
};
|
||||
options.Notifications = new GoogleAuthenticationNotifications()
|
||||
{
|
||||
OnAuthenticated = context =>
|
||||
{
|
||||
|
|
@ -397,15 +403,14 @@ namespace Microsoft.AspNet.Security.Google
|
|||
context.Identity.AddClaim(new Claim("RefreshToken", refreshToken));
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(options);
|
||||
};
|
||||
});
|
||||
var properties = new AuthenticationProperties();
|
||||
var correlationKey = ".AspNet.Correlation.Google";
|
||||
var correlationValue = "TestCorrelationId";
|
||||
properties.Dictionary.Add(correlationKey, correlationValue);
|
||||
properties.RedirectUri = "/me";
|
||||
var state = options.StateDataFormat.Protect(properties);
|
||||
var state = stateFormat.Protect(properties);
|
||||
var transaction = await SendAsync(server,
|
||||
"https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
|
||||
correlationKey + "=" + correlationValue);
|
||||
|
|
@ -456,16 +461,19 @@ namespace Microsoft.AspNet.Security.Google
|
|||
return transaction;
|
||||
}
|
||||
|
||||
private static TestServer CreateServer(GoogleAuthenticationOptions options, Func<HttpContext, Task> testpath = null)
|
||||
private static TestServer CreateServer(Action<GoogleAuthenticationOptions> configureOptions, Func<HttpContext, Task> testpath = null)
|
||||
{
|
||||
return TestServer.Create(app =>
|
||||
{
|
||||
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationType);
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions()
|
||||
app.UseServices(services =>
|
||||
{
|
||||
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
|
||||
{
|
||||
AuthenticationType = CookieAuthenticationType
|
||||
options.SignInAsAuthenticationType = CookieAuthenticationType;
|
||||
});
|
||||
app.UseGoogleAuthentication(options);
|
||||
});
|
||||
app.UseCookieAuthentication(options => options.AuthenticationType = CookieAuthenticationType);
|
||||
app.UseGoogleAuthentication(configureOptions);
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var req = context.Request;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ using Microsoft.AspNet.TestHost;
|
|||
using Newtonsoft.Json;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.AspNet.Security.DataHandler;
|
||||
using Microsoft.AspNet.Security.DataProtection;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount
|
||||
{
|
||||
|
|
@ -28,20 +32,19 @@ namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount
|
|||
[Fact]
|
||||
public async Task ChallengeWillTriggerApplyRedirectEvent()
|
||||
{
|
||||
var options = new MicrosoftAccountAuthenticationOptions()
|
||||
{
|
||||
ClientId = "Test Client Id",
|
||||
ClientSecret = "Test Client Secret",
|
||||
Notifications = new MicrosoftAccountAuthenticationNotifications
|
||||
{
|
||||
OnApplyRedirect = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
}
|
||||
};
|
||||
var server = CreateServer(
|
||||
app => app.UseMicrosoftAccountAuthentication(options),
|
||||
options =>
|
||||
{
|
||||
options.ClientId = "Test Client Id";
|
||||
options.ClientSecret = "Test Client Secret";
|
||||
options.Notifications = new MicrosoftAccountAuthenticationNotifications
|
||||
{
|
||||
OnApplyRedirect = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
};
|
||||
},
|
||||
context =>
|
||||
{
|
||||
context.Response.Challenge("Microsoft");
|
||||
|
|
@ -57,7 +60,11 @@ namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount
|
|||
public async Task ChallengeWillTriggerRedirection()
|
||||
{
|
||||
var server = CreateServer(
|
||||
app => app.UseMicrosoftAccountAuthentication("Test Client Id", "Test Client Secret"),
|
||||
options =>
|
||||
{
|
||||
options.ClientId = "Test Client Id";
|
||||
options.ClientSecret = "Test Client Secret";
|
||||
},
|
||||
context =>
|
||||
{
|
||||
context.Response.Challenge("Microsoft");
|
||||
|
|
@ -77,54 +84,55 @@ namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount
|
|||
[Fact]
|
||||
public async Task AuthenticatedEventCanGetRefreshToken()
|
||||
{
|
||||
var options = new MicrosoftAccountAuthenticationOptions()
|
||||
{
|
||||
ClientId = "Test Client Id",
|
||||
ClientSecret = "Test Client Secret",
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = async req =>
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf")
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
access_token = "Test Access Token",
|
||||
expire_in = 3600,
|
||||
token_type = "Bearer",
|
||||
refresh_token = "Test Refresh Token"
|
||||
});
|
||||
}
|
||||
else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me")
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
id = "Test User ID",
|
||||
name = "Test Name",
|
||||
first_name = "Test Given Name",
|
||||
last_name = "Test Family Name",
|
||||
emails = new
|
||||
{
|
||||
preferred = "Test email"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
Notifications = new MicrosoftAccountAuthenticationNotifications
|
||||
{
|
||||
OnAuthenticated = context =>
|
||||
{
|
||||
var refreshToken = context.RefreshToken;
|
||||
context.Identity.AddClaim(new Claim("RefreshToken", refreshToken));
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("MsftTest"));
|
||||
var server = CreateServer(
|
||||
app => app.UseMicrosoftAccountAuthentication(options),
|
||||
options =>
|
||||
{
|
||||
options.ClientId = "Test Client Id";
|
||||
options.ClientSecret = "Test Client Secret";
|
||||
options.StateDataFormat = stateFormat;
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = async req =>
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf")
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
access_token = "Test Access Token",
|
||||
expire_in = 3600,
|
||||
token_type = "Bearer",
|
||||
refresh_token = "Test Refresh Token"
|
||||
});
|
||||
}
|
||||
else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me")
|
||||
{
|
||||
return await ReturnJsonResponse(new
|
||||
{
|
||||
id = "Test User ID",
|
||||
name = "Test Name",
|
||||
first_name = "Test Given Name",
|
||||
last_name = "Test Family Name",
|
||||
emails = new
|
||||
{
|
||||
preferred = "Test email"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
options.Notifications = new MicrosoftAccountAuthenticationNotifications
|
||||
{
|
||||
OnAuthenticated = context =>
|
||||
{
|
||||
var refreshToken = context.RefreshToken;
|
||||
context.Identity.AddClaim(new Claim("RefreshToken", refreshToken));
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
};
|
||||
},
|
||||
context =>
|
||||
{
|
||||
Describe(context.Response, (ClaimsIdentity)context.User.Identity);
|
||||
|
|
@ -135,7 +143,7 @@ namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount
|
|||
var correlationValue = "TestCorrelationId";
|
||||
properties.Dictionary.Add(correlationKey, correlationValue);
|
||||
properties.RedirectUri = "/me";
|
||||
var state = options.StateDataFormat.Protect(properties);
|
||||
var state = stateFormat.Protect(properties);
|
||||
var transaction = await SendAsync(server,
|
||||
"https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state),
|
||||
correlationKey + "=" + correlationValue);
|
||||
|
|
@ -151,19 +159,19 @@ namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount
|
|||
transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token");
|
||||
}
|
||||
|
||||
private static TestServer CreateServer(Action<IApplicationBuilder> configure, Func<HttpContext, bool> handler)
|
||||
private static TestServer CreateServer(Action<MicrosoftAccountAuthenticationOptions> configureOptions, Func<HttpContext, bool> handler)
|
||||
{
|
||||
return TestServer.Create(app =>
|
||||
{
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||
app.UseServices(services =>
|
||||
{
|
||||
AuthenticationType = "External"
|
||||
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
|
||||
{
|
||||
options.SignInAsAuthenticationType = "External";
|
||||
});
|
||||
});
|
||||
app.SetDefaultSignInAsAuthenticationType("External");
|
||||
if (configure != null)
|
||||
{
|
||||
configure(app);
|
||||
}
|
||||
app.UseCookieAuthentication(options => options.AuthenticationType = "External");
|
||||
app.UseMicrosoftAccountAuthentication(configureOptions);
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
if (handler == null || !handler(context))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ using Microsoft.AspNet.TestHost;
|
|||
using Newtonsoft.Json;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Twitter
|
||||
{
|
||||
|
|
@ -23,20 +25,21 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
[Fact]
|
||||
public async Task ChallengeWillTriggerApplyRedirectEvent()
|
||||
{
|
||||
var options = new TwitterAuthenticationOptions()
|
||||
{
|
||||
ConsumerKey = "Test Consumer Key",
|
||||
ConsumerSecret = "Test Consumer Secret",
|
||||
Notifications = new TwitterAuthenticationNotifications
|
||||
var server = CreateServer(
|
||||
app => app.UseTwitterAuthentication(options =>
|
||||
{
|
||||
OnApplyRedirect = context =>
|
||||
options.ConsumerKey = "Test Consumer Key";
|
||||
options.ConsumerSecret = "Test Consumer Secret";
|
||||
options.Notifications = new TwitterAuthenticationNotifications
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
},
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = req =>
|
||||
OnApplyRedirect = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&custom=test");
|
||||
}
|
||||
};
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = req =>
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token")
|
||||
{
|
||||
|
|
@ -50,11 +53,9 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
}
|
||||
return Task.FromResult<HttpResponseMessage>(null);
|
||||
}
|
||||
},
|
||||
BackchannelCertificateValidator = null
|
||||
};
|
||||
var server = CreateServer(
|
||||
app => app.UseTwitterAuthentication(options),
|
||||
};
|
||||
options.BackchannelCertificateValidator = null;
|
||||
}),
|
||||
context =>
|
||||
{
|
||||
context.Response.Challenge("Twitter");
|
||||
|
|
@ -69,31 +70,30 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
[Fact]
|
||||
public async Task ChallengeWillTriggerRedirection()
|
||||
{
|
||||
var options = new TwitterAuthenticationOptions()
|
||||
{
|
||||
ConsumerKey = "Test Consumer Key",
|
||||
ConsumerSecret = "Test Consumer Secret",
|
||||
BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = req =>
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token")
|
||||
{
|
||||
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content =
|
||||
new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret",
|
||||
Encoding.UTF8,
|
||||
"application/x-www-form-urlencoded")
|
||||
});
|
||||
}
|
||||
return Task.FromResult<HttpResponseMessage>(null);
|
||||
}
|
||||
},
|
||||
BackchannelCertificateValidator = null
|
||||
};
|
||||
var server = CreateServer(
|
||||
app => app.UseTwitterAuthentication(options),
|
||||
app => app.UseTwitterAuthentication(options =>
|
||||
{
|
||||
options.ConsumerKey = "Test Consumer Key";
|
||||
options.ConsumerSecret = "Test Consumer Secret";
|
||||
options.BackchannelHttpHandler = new TestHttpMessageHandler
|
||||
{
|
||||
Sender = req =>
|
||||
{
|
||||
if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token")
|
||||
{
|
||||
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content =
|
||||
new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret",
|
||||
Encoding.UTF8,
|
||||
"application/x-www-form-urlencoded")
|
||||
});
|
||||
}
|
||||
return Task.FromResult<HttpResponseMessage>(null);
|
||||
}
|
||||
};
|
||||
options.BackchannelCertificateValidator = null;
|
||||
}),
|
||||
context =>
|
||||
{
|
||||
context.Response.Challenge("Twitter");
|
||||
|
|
@ -109,10 +109,16 @@ namespace Microsoft.AspNet.Security.Twitter
|
|||
{
|
||||
return TestServer.Create(app =>
|
||||
{
|
||||
app.SetDefaultSignInAsAuthenticationType("External");
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||
app.UseServices(services =>
|
||||
{
|
||||
AuthenticationType = "External"
|
||||
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
|
||||
{
|
||||
options.SignInAsAuthenticationType = "External";
|
||||
});
|
||||
});
|
||||
app.UseCookieAuthentication(options =>
|
||||
{
|
||||
options.AuthenticationType = "External";
|
||||
});
|
||||
if (configure != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
"Microsoft.AspNet.Security.Twitter": "1.0.0-*",
|
||||
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||
"Microsoft.Framework.DependencyInjection": "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel": "1.0.0-*",
|
||||
"Moq": "4.2.1312.1622",
|
||||
"Xunit.KRunner": "1.0.0-*"
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue