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