зеркало из https://github.com/aspnet/Security.git
Refactor Events + Add IAuthenticationBuilder
This commit is contained in:
Родитель
e1cd8c9bc4
Коммит
ff9f145a8e
|
@ -18,9 +18,7 @@ namespace CookieSample
|
|||
{
|
||||
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication();
|
||||
}).AddCookie();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
@ -19,9 +19,7 @@ namespace CookieSessionSample
|
|||
{
|
||||
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication(o => o.SessionStore = new MemoryCacheTicketStore());
|
||||
}).AddCookie(o => o.SessionStore = new MemoryCacheTicketStore());
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
@ -48,9 +48,7 @@ namespace JwtBearerSample
|
|||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
services.AddJwtBearerAuthentication(o =>
|
||||
}).AddJwtBearer(o =>
|
||||
{
|
||||
// You also need to update /wwwroot/app/scripts/app.js
|
||||
o.Authority = Configuration["jwt:authority"];
|
||||
|
@ -59,7 +57,7 @@ namespace JwtBearerSample
|
|||
{
|
||||
OnAuthenticationFailed = c =>
|
||||
{
|
||||
c.HandleResponse();
|
||||
c.NoResult();
|
||||
|
||||
c.Response.StatusCode = 500;
|
||||
c.Response.ContentType = "text/plain";
|
||||
|
|
|
@ -48,11 +48,9 @@ namespace OpenIdConnect.AzureAdSample
|
|||
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication();
|
||||
|
||||
services.AddOpenIdConnectAuthentication(o =>
|
||||
})
|
||||
.AddCookie()
|
||||
.AddOpenIdConnect(o =>
|
||||
{
|
||||
o.ClientId = ClientId;
|
||||
o.ClientSecret = ClientSecret; // for code flow
|
||||
|
|
|
@ -45,11 +45,9 @@ namespace OpenIdConnectSample
|
|||
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication();
|
||||
|
||||
services.AddOpenIdConnectAuthentication(o =>
|
||||
})
|
||||
.AddCookie()
|
||||
.AddOpenIdConnect(o =>
|
||||
{
|
||||
o.ClientId = Configuration["oidc:clientid"];
|
||||
o.ClientSecret = Configuration["oidc:clientsecret"]; // for code flow
|
||||
|
|
|
@ -55,13 +55,11 @@ namespace SocialSample
|
|||
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication(o => o.LoginPath = new PathString("/login"));
|
||||
|
||||
})
|
||||
.AddCookie(o => o.LoginPath = new PathString("/login"))
|
||||
// You must first create an app with Facebook and add its ID and Secret to your user-secrets.
|
||||
// https://developers.facebook.com/apps/
|
||||
services.AddFacebookAuthentication(o =>
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = Configuration["facebook:appid"];
|
||||
o.AppSecret = Configuration["facebook:appsecret"];
|
||||
|
@ -69,11 +67,10 @@ namespace SocialSample
|
|||
o.Fields.Add("name");
|
||||
o.Fields.Add("email");
|
||||
o.SaveTokens = true;
|
||||
});
|
||||
|
||||
})
|
||||
// You must first create an app with Google and add its ID and Secret to your user-secrets.
|
||||
// https://console.developers.google.com/project
|
||||
services.AddOAuthAuthentication("Google-AccessToken", o =>
|
||||
.AddOAuth("Google-AccessToken", o =>
|
||||
{
|
||||
o.ClientId = Configuration["google:clientid"];
|
||||
o.ClientSecret = Configuration["google:clientsecret"];
|
||||
|
@ -84,11 +81,10 @@ namespace SocialSample
|
|||
o.Scope.Add("profile");
|
||||
o.Scope.Add("email");
|
||||
o.SaveTokens = true;
|
||||
});
|
||||
|
||||
})
|
||||
// You must first create an app with Google and add its ID and Secret to your user-secrets.
|
||||
// https://console.developers.google.com/project
|
||||
services.AddGoogleAuthentication(o =>
|
||||
.AddGoogle(o =>
|
||||
{
|
||||
o.ClientId = Configuration["google:clientid"];
|
||||
o.ClientSecret = Configuration["google:clientsecret"];
|
||||
|
@ -104,11 +100,10 @@ namespace SocialSample
|
|||
};
|
||||
o.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url");
|
||||
o.ClaimActions.Remove(ClaimTypes.GivenName);
|
||||
});
|
||||
|
||||
})
|
||||
// You must first create an app with Twitter and add its key and Secret to your user-secrets.
|
||||
// https://apps.twitter.com/
|
||||
services.AddTwitterAuthentication(o =>
|
||||
.AddTwitter(o =>
|
||||
{
|
||||
o.ConsumerKey = Configuration["twitter:consumerkey"];
|
||||
o.ConsumerSecret = Configuration["twitter:consumersecret"];
|
||||
|
@ -126,15 +121,14 @@ namespace SocialSample
|
|||
return Task.FromResult(0);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
})
|
||||
/* Azure AD app model v2 has restrictions that prevent the use of plain HTTP for redirect URLs.
|
||||
Therefore, to authenticate through microsoft accounts, tryout the sample using the following URL:
|
||||
https://localhost:44318/
|
||||
*/
|
||||
// You must first create an app with Microsoft Account and add its ID and Secret to your user-secrets.
|
||||
// https://apps.dev.microsoft.com/
|
||||
services.AddOAuthAuthentication("Microsoft-AccessToken", o =>
|
||||
.AddOAuth("Microsoft-AccessToken", o =>
|
||||
{
|
||||
o.ClientId = Configuration["microsoftaccount:clientid"];
|
||||
o.ClientSecret = Configuration["microsoftaccount:clientsecret"];
|
||||
|
@ -143,20 +137,18 @@ namespace SocialSample
|
|||
o.TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint;
|
||||
o.Scope.Add("https://graph.microsoft.com/user.read");
|
||||
o.SaveTokens = true;
|
||||
});
|
||||
|
||||
})
|
||||
// You must first create an app with Microsoft Account and add its ID and Secret to your user-secrets.
|
||||
// https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-app-registration/
|
||||
services.AddMicrosoftAccountAuthentication(o =>
|
||||
.AddMicrosoftAccount(o =>
|
||||
{
|
||||
o.ClientId = Configuration["microsoftaccount:clientid"];
|
||||
o.ClientSecret = Configuration["microsoftaccount:clientsecret"];
|
||||
o.SaveTokens = true;
|
||||
});
|
||||
|
||||
})
|
||||
// You must first create an app with GitHub and add its ID and Secret to your user-secrets.
|
||||
// https://github.com/settings/applications/
|
||||
services.AddOAuthAuthentication("GitHub-AccessToken", o =>
|
||||
.AddOAuth("GitHub-AccessToken", o =>
|
||||
{
|
||||
o.ClientId = Configuration["github-token:clientid"];
|
||||
o.ClientSecret = Configuration["github-token:clientsecret"];
|
||||
|
@ -164,11 +156,10 @@ namespace SocialSample
|
|||
o.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
|
||||
o.TokenEndpoint = "https://github.com/login/oauth/access_token";
|
||||
o.SaveTokens = true;
|
||||
});
|
||||
|
||||
})
|
||||
// You must first create an app with GitHub and add its ID and Secret to your user-secrets.
|
||||
// https://github.com/settings/applications/
|
||||
services.AddOAuthAuthentication("GitHub", o =>
|
||||
.AddOAuth("GitHub", o =>
|
||||
{
|
||||
o.ClientId = Configuration["github:clientid"];
|
||||
o.ClientSecret = Configuration["github:clientsecret"];
|
||||
|
|
|
@ -14,7 +14,10 @@ using Microsoft.Net.Http.Headers;
|
|||
|
||||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
public class CookieAuthenticationHandler : AuthenticationHandler<CookieAuthenticationOptions>
|
||||
public class CookieAuthenticationHandler :
|
||||
AuthenticationHandler<CookieAuthenticationOptions>,
|
||||
IAuthenticationSignInHandler,
|
||||
IAuthenticationSignOutHandler
|
||||
{
|
||||
private const string HeaderValueNoCache = "no-cache";
|
||||
private const string HeaderValueMinusOne = "-1";
|
||||
|
@ -104,7 +107,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
var cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName);
|
||||
if (string.IsNullOrEmpty(cookie))
|
||||
{
|
||||
return AuthenticateResult.None();
|
||||
return AuthenticateResult.NoResult();
|
||||
}
|
||||
|
||||
var ticket = Options.TicketDataFormat.Unprotect(cookie, GetTlsTokenBinding());
|
||||
|
@ -155,7 +158,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
return result;
|
||||
}
|
||||
|
||||
var context = new CookieValidatePrincipalContext(Context, Scheme, result.Ticket, Options);
|
||||
var context = new CookieValidatePrincipalContext(Context, Scheme, Options, result.Ticket);
|
||||
await Events.ValidatePrincipal(context);
|
||||
|
||||
if (context.Principal == null)
|
||||
|
@ -244,8 +247,15 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
}
|
||||
|
||||
protected override async Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
public async virtual Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
properties = properties ?? new AuthenticationProperties();
|
||||
|
||||
_signInCalled = true;
|
||||
|
||||
// Process the request cookie to initialize members like _sessionKey.
|
||||
|
@ -284,7 +294,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime();
|
||||
}
|
||||
|
||||
var ticket = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.AuthenticationScheme);
|
||||
var ticket = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.Scheme.Name);
|
||||
|
||||
if (Options.SessionStore != null)
|
||||
{
|
||||
if (_sessionKey != null)
|
||||
|
@ -310,20 +321,23 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
var signedInContext = new CookieSignedInContext(
|
||||
Context,
|
||||
Scheme,
|
||||
Options,
|
||||
Scheme.Name,
|
||||
signInContext.Principal,
|
||||
signInContext.Properties);
|
||||
signInContext.Properties,
|
||||
Options);
|
||||
|
||||
await Events.SignedIn(signedInContext);
|
||||
|
||||
// Only redirect on the login path
|
||||
var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath;
|
||||
await ApplyHeaders(shouldRedirect, signedInContext.Properties);
|
||||
|
||||
Logger.SignedIn(Scheme.Name);
|
||||
}
|
||||
|
||||
protected override async Task HandleSignOutAsync(AuthenticationProperties properties)
|
||||
public async virtual Task SignOutAsync(AuthenticationProperties properties)
|
||||
{
|
||||
properties = properties ?? new AuthenticationProperties();
|
||||
|
||||
_signOutCalled = true;
|
||||
|
||||
// Process the request cookie to initialize members like _sessionKey.
|
||||
|
@ -351,6 +365,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
// Only redirect on the logout path
|
||||
var shouldRedirect = Options.LogoutPath.HasValue && OriginalPath == Options.LogoutPath;
|
||||
await ApplyHeaders(shouldRedirect, context.Properties);
|
||||
|
||||
Logger.SignedOut(Scheme.Name);
|
||||
}
|
||||
|
||||
private async Task ApplyHeaders(bool shouldRedirectToReturnUrl, AuthenticationProperties properties)
|
||||
|
@ -380,7 +396,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
if (redirectUri != null)
|
||||
{
|
||||
await Events.RedirectToReturnUrl(
|
||||
new CookieRedirectContext(Context, Scheme, Options, redirectUri, properties));
|
||||
new RedirectContext<CookieAuthenticationOptions>(Context, Scheme, Options, properties, redirectUri));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +422,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
returnUrl = OriginalPathBase + Request.Path + Request.QueryString;
|
||||
}
|
||||
var accessDeniedUri = Options.AccessDeniedPath + QueryString.Create(Options.ReturnUrlParameter, returnUrl);
|
||||
var redirectContext = new CookieRedirectContext(Context, Scheme, Options, BuildRedirectUri(accessDeniedUri), properties);
|
||||
var redirectContext = new RedirectContext<CookieAuthenticationOptions>(Context, Scheme, Options, properties, BuildRedirectUri(accessDeniedUri));
|
||||
await Events.RedirectToAccessDenied(redirectContext);
|
||||
}
|
||||
|
||||
|
@ -419,7 +435,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
|
||||
var loginUri = Options.LoginPath + QueryString.Create(Options.ReturnUrlParameter, redirectUri);
|
||||
var redirectContext = new CookieRedirectContext(Context, Scheme, Options, BuildRedirectUri(loginUri), properties);
|
||||
var redirectContext = new RedirectContext<CookieAuthenticationOptions>(Context, Scheme, Options, properties, BuildRedirectUri(loginUri));
|
||||
await Events.RedirectToLogin(redirectContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,16 +2,32 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class CookieExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder)
|
||||
=> builder.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme)
|
||||
=> builder.AddCookie(authenticationScheme, configureOptions: null);
|
||||
|
||||
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, Action<CookieAuthenticationOptions> configureOptions)
|
||||
=> builder.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, Action<CookieAuthenticationOptions> configureOptions)
|
||||
{
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
|
||||
return builder.AddScheme<CookieAuthenticationOptions, CookieAuthenticationHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
|
||||
|
||||
// REMOVE below once callers have been updated
|
||||
public static IServiceCollection AddCookieAuthentication(this IServiceCollection services) => services.AddCookieAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
public static IServiceCollection AddCookieAuthentication(this IServiceCollection services, string authenticationScheme) => services.AddCookieAuthentication(authenticationScheme, configureOptions: null);
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. 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.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
public class BaseCookieContext : BaseAuthenticationContext
|
||||
{
|
||||
public BaseCookieContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
CookieAuthenticationOptions options,
|
||||
AuthenticationProperties properties)
|
||||
: base(context, scheme.Name, properties)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
Options = options;
|
||||
}
|
||||
|
||||
public CookieAuthenticationOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <summary>
|
||||
/// A delegate assigned to this property will be invoked when the related method is called.
|
||||
/// </summary>
|
||||
public Func<CookieRedirectContext, Task> OnRedirectToLogin { get; set; } = context =>
|
||||
public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToLogin { get; set; } = context =>
|
||||
{
|
||||
if (IsAjaxRequest(context.Request))
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <summary>
|
||||
/// A delegate assigned to this property will be invoked when the related method is called.
|
||||
/// </summary>
|
||||
public Func<CookieRedirectContext, Task> OnRedirectToAccessDenied { get; set; } = context =>
|
||||
public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToAccessDenied { get; set; } = context =>
|
||||
{
|
||||
if (IsAjaxRequest(context.Request))
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <summary>
|
||||
/// A delegate assigned to this property will be invoked when the related method is called.
|
||||
/// </summary>
|
||||
public Func<CookieRedirectContext, Task> OnRedirectToLogout { get; set; } = context =>
|
||||
public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToLogout { get; set; } = context =>
|
||||
{
|
||||
if (IsAjaxRequest(context.Request))
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <summary>
|
||||
/// A delegate assigned to this property will be invoked when the related method is called.
|
||||
/// </summary>
|
||||
public Func<CookieRedirectContext, Task> OnRedirectToReturnUrl { get; set; } = context =>
|
||||
public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToReturnUrl { get; set; } = context =>
|
||||
{
|
||||
if (IsAjaxRequest(context.Request))
|
||||
{
|
||||
|
@ -135,24 +135,24 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// Implements the interface method by invoking the related delegate method.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
public virtual Task RedirectToLogout(CookieRedirectContext context) => OnRedirectToLogout(context);
|
||||
public virtual Task RedirectToLogout(RedirectContext<CookieAuthenticationOptions> context) => OnRedirectToLogout(context);
|
||||
|
||||
/// <summary>
|
||||
/// Implements the interface method by invoking the related delegate method.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
public virtual Task RedirectToLogin(CookieRedirectContext context) => OnRedirectToLogin(context);
|
||||
public virtual Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> context) => OnRedirectToLogin(context);
|
||||
|
||||
/// <summary>
|
||||
/// Implements the interface method by invoking the related delegate method.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
public virtual Task RedirectToReturnUrl(CookieRedirectContext context) => OnRedirectToReturnUrl(context);
|
||||
public virtual Task RedirectToReturnUrl(RedirectContext<CookieAuthenticationOptions> context) => OnRedirectToReturnUrl(context);
|
||||
|
||||
/// <summary>
|
||||
/// Implements the interface method by invoking the related delegate method.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
public virtual Task RedirectToAccessDenied(CookieRedirectContext context) => OnRedirectToAccessDenied(context);
|
||||
public virtual Task RedirectToAccessDenied(RedirectContext<CookieAuthenticationOptions> context) => OnRedirectToAccessDenied(context);
|
||||
}
|
||||
}
|
|
@ -9,32 +9,25 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <summary>
|
||||
/// Context object passed to the ICookieAuthenticationEvents method SignedIn.
|
||||
/// </summary>
|
||||
public class CookieSignedInContext : BaseCookieContext
|
||||
public class CookieSignedInContext : PrincipalContext<CookieAuthenticationOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The handler options</param>
|
||||
/// <param name="authenticationScheme">Initializes AuthenticationScheme property</param>
|
||||
/// <param name="principal">Initializes Principal property</param>
|
||||
/// <param name="properties">Initializes Properties property</param>
|
||||
/// <param name="options">The handler options</param>
|
||||
public CookieSignedInContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
CookieAuthenticationOptions options,
|
||||
string authenticationScheme,
|
||||
ClaimsPrincipal principal,
|
||||
AuthenticationProperties properties)
|
||||
AuthenticationProperties properties,
|
||||
CookieAuthenticationOptions options)
|
||||
: base(context, scheme, options, properties)
|
||||
{
|
||||
Principal = principal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the claims that were converted into the outgoing cookie.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ using Microsoft.AspNetCore.Http;
|
|||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
/// <summary>
|
||||
/// Context object passed to the ICookieAuthenticationEvents method SigningIn.
|
||||
/// Context object passed to the <see cref="CookieAuthenticationEvents.SigningIn(CookieSigningInContext)"/>.
|
||||
/// </summary>
|
||||
public class CookieSigningInContext : BaseCookieContext
|
||||
public class CookieSigningInContext : PrincipalContext<CookieAuthenticationOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the context object.
|
||||
|
@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The handler options</param>
|
||||
/// <param name="principal">Initializes Principal property</param>
|
||||
/// <param name="properties">Initializes Extra property</param>
|
||||
/// <param name="properties">The authentication properties.</param>
|
||||
/// <param name="cookieOptions">Initializes options for the authentication cookie.</param>
|
||||
public CookieSigningInContext(
|
||||
HttpContext context,
|
||||
|
@ -29,16 +29,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
CookieOptions cookieOptions)
|
||||
: base(context, scheme, options, properties)
|
||||
{
|
||||
Principal = principal;
|
||||
CookieOptions = cookieOptions;
|
||||
Principal = principal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the claims about to be converted into the outgoing cookie.
|
||||
/// May be replaced or altered during the SigningIn call.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The options for creating the outgoing cookie.
|
||||
/// May be replace or altered during the SigningIn call.
|
||||
|
|
|
@ -6,9 +6,9 @@ using Microsoft.AspNetCore.Http;
|
|||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
/// <summary>
|
||||
/// Context object passed to the ICookieAuthenticationEvents method SigningOut
|
||||
/// Context object passed to the <see cref="CookieAuthenticationEvents.SigningOut(CookieSigningOutContext)"/>
|
||||
/// </summary>
|
||||
public class CookieSigningOutContext : BaseCookieContext
|
||||
public class CookieSigningOutContext : PropertiesContext<CookieAuthenticationOptions>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -25,9 +25,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
AuthenticationProperties properties,
|
||||
CookieOptions cookieOptions)
|
||||
: base(context, scheme, options, properties)
|
||||
{
|
||||
CookieOptions = cookieOptions;
|
||||
}
|
||||
=> CookieOptions = cookieOptions;
|
||||
|
||||
/// <summary>
|
||||
/// The options for creating the outgoing cookie.
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <summary>
|
||||
/// Context object passed to the CookieAuthenticationEvents ValidatePrincipal method.
|
||||
/// </summary>
|
||||
public class CookieValidatePrincipalContext : BaseCookieContext
|
||||
public class CookieValidatePrincipalContext : PrincipalContext<CookieAuthenticationOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the context object.
|
||||
|
@ -19,33 +19,17 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// <param name="scheme"></param>
|
||||
/// <param name="ticket">Contains the initial values for identity and extra data</param>
|
||||
/// <param name="options"></param>
|
||||
public CookieValidatePrincipalContext(HttpContext context, AuthenticationScheme scheme, AuthenticationTicket ticket, CookieAuthenticationOptions options)
|
||||
public CookieValidatePrincipalContext(HttpContext context, AuthenticationScheme scheme, CookieAuthenticationOptions options, AuthenticationTicket ticket)
|
||||
: base(context, scheme, options, ticket?.Properties)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (ticket == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ticket));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
Principal = ticket.Principal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the claims principal arriving with the request. May be altered to change the
|
||||
/// details of the authenticated user.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the cookie will be renewed
|
||||
/// </summary>
|
||||
|
@ -56,18 +40,12 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// Principal property, which determines the identity of the authenticated request.
|
||||
/// </summary>
|
||||
/// <param name="principal">The <see cref="ClaimsPrincipal"/> used as the replacement</param>
|
||||
public void ReplacePrincipal(ClaimsPrincipal principal)
|
||||
{
|
||||
Principal = principal;
|
||||
}
|
||||
public void ReplacePrincipal(ClaimsPrincipal principal) => Principal = principal;
|
||||
|
||||
/// <summary>
|
||||
/// Called to reject the incoming principal. This may be done if the application has determined the
|
||||
/// account is no longer active, and the request should be treated as if it was anonymous.
|
||||
/// </summary>
|
||||
public void RejectPrincipal()
|
||||
{
|
||||
Principal = null;
|
||||
}
|
||||
public void RejectPrincipal() => Principal = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) .NET Foundation. 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.Extensions.Logging
|
||||
{
|
||||
internal static class LoggingExtensions
|
||||
{
|
||||
private static Action<ILogger, string, Exception> _authSchemeSignedIn;
|
||||
private static Action<ILogger, string, Exception> _authSchemeSignedOut;
|
||||
|
||||
static LoggingExtensions()
|
||||
{
|
||||
_authSchemeSignedIn = LoggerMessage.Define<string>(
|
||||
eventId: 10,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "AuthenticationScheme: {AuthenticationScheme} signed in.");
|
||||
_authSchemeSignedOut = LoggerMessage.Define<string>(
|
||||
eventId: 11,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "AuthenticationScheme: {AuthenticationScheme} signed out.");
|
||||
}
|
||||
|
||||
public static void SignedIn(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_authSchemeSignedIn(logger, authenticationScheme, null);
|
||||
}
|
||||
|
||||
public static void SignedOut(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_authSchemeSignedOut(logger, authenticationScheme, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,6 +55,5 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
options.AccessDeniedPath = CookieAuthenticationDefaults.AccessDeniedPath;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -19,69 +19,29 @@
|
|||
"TypeId": "public interface Microsoft.AspNetCore.Authentication.Cookies.ICookieAuthenticationEvents",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationTicket ticket, Microsoft.AspNetCore.Builder.CookieAuthenticationOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningOutContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.CookieAuthenticationOptions options, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties, Microsoft.AspNetCore.Http.CookieOptions cookieOptions)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningOutContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningOutContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSignedInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.CookieAuthenticationOptions options, System.String authenticationScheme, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSignedInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.CookieAuthenticationOptions options, System.String authenticationScheme, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties, Microsoft.AspNetCore.Http.CookieOptions cookieOptions)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieRedirectContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.CookieAuthenticationOptions options, System.String redirectUri, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieRedirectContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.AspNetCore.Builder.CookieAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseCookieAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.CookieAuthenticationOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieRedirectContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSignedInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningInContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieSigningOutContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext : Microsoft.AspNetCore.Authentication.Cookies.BaseCookieContext",
|
||||
"Kind": "Removal"
|
||||
}
|
||||
]
|
|
@ -2,12 +2,24 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Facebook;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class FacebookAuthenticationOptionsExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddFacebook(this AuthenticationBuilder builder)
|
||||
=> builder.AddFacebook(FacebookDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
public static AuthenticationBuilder AddFacebook(this AuthenticationBuilder builder, Action<FacebookOptions> configureOptions)
|
||||
=> builder.AddFacebook(FacebookDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddFacebook(this AuthenticationBuilder builder, string authenticationScheme, Action<FacebookOptions> configureOptions)
|
||||
=> builder.AddOAuth<FacebookOptions, FacebookHandler>(authenticationScheme, configureOptions);
|
||||
|
||||
|
||||
// REMOVE below once callers have been updated
|
||||
public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services)
|
||||
=> services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
|
|
|
@ -42,13 +42,13 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name);
|
||||
var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens, payload);
|
||||
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload);
|
||||
context.RunClaimActions();
|
||||
|
||||
await Events.CreatingTicket(context);
|
||||
|
||||
return context.Ticket;
|
||||
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
|
||||
|
||||
}
|
||||
|
||||
private string GenerateAppSecretProof(string accessToken)
|
||||
|
|
|
@ -2,12 +2,25 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Google;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class GoogleExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddGoogle(this AuthenticationBuilder builder)
|
||||
=> builder.AddGoogle(GoogleDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
public static AuthenticationBuilder AddGoogle(this AuthenticationBuilder builder, Action<GoogleOptions> configureOptions)
|
||||
=> builder.AddGoogle(GoogleDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddGoogle(this AuthenticationBuilder builder, string authenticationScheme, Action<GoogleOptions> configureOptions)
|
||||
=> builder.AddOAuth<GoogleOptions, GoogleHandler>(authenticationScheme, configureOptions);
|
||||
|
||||
|
||||
// REMOVE below once callers have been updated
|
||||
|
||||
public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services)
|
||||
=> services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
|
|
|
@ -39,14 +39,11 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
|
||||
var principal = new ClaimsPrincipal(identity);
|
||||
var ticket = new AuthenticationTicket(principal, properties, Scheme.Name);
|
||||
var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens, payload);
|
||||
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload);
|
||||
context.RunClaimActions();
|
||||
|
||||
await Events.CreatingTicket(context);
|
||||
|
||||
return context.Ticket;
|
||||
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
|
||||
}
|
||||
|
||||
// TODO: Abstract this properties override pattern into the base class?
|
||||
|
|
|
@ -6,12 +6,13 @@ using Microsoft.AspNetCore.Http;
|
|||
|
||||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
public class AuthenticationFailedContext : BaseJwtBearerContext
|
||||
public class AuthenticationFailedContext : ResultContext<JwtBearerOptions>
|
||||
{
|
||||
public AuthenticationFailedContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public AuthenticationFailedContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
JwtBearerOptions options)
|
||||
: base(context, scheme, options) { }
|
||||
|
||||
public Exception Exception { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. 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.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
public class BaseJwtBearerContext : BaseControlContext
|
||||
{
|
||||
public BaseJwtBearerContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
|
||||
: base(context)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (scheme == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(scheme));
|
||||
}
|
||||
|
||||
Options = options;
|
||||
Scheme = scheme;
|
||||
}
|
||||
|
||||
public JwtBearerOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
}
|
||||
}
|
|
@ -6,15 +6,14 @@ using Microsoft.AspNetCore.Http;
|
|||
|
||||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
public class JwtBearerChallengeContext : BaseJwtBearerContext
|
||||
public class JwtBearerChallengeContext : PropertiesContext<JwtBearerOptions>
|
||||
{
|
||||
public JwtBearerChallengeContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options, AuthenticationProperties properties)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
Properties = properties;
|
||||
}
|
||||
|
||||
public AuthenticationProperties Properties { get; }
|
||||
public JwtBearerChallengeContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
JwtBearerOptions options,
|
||||
AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties) { }
|
||||
|
||||
/// <summary>
|
||||
/// Any failures encountered during the authentication process.
|
||||
|
@ -40,5 +39,15 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
/// WWW-Authenticate header. This property is always null unless explicitly set.
|
||||
/// </summary>
|
||||
public string ErrorUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, will skip any default logic for this challenge.
|
||||
/// </summary>
|
||||
public bool Handled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skips any default logic for this challenge.
|
||||
/// </summary>
|
||||
public void HandleResponse() => Handled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,13 @@ using Microsoft.AspNetCore.Http;
|
|||
|
||||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
public class MessageReceivedContext : BaseJwtBearerContext
|
||||
public class MessageReceivedContext : ResultContext<JwtBearerOptions>
|
||||
{
|
||||
public MessageReceivedContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public MessageReceivedContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
JwtBearerOptions options)
|
||||
: base(context, scheme, options) { }
|
||||
|
||||
/// <summary>
|
||||
/// Bearer Token. This will give application an opportunity to retrieve token from an alternation location.
|
||||
|
|
|
@ -6,12 +6,13 @@ using Microsoft.IdentityModel.Tokens;
|
|||
|
||||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
public class TokenValidatedContext : BaseJwtBearerContext
|
||||
public class TokenValidatedContext : ResultContext<JwtBearerOptions>
|
||||
{
|
||||
public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public TokenValidatedContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
JwtBearerOptions options)
|
||||
: base(context, scheme, options) { }
|
||||
|
||||
public SecurityToken SecurityToken { get; set; }
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -10,6 +11,20 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
public static class JwtBearerExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder)
|
||||
=> builder.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, Action<JwtBearerOptions> configureOptions)
|
||||
=> builder.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, string authenticationScheme, Action<JwtBearerOptions> configureOptions)
|
||||
{
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>, JwtBearerPostConfigureOptions>());
|
||||
return builder.AddScheme<JwtBearerOptions, JwtBearerHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
|
||||
|
||||
// REMOVE once callers updated
|
||||
public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services)
|
||||
=> services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
|
@ -13,7 +12,6 @@ using Microsoft.AspNetCore.DataProtection;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Protocols;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
@ -47,7 +45,6 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
string token = null;
|
||||
AuthenticateResult result = null;
|
||||
try
|
||||
{
|
||||
// Give application opportunity to find from a different location, adjust, or reject token
|
||||
|
@ -55,9 +52,9 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
// event can set the token
|
||||
await Events.MessageReceived(messageReceivedContext);
|
||||
if (messageReceivedContext.IsProcessingComplete(out result))
|
||||
if (messageReceivedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return messageReceivedContext.Result;
|
||||
}
|
||||
|
||||
// If application retrieved token from somewhere else, use that.
|
||||
|
@ -70,7 +67,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
// If no authorization header found, nothing to process further
|
||||
if (string.IsNullOrEmpty(authorization))
|
||||
{
|
||||
return AuthenticateResult.None();
|
||||
return AuthenticateResult.NoResult();
|
||||
}
|
||||
|
||||
if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
|
||||
|
@ -81,7 +78,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
// If no token found, no further work possible
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return AuthenticateResult.None();
|
||||
return AuthenticateResult.NoResult();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,29 +135,28 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
Logger.TokenValidationSucceeded();
|
||||
|
||||
var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name);
|
||||
var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options)
|
||||
{
|
||||
Ticket = ticket,
|
||||
SecurityToken = validatedToken,
|
||||
Principal = principal,
|
||||
SecurityToken = validatedToken
|
||||
};
|
||||
|
||||
await Events.TokenValidated(tokenValidatedContext);
|
||||
if (tokenValidatedContext.IsProcessingComplete(out result))
|
||||
if (tokenValidatedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return tokenValidatedContext.Result;
|
||||
}
|
||||
ticket = tokenValidatedContext.Ticket;
|
||||
|
||||
if (Options.SaveToken)
|
||||
{
|
||||
ticket.Properties.StoreTokens(new[]
|
||||
tokenValidatedContext.Properties.StoreTokens(new[]
|
||||
{
|
||||
new AuthenticationToken { Name = "access_token", Value = token }
|
||||
});
|
||||
}
|
||||
|
||||
return AuthenticateResult.Success(ticket);
|
||||
tokenValidatedContext.Success();
|
||||
return tokenValidatedContext.Result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,9 +168,9 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
};
|
||||
|
||||
await Events.AuthenticationFailed(authenticationFailedContext);
|
||||
if (authenticationFailedContext.IsProcessingComplete(out result))
|
||||
if (authenticationFailedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return authenticationFailedContext.Result;
|
||||
}
|
||||
|
||||
return AuthenticateResult.Fail(authenticationFailedContext.Exception);
|
||||
|
@ -192,9 +188,9 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
};
|
||||
|
||||
await Events.AuthenticationFailed(authenticationFailedContext);
|
||||
if (authenticationFailedContext.IsProcessingComplete(out result))
|
||||
if (authenticationFailedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return authenticationFailedContext.Result;
|
||||
}
|
||||
|
||||
throw;
|
||||
|
@ -217,7 +213,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
|
||||
await Events.Challenge(eventContext);
|
||||
if (eventContext.IsProcessingComplete(out var ignored))
|
||||
if (eventContext.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -329,15 +325,5 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
return string.Join("; ", messages);
|
||||
}
|
||||
|
||||
protected override Task HandleSignOutAsync(AuthenticationProperties properties)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
protected override Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,44 +15,29 @@
|
|||
"TypeId": "public interface Microsoft.AspNetCore.Authentication.JwtBearer.IJwtBearerEvents",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.AspNetCore.Builder.JwtBearerAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseJwtBearerAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.JwtBearerOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.AuthenticationFailedContext : Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.JwtBearerOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.JwtBearerOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Builder.JwtBearerOptions get_Options()",
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerChallengeContext : Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.MessageReceivedContext : Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.JwtBearerOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.TokenValidatedContext : Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.JwtBearerOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerChallengeContext : Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.JwtBearerOptions options, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerChallengeContext : Microsoft.AspNetCore.Authentication.JwtBearer.BaseJwtBearerContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.AspNetCore.Builder.JwtBearerAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseJwtBearerAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.JwtBearerOptions options)",
|
||||
"Kind": "Removal"
|
||||
}
|
||||
]
|
|
@ -2,12 +2,25 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class MicrosoftAccountExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddMicrosoftAccount(this AuthenticationBuilder builder)
|
||||
=> builder.AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
public static AuthenticationBuilder AddMicrosoftAccount(this AuthenticationBuilder builder, Action<MicrosoftAccountOptions> configureOptions)
|
||||
=> builder.AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddMicrosoftAccount(this AuthenticationBuilder builder, string authenticationScheme, Action<MicrosoftAccountOptions> configureOptions)
|
||||
=> builder.AddOAuth<MicrosoftAccountOptions, MicrosoftAccountHandler>(authenticationScheme, configureOptions);
|
||||
|
||||
|
||||
// REMOVE below once callers have been updated
|
||||
|
||||
public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services)
|
||||
=> services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
|
|
|
@ -32,12 +32,11 @@ namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
|
|||
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name);
|
||||
var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens, payload);
|
||||
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload);
|
||||
context.RunClaimActions();
|
||||
|
||||
await Events.CreatingTicket(context);
|
||||
return context.Ticket;
|
||||
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,32 +13,34 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
/// <summary>
|
||||
/// Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.
|
||||
/// </summary>
|
||||
public class OAuthCreatingTicketContext : BaseAuthenticationContext
|
||||
public class OAuthCreatingTicketContext : ResultContext<OAuthOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
|
||||
/// </summary>
|
||||
/// <param name="ticket">The <see cref="AuthenticationTicket"/>.</param>
|
||||
/// <param name="principal">The <see cref="ClaimsPrincipal"/>.</param>
|
||||
/// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
|
||||
/// <param name="context">The HTTP environment.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The options used by the authentication middleware.</param>
|
||||
/// <param name="backchannel">The HTTP client used by the authentication middleware</param>
|
||||
/// <param name="tokens">The tokens returned from the token endpoint.</param>
|
||||
public OAuthCreatingTicketContext(
|
||||
AuthenticationTicket ticket,
|
||||
ClaimsPrincipal principal,
|
||||
AuthenticationProperties properties,
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OAuthOptions options,
|
||||
HttpClient backchannel,
|
||||
OAuthTokenResponse tokens)
|
||||
: this(ticket, context, scheme, options, backchannel, tokens, user: new JObject())
|
||||
{
|
||||
}
|
||||
: this(principal, properties, context, scheme, options, backchannel, tokens, user: new JObject())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
|
||||
/// </summary>
|
||||
/// <param name="ticket">The <see cref="AuthenticationTicket"/>.</param>
|
||||
/// <param name="principal">The <see cref="ClaimsPrincipal"/>.</param>
|
||||
/// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
|
||||
/// <param name="context">The HTTP environment.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The options used by the authentication middleware.</param>
|
||||
|
@ -46,25 +48,16 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
/// <param name="tokens">The tokens returned from the token endpoint.</param>
|
||||
/// <param name="user">The JSON-serialized user.</param>
|
||||
public OAuthCreatingTicketContext(
|
||||
AuthenticationTicket ticket,
|
||||
ClaimsPrincipal principal,
|
||||
AuthenticationProperties properties,
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OAuthOptions options,
|
||||
HttpClient backchannel,
|
||||
OAuthTokenResponse tokens,
|
||||
JObject user)
|
||||
: base(context, scheme.Name, ticket.Properties)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (backchannel == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(backchannel));
|
||||
|
@ -80,23 +73,13 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if (scheme == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(scheme));
|
||||
}
|
||||
|
||||
TokenResponse = tokens;
|
||||
Backchannel = backchannel;
|
||||
User = user;
|
||||
Options = options;
|
||||
Scheme = scheme;
|
||||
Ticket = ticket;
|
||||
Principal = principal;
|
||||
Properties = properties;
|
||||
}
|
||||
|
||||
public OAuthOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the JSON-serialized user or an empty
|
||||
/// <see cref="JObject"/> if it is not available.
|
||||
|
@ -146,20 +129,12 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
public HttpClient Backchannel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="AuthenticationTicket"/> that will be created.
|
||||
/// Gets the main identity exposed by the authentication ticket.
|
||||
/// This property returns <c>null</c> when the ticket is <c>null</c>.
|
||||
/// </summary>
|
||||
public AuthenticationTicket Ticket { get; set; }
|
||||
public ClaimsIdentity Identity => Principal?.Identity as ClaimsIdentity;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the main identity exposed by <see cref="Ticket"/>.
|
||||
/// This property returns <c>null</c> when <see cref="Ticket"/> is <c>null</c>.
|
||||
/// </summary>
|
||||
public ClaimsIdentity Identity => Ticket?.Principal.Identity as ClaimsIdentity;
|
||||
|
||||
public void RunClaimActions()
|
||||
{
|
||||
RunClaimActions(User);
|
||||
}
|
||||
public void RunClaimActions() => RunClaimActions(User);
|
||||
|
||||
public void RunClaimActions(JObject userData)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
/// <summary>
|
||||
/// Gets or sets the delegate that is invoked when the RedirectToAuthorizationEndpoint method is invoked.
|
||||
/// </summary>
|
||||
public Func<OAuthRedirectToAuthorizationContext, Task> OnRedirectToAuthorizationEndpoint { get; set; } = context =>
|
||||
public Func<RedirectContext<OAuthOptions>, Task> OnRedirectToAuthorizationEndpoint { get; set; } = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri);
|
||||
return Task.CompletedTask;
|
||||
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
/// <summary>
|
||||
/// Called when a Challenge causes a redirect to authorize endpoint in the OAuth handler.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains redirect URI and <see cref="Http.Authentication.AuthenticationProperties"/> of the challenge.</param>
|
||||
public virtual Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationContext context) => OnRedirectToAuthorizationEndpoint(context);
|
||||
/// <param name="context">Contains redirect URI and <see cref="AuthenticationProperties"/> of the challenge.</param>
|
||||
public virtual Task RedirectToAuthorizationEndpoint(RedirectContext<OAuthOptions> context) => OnRedirectToAuthorizationEndpoint(context);
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// Context passed when a Challenge causes a redirect to authorize endpoint in the handler.
|
||||
/// </summary>
|
||||
public class OAuthRedirectToAuthorizationContext : BaseContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context.</param>
|
||||
/// <param name="options">The <see cref="OAuthOptions"/>.</param>
|
||||
/// <param name="properties">The authentication properties of the challenge.</param>
|
||||
/// <param name="redirectUri">The initial redirect URI.</param>
|
||||
public OAuthRedirectToAuthorizationContext(HttpContext context, OAuthOptions options, AuthenticationProperties properties, string redirectUri)
|
||||
: base(context)
|
||||
{
|
||||
RedirectUri = redirectUri;
|
||||
Properties = properties;
|
||||
Options = options;
|
||||
}
|
||||
|
||||
public OAuthOptions Options { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URI used for the redirect operation.
|
||||
/// </summary>
|
||||
public string RedirectUri { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authentication properties of the challenge.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; private set; }
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -10,6 +11,18 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
public static class OAuthExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddOAuth(this AuthenticationBuilder builder, string authenticationScheme, Action<OAuthOptions> configureOptions)
|
||||
=> builder.AddOAuth<OAuthOptions, OAuthHandler<OAuthOptions>>(authenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddOAuth<TOptions, THandler>(this AuthenticationBuilder builder, string authenticationScheme, Action<TOptions> configureOptions)
|
||||
where TOptions : OAuthOptions, new()
|
||||
where THandler : OAuthHandler<TOptions>
|
||||
{
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<TOptions>, OAuthPostConfigureOptions<TOptions, THandler>>());
|
||||
return builder.AddRemoteScheme<TOptions, THandler>(authenticationScheme, authenticationScheme, configureOptions);
|
||||
}
|
||||
|
||||
// REMOVE below once callers have been updated
|
||||
public static IServiceCollection AddOAuthAuthentication(this IServiceCollection services, string authenticationScheme, Action<OAuthOptions> configureOptions)
|
||||
{
|
||||
return services.AddOAuthAuthentication<OAuthOptions, OAuthHandler<OAuthOptions>>(authenticationScheme, configureOptions);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
/// <returns>A new instance of the events instance.</returns>
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new OAuthEvents());
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync()
|
||||
protected override async Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
|
||||
{
|
||||
AuthenticationProperties properties = null;
|
||||
var query = Request.Query;
|
||||
|
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
failureMessage.Append(";Uri=").Append(errorUri);
|
||||
}
|
||||
|
||||
return AuthenticateResult.Fail(failureMessage.ToString());
|
||||
return HandleRequestResult.Fail(failureMessage.ToString());
|
||||
}
|
||||
|
||||
var code = query["code"];
|
||||
|
@ -72,30 +72,30 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
properties = Options.StateDataFormat.Unprotect(state);
|
||||
if (properties == null)
|
||||
{
|
||||
return AuthenticateResult.Fail("The oauth state was missing or invalid.");
|
||||
return HandleRequestResult.Fail("The oauth state was missing or invalid.");
|
||||
}
|
||||
|
||||
// OAuth2 10.12 CSRF
|
||||
if (!ValidateCorrelationId(properties))
|
||||
{
|
||||
return AuthenticateResult.Fail("Correlation failed.");
|
||||
return HandleRequestResult.Fail("Correlation failed.");
|
||||
}
|
||||
|
||||
if (StringValues.IsNullOrEmpty(code))
|
||||
{
|
||||
return AuthenticateResult.Fail("Code was not found.");
|
||||
return HandleRequestResult.Fail("Code was not found.");
|
||||
}
|
||||
|
||||
var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath));
|
||||
|
||||
if (tokens.Error != null)
|
||||
{
|
||||
return AuthenticateResult.Fail(tokens.Error);
|
||||
return HandleRequestResult.Fail(tokens.Error);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tokens.AccessToken))
|
||||
{
|
||||
return AuthenticateResult.Fail("Failed to retrieve access token.");
|
||||
return HandleRequestResult.Fail("Failed to retrieve access token.");
|
||||
}
|
||||
|
||||
var identity = new ClaimsIdentity(ClaimsIssuer);
|
||||
|
@ -137,11 +137,11 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
var ticket = await CreateTicketAsync(identity, properties, tokens);
|
||||
if (ticket != null)
|
||||
{
|
||||
return AuthenticateResult.Success(ticket);
|
||||
return HandleRequestResult.Success(ticket);
|
||||
}
|
||||
else
|
||||
{
|
||||
return AuthenticateResult.Fail("Failed to retrieve user information from remote server.");
|
||||
return HandleRequestResult.Fail("Failed to retrieve user information from remote server.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,10 +185,9 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
|
||||
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
{
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name);
|
||||
var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens);
|
||||
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens);
|
||||
await Events.CreatingTicket(context);
|
||||
return context.Ticket;
|
||||
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
|
||||
}
|
||||
|
||||
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||
|
@ -202,8 +201,8 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
GenerateCorrelationId(properties);
|
||||
|
||||
var authorizationEndpoint = BuildChallengeUrl(properties, BuildRedirectUri(Options.CallbackPath));
|
||||
var redirectContext = new OAuthRedirectToAuthorizationContext(
|
||||
Context, Options,
|
||||
var redirectContext = new RedirectContext<OAuthOptions>(
|
||||
Context, Scheme, Options,
|
||||
properties, authorizationEndpoint);
|
||||
await Events.RedirectToAuthorizationEndpoint(redirectContext);
|
||||
}
|
||||
|
|
|
@ -23,24 +23,13 @@
|
|||
"TypeId": "public interface Microsoft.AspNetCore.Authentication.OAuth.IOAuthEvents : Microsoft.AspNetCore.Authentication.IRemoteAuthenticationEvents",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OAuth.OAuthRedirectToAuthorizationContext : Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OAuthOptions options, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties, System.String redirectUri)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OAuth.OAuthRedirectToAuthorizationContext : Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Builder.OAuthOptions get_Options()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OAuth.OAuthRedirectToAuthorizationContext : Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.AspNetCore.Builder.OAuthAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseOAuthAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.OAuthOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OAuth.OAuthRedirectToAuthorizationContext : Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"Kind": "Removal"
|
||||
}
|
||||
]
|
|
@ -2,17 +2,18 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
public class AuthenticationFailedContext : BaseOpenIdConnectContext
|
||||
public class AuthenticationFailedContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
public AuthenticationFailedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
: base(context, scheme, options, new AuthenticationProperties())
|
||||
{ }
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
public Exception Exception { get; set; }
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
|
@ -13,17 +11,19 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// This Context can be used to be informed when an 'AuthorizationCode' is received over the OpenIdConnect protocol.
|
||||
/// </summary>
|
||||
public class AuthorizationCodeReceivedContext : BaseOpenIdConnectContext
|
||||
public class AuthorizationCodeReceivedContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a <see cref="AuthorizationCodeReceivedContext"/>
|
||||
/// </summary>
|
||||
public AuthorizationCodeReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public AuthorizationCodeReceivedContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OpenIdConnectOptions options,
|
||||
AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties) { }
|
||||
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="JwtSecurityToken"/> that was received in the authentication response, if any.
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. 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.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
public class BaseOpenIdConnectContext : BaseControlContext
|
||||
{
|
||||
public BaseOpenIdConnectContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context)
|
||||
{
|
||||
Options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
Scheme = scheme ?? throw new ArgumentNullException(nameof(scheme));
|
||||
}
|
||||
|
||||
public OpenIdConnectOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
}
|
||||
}
|
|
@ -2,21 +2,24 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
public class MessageReceivedContext : BaseOpenIdConnectContext
|
||||
public class MessageReceivedContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
public MessageReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public MessageReceivedContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OpenIdConnectOptions options,
|
||||
AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties) { }
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bearer Token. This will give application an opportunity to retrieve token from an alternation location.
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
|
@ -9,14 +10,25 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// When a user configures the <see cref="OpenIdConnectHandler"/> to be notified prior to redirecting to an IdentityProvider
|
||||
/// an instance of <see cref="RedirectContext"/> is passed to the 'RedirectToAuthenticationEndpoint' or 'RedirectToEndSessionEndpoint' events.
|
||||
/// </summary>
|
||||
public class RedirectContext : BaseOpenIdConnectContext
|
||||
public class RedirectContext : PropertiesContext<OpenIdConnectOptions>
|
||||
{
|
||||
public RedirectContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, AuthenticationProperties properties)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
Properties = properties;
|
||||
}
|
||||
public RedirectContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OpenIdConnectOptions options,
|
||||
AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties) { }
|
||||
|
||||
public AuthenticationProperties Properties { get; }
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, will skip any default logic for this redirect.
|
||||
/// </summary>
|
||||
public bool Handled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skips any default logic for this redirect.
|
||||
/// </summary>
|
||||
public void HandleResponse() => Handled = true;
|
||||
}
|
||||
}
|
|
@ -6,16 +6,12 @@ using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
|||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
public class RemoteSignOutContext : BaseOpenIdConnectContext
|
||||
public class RemoteSignOutContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
public RemoteSignOutContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OpenIdConnectOptions options,
|
||||
OpenIdConnectMessage message)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
ProtocolMessage = message;
|
||||
}
|
||||
public RemoteSignOutContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, OpenIdConnectMessage message)
|
||||
: base(context, scheme, options, new AuthenticationProperties())
|
||||
=> ProtocolMessage = message;
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
|
@ -9,18 +10,16 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// This Context can be used to be informed when an 'AuthorizationCode' is redeemed for tokens at the token endpoint.
|
||||
/// </summary>
|
||||
public class TokenResponseReceivedContext : BaseOpenIdConnectContext
|
||||
public class TokenResponseReceivedContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a <see cref="TokenResponseReceivedContext"/>
|
||||
/// </summary>
|
||||
public TokenResponseReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, AuthenticationProperties properties)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
Properties = properties;
|
||||
}
|
||||
public TokenResponseReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties)
|
||||
=> Principal = user;
|
||||
|
||||
public AuthenticationProperties Properties { get; }
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="OpenIdConnectMessage"/> that contains the tokens received after redeeming the code at the token endpoint.
|
||||
|
|
|
@ -2,25 +2,22 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
public class TokenValidatedContext : BaseOpenIdConnectContext
|
||||
public class TokenValidatedContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a <see cref="TokenValidatedContext"/>
|
||||
/// </summary>
|
||||
public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties)
|
||||
=> Principal = principal;
|
||||
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
public JwtSecurityToken SecurityToken { get; set; }
|
||||
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
public class UserInformationReceivedContext : BaseOpenIdConnectContext
|
||||
public class UserInformationReceivedContext : RemoteAuthenticationContext<OpenIdConnectOptions>
|
||||
{
|
||||
public UserInformationReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
public UserInformationReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties)
|
||||
=> Principal = principal;
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
public JObject User { get; set; }
|
||||
}
|
||||
|
|
|
@ -8,9 +8,7 @@ namespace Microsoft.Extensions.Logging
|
|||
internal static class LoggingExtensions
|
||||
{
|
||||
private static Action<ILogger, Exception> _redirectToIdentityProviderForSignOutHandledResponse;
|
||||
private static Action<ILogger, Exception> _redirectToIdentityProviderForSignOutSkipped;
|
||||
private static Action<ILogger, Exception> _redirectToIdentityProviderHandledResponse;
|
||||
private static Action<ILogger, Exception> _redirectToIdentityProviderSkipped;
|
||||
private static Action<ILogger, Exception> _updatingConfiguration;
|
||||
private static Action<ILogger, Exception> _receivedIdToken;
|
||||
private static Action<ILogger, Exception> _redeemingCodeForTokens;
|
||||
|
@ -55,6 +53,7 @@ namespace Microsoft.Extensions.Logging
|
|||
private static Action<ILogger, Exception> _remoteSignOut;
|
||||
private static Action<ILogger, Exception> _remoteSignOutSessionIdMissing;
|
||||
private static Action<ILogger, Exception> _remoteSignOutSessionIdInvalid;
|
||||
private static Action<ILogger, string, Exception> _signOut;
|
||||
|
||||
static LoggingExtensions()
|
||||
{
|
||||
|
@ -63,10 +62,6 @@ namespace Microsoft.Extensions.Logging
|
|||
eventId: 1,
|
||||
logLevel: LogLevel.Debug,
|
||||
formatString: "RedirectToIdentityProviderForSignOut.HandledResponse");
|
||||
_redirectToIdentityProviderForSignOutSkipped = LoggerMessage.Define(
|
||||
eventId: 2,
|
||||
logLevel: LogLevel.Debug,
|
||||
formatString: "RedirectToIdentityProviderForSignOut.Skipped");
|
||||
_invalidLogoutQueryStringRedirectUrl = LoggerMessage.Define<string>(
|
||||
eventId: 3,
|
||||
logLevel: LogLevel.Warning,
|
||||
|
@ -87,10 +82,6 @@ namespace Microsoft.Extensions.Logging
|
|||
eventId: 6,
|
||||
logLevel: LogLevel.Debug,
|
||||
formatString: "RedirectToIdentityProvider.HandledResponse");
|
||||
_redirectToIdentityProviderSkipped = LoggerMessage.Define(
|
||||
eventId: 7,
|
||||
logLevel: LogLevel.Debug,
|
||||
formatString: "RedirectToIdentityProvider.Skipped");
|
||||
_invalidAuthenticationRequestUrl = LoggerMessage.Define<string>(
|
||||
eventId: 8,
|
||||
logLevel: LogLevel.Warning,
|
||||
|
@ -253,6 +244,10 @@ namespace Microsoft.Extensions.Logging
|
|||
logLevel: LogLevel.Error,
|
||||
formatString: "The remote signout request was ignored because the 'sid' parameter didn't match " +
|
||||
"the expected value, which may indicate an unsolicited logout.");
|
||||
_signOut = LoggerMessage.Define<string>(
|
||||
eventId: 49,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "AuthenticationScheme: {AuthenticationScheme} signed out.");
|
||||
}
|
||||
|
||||
public static void UpdatingConfiguration(this ILogger logger)
|
||||
|
@ -345,21 +340,11 @@ namespace Microsoft.Extensions.Logging
|
|||
_redirectToIdentityProviderForSignOutHandledResponse(logger, null);
|
||||
}
|
||||
|
||||
public static void RedirectToIdentityProviderForSignOutSkipped(this ILogger logger)
|
||||
{
|
||||
_redirectToIdentityProviderForSignOutSkipped(logger, null);
|
||||
}
|
||||
|
||||
public static void RedirectToIdentityProviderHandledResponse(this ILogger logger)
|
||||
{
|
||||
_redirectToIdentityProviderHandledResponse(logger, null);
|
||||
}
|
||||
|
||||
public static void RedirectToIdentityProviderSkipped(this ILogger logger)
|
||||
{
|
||||
_redirectToIdentityProviderSkipped(logger, null);
|
||||
}
|
||||
|
||||
public static void UserInformationReceivedHandledResponse(this ILogger logger)
|
||||
{
|
||||
_userInformationReceivedHandledResponse(logger, null);
|
||||
|
@ -494,5 +479,10 @@ namespace Microsoft.Extensions.Logging
|
|||
{
|
||||
_remoteSignOutSessionIdInvalid(logger, null);
|
||||
}
|
||||
|
||||
public static void SignedOut(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_signOut(logger, authenticationScheme, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -10,6 +11,19 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
public static class OpenIdConnectExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddOpenIdConnect(this AuthenticationBuilder builder)
|
||||
=> builder.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
public static AuthenticationBuilder AddOpenIdConnect(this AuthenticationBuilder builder, Action<OpenIdConnectOptions> configureOptions)
|
||||
=> builder.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, Action<OpenIdConnectOptions> configureOptions)
|
||||
{
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<OpenIdConnectOptions>, OpenIdConnectPostConfigureOptions>());
|
||||
return builder.AddRemoteScheme<OpenIdConnectOptions, OpenIdConnectHandler>(authenticationScheme, authenticationScheme, configureOptions);
|
||||
}
|
||||
|
||||
// REMOVE once callers have been updated
|
||||
public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services)
|
||||
=> services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// A per-request authentication handler for the OpenIdConnectAuthenticationMiddleware.
|
||||
/// </summary>
|
||||
public class OpenIdConnectHandler : RemoteAuthenticationHandler<OpenIdConnectOptions>
|
||||
public class OpenIdConnectHandler : RemoteAuthenticationHandler<OpenIdConnectOptions>, IAuthenticationSignOutHandler
|
||||
{
|
||||
private const string NonceProperty = "N";
|
||||
private const string UriSchemeDelimiter = "://";
|
||||
|
@ -110,16 +110,19 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
var remoteSignOutContext = new RemoteSignOutContext(Context, Scheme, Options, message);
|
||||
await Events.RemoteSignOut(remoteSignOutContext);
|
||||
|
||||
if (remoteSignOutContext.HandledResponse)
|
||||
if (remoteSignOutContext.Result != null)
|
||||
{
|
||||
if (remoteSignOutContext.Result.Handled)
|
||||
{
|
||||
Logger.RemoteSignOutHandledResponse();
|
||||
return true;
|
||||
}
|
||||
if (remoteSignOutContext.Skipped)
|
||||
if (remoteSignOutContext.Result.Skipped)
|
||||
{
|
||||
Logger.RemoteSignOutSkipped();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
|
@ -161,8 +164,10 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// Redirect user to the identity provider for sign out
|
||||
/// </summary>
|
||||
/// <returns>A task executing the sign out procedure</returns>
|
||||
protected override async Task HandleSignOutAsync(AuthenticationProperties properties)
|
||||
public async virtual Task SignOutAsync(AuthenticationProperties properties)
|
||||
{
|
||||
properties = properties ?? new AuthenticationProperties();
|
||||
|
||||
Logger.EnteringOpenIdAuthenticationHandlerHandleSignOutAsync(GetType().FullName);
|
||||
|
||||
if (_configuration == null && Options.ConfigurationManager != null)
|
||||
|
@ -199,16 +204,11 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
};
|
||||
|
||||
await Events.RedirectToIdentityProviderForSignOut(redirectContext);
|
||||
if (redirectContext.HandledResponse)
|
||||
if (redirectContext.Handled)
|
||||
{
|
||||
Logger.RedirectToIdentityProviderForSignOutHandledResponse();
|
||||
return;
|
||||
}
|
||||
else if (redirectContext.Skipped)
|
||||
{
|
||||
Logger.RedirectToIdentityProviderForSignOutSkipped();
|
||||
return;
|
||||
}
|
||||
|
||||
message = redirectContext.ProtocolMessage;
|
||||
|
||||
|
@ -221,8 +221,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
if (string.IsNullOrEmpty(message.IssuerAddress))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Cannot redirect to the end session endpoint, the configuration may be missing or invalid.");
|
||||
throw new InvalidOperationException("Cannot redirect to the end session endpoint, the configuration may be missing or invalid.");
|
||||
}
|
||||
|
||||
if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.RedirectGet)
|
||||
|
@ -266,6 +265,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
{
|
||||
throw new NotImplementedException($"An unsupported authentication method has been configured: {Options.AuthenticationMethod}");
|
||||
}
|
||||
|
||||
Logger.SignedOut(Scheme.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -343,16 +344,11 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
};
|
||||
|
||||
await Events.RedirectToIdentityProvider(redirectContext);
|
||||
if (redirectContext.HandledResponse)
|
||||
if (redirectContext.Handled)
|
||||
{
|
||||
Logger.RedirectToIdentityProviderHandledResponse();
|
||||
return;
|
||||
}
|
||||
else if (redirectContext.Skipped)
|
||||
{
|
||||
Logger.RedirectToIdentityProviderSkipped();
|
||||
return;
|
||||
}
|
||||
|
||||
message = redirectContext.ProtocolMessage;
|
||||
|
||||
|
@ -418,8 +414,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// Invoked to process incoming OpenIdConnect messages.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="AuthenticationTicket"/> if successful.</returns>
|
||||
protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync()
|
||||
/// <returns>An <see cref="HandleRequestResult"/>.</returns>
|
||||
protected override async Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
|
||||
{
|
||||
Logger.EnteringOpenIdAuthenticationHandlerHandleRemoteAuthenticateAsync(GetType().FullName);
|
||||
|
||||
|
@ -437,9 +433,9 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
// Not for us?
|
||||
return AuthenticateResult.None();
|
||||
return HandleRequestResult.SkipHandler();
|
||||
}
|
||||
return AuthenticateResult.Fail("An OpenID Connect response cannot contain an " +
|
||||
return HandleRequestResult.Fail("An OpenID Connect response cannot contain an " +
|
||||
"identity token or an access token when using response_mode=query");
|
||||
}
|
||||
}
|
||||
|
@ -459,13 +455,11 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
// Not for us?
|
||||
return AuthenticateResult.None();
|
||||
return HandleRequestResult.SkipHandler();
|
||||
}
|
||||
return AuthenticateResult.Fail("No message.");
|
||||
return HandleRequestResult.Fail("No message.");
|
||||
}
|
||||
|
||||
AuthenticateResult result;
|
||||
|
||||
try
|
||||
{
|
||||
AuthenticationProperties properties = null;
|
||||
|
@ -475,9 +469,9 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var messageReceivedContext = await RunMessageReceivedEventAsync(authorizationResponse, properties);
|
||||
if (messageReceivedContext.IsProcessingComplete(out result))
|
||||
if (messageReceivedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return messageReceivedContext.Result;
|
||||
}
|
||||
authorizationResponse = messageReceivedContext.ProtocolMessage;
|
||||
properties = messageReceivedContext.Properties;
|
||||
|
@ -491,9 +485,9 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
Logger.NullOrEmptyAuthorizationResponseState();
|
||||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
return AuthenticateResult.None();
|
||||
return HandleRequestResult.SkipHandler();
|
||||
}
|
||||
return AuthenticateResult.Fail(Resources.MessageStateIsNullOrEmpty);
|
||||
return HandleRequestResult.Fail(Resources.MessageStateIsNullOrEmpty);
|
||||
}
|
||||
|
||||
// if state exists and we failed to 'unprotect' this is not a message we should process.
|
||||
|
@ -506,9 +500,9 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
// Not for us?
|
||||
return AuthenticateResult.None();
|
||||
return HandleRequestResult.SkipHandler();
|
||||
}
|
||||
return AuthenticateResult.Fail(Resources.MessageStateIsInvalid);
|
||||
return HandleRequestResult.Fail(Resources.MessageStateIsInvalid);
|
||||
}
|
||||
|
||||
string userstate = null;
|
||||
|
@ -517,13 +511,13 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
if (!ValidateCorrelationId(properties))
|
||||
{
|
||||
return AuthenticateResult.Fail("Correlation failed.");
|
||||
return HandleRequestResult.Fail("Correlation failed.");
|
||||
}
|
||||
|
||||
// if any of the error fields are set, throw error null
|
||||
if (!string.IsNullOrEmpty(authorizationResponse.Error))
|
||||
{
|
||||
return AuthenticateResult.Fail(CreateOpenIdConnectProtocolException(authorizationResponse, response: null));
|
||||
return HandleRequestResult.Fail(CreateOpenIdConnectProtocolException(authorizationResponse, response: null));
|
||||
}
|
||||
|
||||
if (_configuration == null && Options.ConfigurationManager != null)
|
||||
|
@ -534,7 +528,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
PopulateSessionProperties(authorizationResponse, properties);
|
||||
|
||||
AuthenticationTicket ticket = null;
|
||||
ClaimsPrincipal user = null;
|
||||
JwtSecurityToken jwt = null;
|
||||
string nonce = null;
|
||||
var validationParameters = Options.TokenValidationParameters.Clone();
|
||||
|
@ -543,7 +537,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (!string.IsNullOrEmpty(authorizationResponse.IdToken))
|
||||
{
|
||||
Logger.ReceivedIdToken();
|
||||
ticket = ValidateToken(authorizationResponse.IdToken, properties, validationParameters, out jwt);
|
||||
user = ValidateToken(authorizationResponse.IdToken, properties, validationParameters, out jwt);
|
||||
|
||||
nonce = jwt.Payload.Nonce;
|
||||
if (!string.IsNullOrEmpty(nonce))
|
||||
|
@ -551,14 +545,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
nonce = ReadNonceCookie(nonce);
|
||||
}
|
||||
|
||||
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, null, properties, ticket, jwt, nonce);
|
||||
if (tokenValidatedContext.IsProcessingComplete(out result))
|
||||
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, null, user, properties, jwt, nonce);
|
||||
if (tokenValidatedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return tokenValidatedContext.Result;
|
||||
}
|
||||
authorizationResponse = tokenValidatedContext.ProtocolMessage;
|
||||
user = tokenValidatedContext.Principal;
|
||||
properties = tokenValidatedContext.Properties;
|
||||
ticket = tokenValidatedContext.Ticket;
|
||||
jwt = tokenValidatedContext.SecurityToken;
|
||||
nonce = tokenValidatedContext.Nonce;
|
||||
}
|
||||
|
@ -576,17 +570,17 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
// Authorization Code or Hybrid flow
|
||||
if (!string.IsNullOrEmpty(authorizationResponse.Code))
|
||||
{
|
||||
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(authorizationResponse, properties, ticket, jwt);
|
||||
if (authorizationCodeReceivedContext.IsProcessingComplete(out result))
|
||||
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(authorizationResponse, user, properties, jwt);
|
||||
if (authorizationCodeReceivedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return authorizationCodeReceivedContext.Result;
|
||||
}
|
||||
authorizationResponse = authorizationCodeReceivedContext.ProtocolMessage;
|
||||
user = authorizationCodeReceivedContext.Principal;
|
||||
properties = authorizationCodeReceivedContext.Properties;
|
||||
var tokenEndpointRequest = authorizationCodeReceivedContext.TokenEndpointRequest;
|
||||
// If the developer redeemed the code themselves...
|
||||
tokenEndpointResponse = authorizationCodeReceivedContext.TokenEndpointResponse;
|
||||
ticket = authorizationCodeReceivedContext.Ticket;
|
||||
jwt = authorizationCodeReceivedContext.JwtSecurityToken;
|
||||
|
||||
if (!authorizationCodeReceivedContext.HandledCodeRedemption)
|
||||
|
@ -594,14 +588,16 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
tokenEndpointResponse = await RedeemAuthorizationCodeAsync(tokenEndpointRequest);
|
||||
}
|
||||
|
||||
var tokenResponseReceivedContext = await RunTokenResponseReceivedEventAsync(authorizationResponse, tokenEndpointResponse, properties, ticket);
|
||||
if (tokenResponseReceivedContext.IsProcessingComplete(out result))
|
||||
var tokenResponseReceivedContext = await RunTokenResponseReceivedEventAsync(authorizationResponse, tokenEndpointResponse, user, properties);
|
||||
if (tokenResponseReceivedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return tokenResponseReceivedContext.Result;
|
||||
}
|
||||
|
||||
authorizationResponse = tokenResponseReceivedContext.ProtocolMessage;
|
||||
tokenEndpointResponse = tokenResponseReceivedContext.TokenEndpointResponse;
|
||||
user = tokenResponseReceivedContext.Principal;
|
||||
properties = tokenResponseReceivedContext.Properties;
|
||||
|
||||
// no need to validate signature when token is received using "code flow" as per spec
|
||||
// [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation].
|
||||
|
@ -610,10 +606,10 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
// At least a cursory validation is required on the new IdToken, even if we've already validated the one from the authorization response.
|
||||
// And we'll want to validate the new JWT in ValidateTokenResponse.
|
||||
JwtSecurityToken tokenEndpointJwt;
|
||||
var tokenEndpointTicket = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt);
|
||||
var tokenEndpointUser = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt);
|
||||
|
||||
// Avoid reading & deleting the nonce cookie, running the event, etc, if it was already done as part of the authorization response validation.
|
||||
if (ticket == null)
|
||||
if (user == null)
|
||||
{
|
||||
nonce = tokenEndpointJwt.Payload.Nonce;
|
||||
if (!string.IsNullOrEmpty(nonce))
|
||||
|
@ -621,15 +617,15 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
nonce = ReadNonceCookie(nonce);
|
||||
}
|
||||
|
||||
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, tokenEndpointResponse, properties, tokenEndpointTicket, tokenEndpointJwt, nonce);
|
||||
if (tokenValidatedContext.IsProcessingComplete(out result))
|
||||
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, tokenEndpointResponse, tokenEndpointUser, properties, tokenEndpointJwt, nonce);
|
||||
if (tokenValidatedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return tokenValidatedContext.Result;
|
||||
}
|
||||
authorizationResponse = tokenValidatedContext.ProtocolMessage;
|
||||
tokenEndpointResponse = tokenValidatedContext.TokenEndpointResponse;
|
||||
user = tokenValidatedContext.Principal;
|
||||
properties = tokenValidatedContext.Properties;
|
||||
ticket = tokenValidatedContext.Ticket;
|
||||
jwt = tokenValidatedContext.SecurityToken;
|
||||
nonce = tokenValidatedContext.Nonce;
|
||||
}
|
||||
|
@ -658,23 +654,23 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
if (Options.SaveTokens)
|
||||
{
|
||||
SaveTokens(ticket.Properties, tokenEndpointResponse ?? authorizationResponse);
|
||||
SaveTokens(properties, tokenEndpointResponse ?? authorizationResponse);
|
||||
}
|
||||
|
||||
if (Options.GetClaimsFromUserInfoEndpoint)
|
||||
{
|
||||
return await GetUserInformationAsync(tokenEndpointResponse ?? authorizationResponse, jwt, ticket);
|
||||
return await GetUserInformationAsync(tokenEndpointResponse ?? authorizationResponse, jwt, user, properties);
|
||||
}
|
||||
else
|
||||
{
|
||||
var identity = (ClaimsIdentity)ticket.Principal.Identity;
|
||||
var identity = (ClaimsIdentity)user.Identity;
|
||||
foreach (var action in Options.ClaimActions)
|
||||
{
|
||||
action.Run(null, identity, ClaimsIssuer);
|
||||
}
|
||||
}
|
||||
|
||||
return AuthenticateResult.Success(ticket);
|
||||
return HandleRequestResult.Success(new AuthenticationTicket(user, properties, Scheme.Name));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
@ -691,12 +687,12 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var authenticationFailedContext = await RunAuthenticationFailedEventAsync(authorizationResponse, exception);
|
||||
if (authenticationFailedContext.IsProcessingComplete(out result))
|
||||
if (authenticationFailedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return authenticationFailedContext.Result;
|
||||
}
|
||||
|
||||
return AuthenticateResult.Fail(exception);
|
||||
return HandleRequestResult.Fail(exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -765,21 +761,24 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// </summary>
|
||||
/// <param name="message">message that is being processed</param>
|
||||
/// <param name="jwt">The <see cref="JwtSecurityToken"/>.</param>
|
||||
/// <param name="ticket">authentication ticket with claims principal and identities</param>
|
||||
/// <returns>Authentication ticket with identity with additional claims, if any.</returns>
|
||||
protected virtual async Task<AuthenticateResult> GetUserInformationAsync(OpenIdConnectMessage message, JwtSecurityToken jwt, AuthenticationTicket ticket)
|
||||
/// <param name="principal">The claims principal and identities.</param>
|
||||
/// <param name="properties">The authentication properties.</param>
|
||||
/// <returns><see cref="HandleRequestResult"/> which is used to determine if the remote authentication was successful.</returns>
|
||||
protected virtual async Task<HandleRequestResult> GetUserInformationAsync(
|
||||
OpenIdConnectMessage message, JwtSecurityToken jwt,
|
||||
ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
{
|
||||
var userInfoEndpoint = _configuration?.UserInfoEndpoint;
|
||||
|
||||
if (string.IsNullOrEmpty(userInfoEndpoint))
|
||||
{
|
||||
Logger.UserInfoEndpointNotSet();
|
||||
return AuthenticateResult.Success(ticket);
|
||||
return HandleRequestResult.Success(new AuthenticationTicket(principal, properties, Scheme.Name));
|
||||
}
|
||||
if (string.IsNullOrEmpty(message.AccessToken))
|
||||
{
|
||||
Logger.AccessTokenNotAvailable();
|
||||
return AuthenticateResult.Success(ticket);
|
||||
return HandleRequestResult.Success(new AuthenticationTicket(principal, properties, Scheme.Name));
|
||||
}
|
||||
Logger.RetrievingClaims();
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, userInfoEndpoint);
|
||||
|
@ -801,16 +800,16 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
else
|
||||
{
|
||||
return AuthenticateResult.Fail("Unknown response type: " + contentType.MediaType);
|
||||
return HandleRequestResult.Fail("Unknown response type: " + contentType.MediaType);
|
||||
}
|
||||
|
||||
var userInformationReceivedContext = await RunUserInformationReceivedEventAsync(ticket, message, user);
|
||||
AuthenticateResult result;
|
||||
if (userInformationReceivedContext.IsProcessingComplete(out result))
|
||||
var userInformationReceivedContext = await RunUserInformationReceivedEventAsync(principal, properties, message, user);
|
||||
if (userInformationReceivedContext.Result != null)
|
||||
{
|
||||
return result;
|
||||
return userInformationReceivedContext.Result;
|
||||
}
|
||||
ticket = userInformationReceivedContext.Ticket;
|
||||
principal = userInformationReceivedContext.Principal;
|
||||
properties = userInformationReceivedContext.Properties;
|
||||
user = userInformationReceivedContext.User;
|
||||
|
||||
Options.ProtocolValidator.ValidateUserInfoResponse(new OpenIdConnectProtocolValidationContext()
|
||||
|
@ -819,14 +818,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
ValidatedIdToken = jwt,
|
||||
});
|
||||
|
||||
var identity = (ClaimsIdentity)ticket.Principal.Identity;
|
||||
var identity = (ClaimsIdentity)principal.Identity;
|
||||
|
||||
foreach (var action in Options.ClaimActions)
|
||||
{
|
||||
action.Run(user, identity, ClaimsIssuer);
|
||||
}
|
||||
|
||||
return AuthenticateResult.Success(ticket);
|
||||
return HandleRequestResult.Success(new AuthenticationTicket(principal, properties, Scheme.Name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -983,51 +982,54 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
private async Task<MessageReceivedContext> RunMessageReceivedEventAsync(OpenIdConnectMessage message, AuthenticationProperties properties)
|
||||
{
|
||||
Logger.MessageReceived(message.BuildRedirectUrl());
|
||||
var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options)
|
||||
var context = new MessageReceivedContext(Context, Scheme, Options, properties)
|
||||
{
|
||||
ProtocolMessage = message,
|
||||
Properties = properties,
|
||||
};
|
||||
|
||||
await Events.MessageReceived(messageReceivedContext);
|
||||
if (messageReceivedContext.HandledResponse)
|
||||
await Events.MessageReceived(context);
|
||||
if (context.Result != null)
|
||||
{
|
||||
if (context.Result.Handled)
|
||||
{
|
||||
Logger.MessageReceivedContextHandledResponse();
|
||||
}
|
||||
else if (messageReceivedContext.Skipped)
|
||||
else if (context.Result.Skipped)
|
||||
{
|
||||
Logger.MessageReceivedContextSkipped();
|
||||
}
|
||||
|
||||
return messageReceivedContext;
|
||||
}
|
||||
|
||||
private async Task<TokenValidatedContext> RunTokenValidatedEventAsync(OpenIdConnectMessage authorizationResponse, OpenIdConnectMessage tokenEndpointResponse, AuthenticationProperties properties, AuthenticationTicket ticket, JwtSecurityToken jwt, string nonce)
|
||||
return context;
|
||||
}
|
||||
|
||||
private async Task<TokenValidatedContext> RunTokenValidatedEventAsync(OpenIdConnectMessage authorizationResponse, OpenIdConnectMessage tokenEndpointResponse, ClaimsPrincipal user, AuthenticationProperties properties, JwtSecurityToken jwt, string nonce)
|
||||
{
|
||||
var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options)
|
||||
var context = new TokenValidatedContext(Context, Scheme, Options, user, properties)
|
||||
{
|
||||
ProtocolMessage = authorizationResponse,
|
||||
TokenEndpointResponse = tokenEndpointResponse,
|
||||
Properties = properties,
|
||||
Ticket = ticket,
|
||||
SecurityToken = jwt,
|
||||
Nonce = nonce,
|
||||
};
|
||||
|
||||
await Events.TokenValidated(tokenValidatedContext);
|
||||
if (tokenValidatedContext.HandledResponse)
|
||||
await Events.TokenValidated(context);
|
||||
if (context.Result != null)
|
||||
{
|
||||
if (context.Result.Handled)
|
||||
{
|
||||
Logger.TokenValidatedHandledResponse();
|
||||
}
|
||||
else if (tokenValidatedContext.Skipped)
|
||||
else if (context.Result.Skipped)
|
||||
{
|
||||
Logger.TokenValidatedSkipped();
|
||||
}
|
||||
|
||||
return tokenValidatedContext;
|
||||
}
|
||||
|
||||
private async Task<AuthorizationCodeReceivedContext> RunAuthorizationCodeReceivedEventAsync(OpenIdConnectMessage authorizationResponse, AuthenticationProperties properties, AuthenticationTicket ticket, JwtSecurityToken jwt)
|
||||
return context;
|
||||
}
|
||||
|
||||
private async Task<AuthorizationCodeReceivedContext> RunAuthorizationCodeReceivedEventAsync(OpenIdConnectMessage authorizationResponse, ClaimsPrincipal user, AuthenticationProperties properties, JwtSecurityToken jwt)
|
||||
{
|
||||
Logger.AuthorizationCodeReceived();
|
||||
|
||||
|
@ -1041,102 +1043,112 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
RedirectUri = properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]
|
||||
};
|
||||
|
||||
var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Scheme, Options)
|
||||
var context = new AuthorizationCodeReceivedContext(Context, Scheme, Options, properties)
|
||||
{
|
||||
ProtocolMessage = authorizationResponse,
|
||||
Properties = properties,
|
||||
TokenEndpointRequest = tokenEndpointRequest,
|
||||
Ticket = ticket,
|
||||
Principal = user,
|
||||
JwtSecurityToken = jwt,
|
||||
Backchannel = Backchannel,
|
||||
Backchannel = Backchannel
|
||||
};
|
||||
|
||||
await Events.AuthorizationCodeReceived(authorizationCodeReceivedContext);
|
||||
if (authorizationCodeReceivedContext.HandledResponse)
|
||||
await Events.AuthorizationCodeReceived(context);
|
||||
if (context.Result != null)
|
||||
{
|
||||
if (context.Result.Handled)
|
||||
{
|
||||
Logger.AuthorizationCodeReceivedContextHandledResponse();
|
||||
}
|
||||
else if (authorizationCodeReceivedContext.Skipped)
|
||||
else if (context.Result.Skipped)
|
||||
{
|
||||
Logger.AuthorizationCodeReceivedContextSkipped();
|
||||
}
|
||||
}
|
||||
|
||||
return authorizationCodeReceivedContext;
|
||||
return context;
|
||||
}
|
||||
|
||||
private async Task<TokenResponseReceivedContext> RunTokenResponseReceivedEventAsync(
|
||||
OpenIdConnectMessage message,
|
||||
OpenIdConnectMessage tokenEndpointResponse,
|
||||
AuthenticationProperties properties,
|
||||
AuthenticationTicket ticket)
|
||||
ClaimsPrincipal user,
|
||||
AuthenticationProperties properties)
|
||||
{
|
||||
Logger.TokenResponseReceived();
|
||||
var eventContext = new TokenResponseReceivedContext(Context, Scheme, Options, properties)
|
||||
var context = new TokenResponseReceivedContext(Context, Scheme, Options, user, properties)
|
||||
{
|
||||
ProtocolMessage = message,
|
||||
TokenEndpointResponse = tokenEndpointResponse,
|
||||
Ticket = ticket
|
||||
};
|
||||
|
||||
await Events.TokenResponseReceived(eventContext);
|
||||
if (eventContext.HandledResponse)
|
||||
await Events.TokenResponseReceived(context);
|
||||
if (context.Result != null)
|
||||
{
|
||||
if (context.Result.Handled)
|
||||
{
|
||||
Logger.TokenResponseReceivedHandledResponse();
|
||||
}
|
||||
else if (eventContext.Skipped)
|
||||
else if (context.Result.Skipped)
|
||||
{
|
||||
Logger.TokenResponseReceivedSkipped();
|
||||
}
|
||||
|
||||
return eventContext;
|
||||
}
|
||||
|
||||
private async Task<UserInformationReceivedContext> RunUserInformationReceivedEventAsync(AuthenticationTicket ticket, OpenIdConnectMessage message, JObject user)
|
||||
return context;
|
||||
}
|
||||
|
||||
private async Task<UserInformationReceivedContext> RunUserInformationReceivedEventAsync(ClaimsPrincipal principal, AuthenticationProperties properties, OpenIdConnectMessage message, JObject user)
|
||||
{
|
||||
Logger.UserInformationReceived(user.ToString());
|
||||
|
||||
var userInformationReceivedContext = new UserInformationReceivedContext(Context, Scheme, Options)
|
||||
var context = new UserInformationReceivedContext(Context, Scheme, Options, principal, properties)
|
||||
{
|
||||
Ticket = ticket,
|
||||
ProtocolMessage = message,
|
||||
User = user,
|
||||
};
|
||||
|
||||
await Events.UserInformationReceived(userInformationReceivedContext);
|
||||
if (userInformationReceivedContext.HandledResponse)
|
||||
await Events.UserInformationReceived(context);
|
||||
if (context.Result != null)
|
||||
{
|
||||
if (context.Result.Handled)
|
||||
{
|
||||
Logger.UserInformationReceivedHandledResponse();
|
||||
}
|
||||
else if (userInformationReceivedContext.Skipped)
|
||||
else if (context.Result.Skipped)
|
||||
{
|
||||
Logger.UserInformationReceivedSkipped();
|
||||
}
|
||||
}
|
||||
|
||||
return userInformationReceivedContext;
|
||||
return context;
|
||||
}
|
||||
|
||||
private async Task<AuthenticationFailedContext> RunAuthenticationFailedEventAsync(OpenIdConnectMessage message, Exception exception)
|
||||
{
|
||||
var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
|
||||
var context = new AuthenticationFailedContext(Context, Scheme, Options)
|
||||
{
|
||||
ProtocolMessage = message,
|
||||
Exception = exception
|
||||
};
|
||||
|
||||
await Events.AuthenticationFailed(authenticationFailedContext);
|
||||
if (authenticationFailedContext.HandledResponse)
|
||||
await Events.AuthenticationFailed(context);
|
||||
if (context.Result != null)
|
||||
{
|
||||
if (context.Result.Handled)
|
||||
{
|
||||
Logger.AuthenticationFailedContextHandledResponse();
|
||||
}
|
||||
else if (authenticationFailedContext.Skipped)
|
||||
else if (context.Result.Skipped)
|
||||
{
|
||||
Logger.AuthenticationFailedContextSkipped();
|
||||
}
|
||||
|
||||
return authenticationFailedContext;
|
||||
}
|
||||
|
||||
private AuthenticationTicket ValidateToken(string idToken, AuthenticationProperties properties, TokenValidationParameters validationParameters, out JwtSecurityToken jwt)
|
||||
return context;
|
||||
}
|
||||
|
||||
// Note this modifies properties if Options.UseTokenLifetime
|
||||
private ClaimsPrincipal ValidateToken(string idToken, AuthenticationProperties properties, TokenValidationParameters validationParameters, out JwtSecurityToken jwt)
|
||||
{
|
||||
if (!Options.SecurityTokenValidator.CanReadToken(idToken))
|
||||
{
|
||||
|
@ -1173,24 +1185,22 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, Resources.UnableToValidateToken, idToken));
|
||||
}
|
||||
|
||||
var ticket = new AuthenticationTicket(principal, properties, Scheme.Name);
|
||||
|
||||
if (Options.UseTokenLifetime)
|
||||
{
|
||||
var issued = validatedToken.ValidFrom;
|
||||
if (issued != DateTime.MinValue)
|
||||
{
|
||||
ticket.Properties.IssuedUtc = issued;
|
||||
properties.IssuedUtc = issued;
|
||||
}
|
||||
|
||||
var expires = validatedToken.ValidTo;
|
||||
if (expires != DateTime.MinValue)
|
||||
{
|
||||
ticket.Properties.ExpiresUtc = expires;
|
||||
properties.ExpiresUtc = expires;
|
||||
}
|
||||
}
|
||||
|
||||
return ticket;
|
||||
return principal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4,13 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Protocols;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
|
|
@ -18,100 +18,46 @@
|
|||
{
|
||||
"TypeId": "public interface Microsoft.AspNetCore.Authentication.OpenIdConnect.IOpenIdConnectEvents : Microsoft.AspNetCore.Authentication.IRemoteAuthenticationEvents",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.AspNetCore.Builder.OpenIdConnectAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseOpenIdConnectAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthenticationFailedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthorizationCodeReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthorizationCodeReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthorizationCodeReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Builder.OpenIdConnectOptions get_Options()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.MessageReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.MessageReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.MessageReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.UserInformationReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenResponseReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenResponseReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.RemoteSignOutContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options, Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage message)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.AspNetCore.Builder.OpenIdConnectAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseOpenIdConnectAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.OpenIdConnectOptions options)",
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenResponseReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.OpenIdConnect.UserInformationReceivedContext : Microsoft.AspNetCore.Authentication.OpenIdConnect.BaseOpenIdConnectContext",
|
||||
"Kind": "Removal"
|
||||
}
|
||||
]
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for other Twitter contexts.
|
||||
/// </summary>
|
||||
public class BaseTwitterContext : BaseAuthenticationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="BaseTwitterContext"/>
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP environment</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The options for Twitter</param>
|
||||
/// <param name="properties">The AuthenticationProperties</param>
|
||||
public BaseTwitterContext(HttpContext context, AuthenticationScheme scheme, TwitterOptions options, AuthenticationProperties properties)
|
||||
: base(context, scheme.Name, properties)
|
||||
{
|
||||
Options = options;
|
||||
}
|
||||
|
||||
public TwitterOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// <summary>
|
||||
/// Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.
|
||||
/// </summary>
|
||||
public class TwitterCreatingTicketContext : BaseTwitterContext
|
||||
public class TwitterCreatingTicketContext : ResultContext<TwitterOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="TwitterCreatingTicketContext"/>
|
||||
|
@ -19,29 +19,33 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// <param name="context">The HTTP environment</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The options for Twitter</param>
|
||||
/// <param name="principal">The <see cref="ClaimsPrincipal"/>.</param>
|
||||
/// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
|
||||
/// <param name="userId">Twitter user ID</param>
|
||||
/// <param name="screenName">Twitter screen name</param>
|
||||
/// <param name="accessToken">Twitter access token</param>
|
||||
/// <param name="accessTokenSecret">Twitter access token secret</param>
|
||||
/// <param name="user">User details</param>
|
||||
/// <param name="properties">AuthenticationProperties.</param>
|
||||
public TwitterCreatingTicketContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
TwitterOptions options,
|
||||
ClaimsPrincipal principal,
|
||||
AuthenticationProperties properties,
|
||||
string userId,
|
||||
string screenName,
|
||||
string accessToken,
|
||||
string accessTokenSecret,
|
||||
JObject user)
|
||||
: base(context, scheme, options, properties)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
UserId = userId;
|
||||
ScreenName = screenName;
|
||||
AccessToken = accessToken;
|
||||
AccessTokenSecret = accessTokenSecret;
|
||||
User = user ?? new JObject();
|
||||
Principal = principal;
|
||||
Properties = properties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -69,10 +73,5 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// <see cref="JObject"/> if it is not available.
|
||||
/// </summary>
|
||||
public JObject User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ClaimsPrincipal"/> representing the user
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// <summary>
|
||||
/// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked.
|
||||
/// </summary>
|
||||
public Func<TwitterRedirectToAuthorizationEndpointContext, Task> OnRedirectToAuthorizationEndpoint { get; set; } = context =>
|
||||
public Func<RedirectContext<TwitterOptions>, Task> OnRedirectToAuthorizationEndpoint { get; set; } = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri);
|
||||
return Task.CompletedTask;
|
||||
|
@ -36,6 +36,6 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// Called when a Challenge causes a redirect to authorize endpoint in the Twitter handler
|
||||
/// </summary>
|
||||
/// <param name="context">Contains redirect URI and <see cref="Http.Authentication.AuthenticationProperties"/> of the challenge </param>
|
||||
public virtual Task RedirectToAuthorizationEndpoint(TwitterRedirectToAuthorizationEndpointContext context) => OnRedirectToAuthorizationEndpoint(context);
|
||||
public virtual Task RedirectToAuthorizationEndpoint(RedirectContext<TwitterOptions> context) => OnRedirectToAuthorizationEndpoint(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||
{
|
||||
/// <summary>
|
||||
/// The Context passed when a Challenge causes a redirect to authorize endpoint in the Twitter handler.
|
||||
/// </summary>
|
||||
public class TwitterRedirectToAuthorizationEndpointContext : BaseTwitterContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context.</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The Twitter handler options.</param>
|
||||
/// <param name="properties">The authentication properties of the challenge.</param>
|
||||
/// <param name="redirectUri">The initial redirect URI.</param>
|
||||
public TwitterRedirectToAuthorizationEndpointContext(HttpContext context, AuthenticationScheme scheme,
|
||||
|
||||
TwitterOptions options, AuthenticationProperties properties, string redirectUri)
|
||||
: base(context, scheme, options, properties)
|
||||
{
|
||||
RedirectUri = redirectUri;
|
||||
Properties = properties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URI used for the redirect operation.
|
||||
/// </summary>
|
||||
public string RedirectUri { get; private set; }
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Twitter;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -10,6 +11,19 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
public static class TwitterExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddTwitter(this AuthenticationBuilder builder)
|
||||
=> builder.AddTwitter(TwitterDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
public static AuthenticationBuilder AddTwitter(this AuthenticationBuilder builder, Action<TwitterOptions> configureOptions)
|
||||
=> builder.AddTwitter(TwitterDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static AuthenticationBuilder AddTwitter(this AuthenticationBuilder builder, string authenticationScheme, Action<TwitterOptions> configureOptions)
|
||||
{
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<TwitterOptions>, TwitterPostConfigureOptions>());
|
||||
return builder.AddRemoteScheme<TwitterOptions, TwitterHandler>(authenticationScheme, authenticationScheme, configureOptions);
|
||||
}
|
||||
|
||||
// REMOVE below once callers have been updated.
|
||||
public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services)
|
||||
=> services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, _ => { });
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new TwitterEvents());
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync()
|
||||
protected override async Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
|
||||
{
|
||||
AuthenticationProperties properties = null;
|
||||
var query = Request.Query;
|
||||
|
@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
|
||||
if (requestToken == null)
|
||||
{
|
||||
return AuthenticateResult.Fail("Invalid state cookie.");
|
||||
return HandleRequestResult.Fail("Invalid state cookie.");
|
||||
}
|
||||
|
||||
properties = requestToken.Properties;
|
||||
|
@ -66,18 +66,18 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
var returnedToken = query["oauth_token"];
|
||||
if (StringValues.IsNullOrEmpty(returnedToken))
|
||||
{
|
||||
return AuthenticateResult.Fail("Missing oauth_token");
|
||||
return HandleRequestResult.Fail("Missing oauth_token");
|
||||
}
|
||||
|
||||
if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal))
|
||||
{
|
||||
return AuthenticateResult.Fail("Unmatched token");
|
||||
return HandleRequestResult.Fail("Unmatched token");
|
||||
}
|
||||
|
||||
var oauthVerifier = query["oauth_verifier"];
|
||||
if (StringValues.IsNullOrEmpty(oauthVerifier))
|
||||
{
|
||||
return AuthenticateResult.Fail("Missing or blank oauth_verifier");
|
||||
return HandleRequestResult.Fail("Missing or blank oauth_verifier");
|
||||
}
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
|
@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
});
|
||||
}
|
||||
|
||||
return AuthenticateResult.Success(await CreateTicketAsync(identity, properties, accessToken, user));
|
||||
return HandleRequestResult.Success(await CreateTicketAsync(identity, properties, accessToken, user));
|
||||
}
|
||||
|
||||
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(
|
||||
|
@ -127,18 +127,9 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
action.Run(user, identity, ClaimsIssuer);
|
||||
}
|
||||
|
||||
var context = new TwitterCreatingTicketContext(Context, Scheme, Options, properties, token.UserId, token.ScreenName, token.Token, token.TokenSecret, user)
|
||||
{
|
||||
Principal = new ClaimsPrincipal(identity)
|
||||
};
|
||||
|
||||
var context = new TwitterCreatingTicketContext(Context, Scheme, Options, new ClaimsPrincipal(identity), properties, token.UserId, token.ScreenName, token.Token, token.TokenSecret, user);
|
||||
await Events.CreatingTicket(context);
|
||||
|
||||
if (context.Principal?.Identity == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
|
||||
}
|
||||
|
||||
|
@ -165,7 +156,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
|
||||
Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(requestToken), cookieOptions);
|
||||
|
||||
var redirectContext = new TwitterRedirectToAuthorizationEndpointContext(Context, Scheme, Options, properties, twitterAuthenticationEndpoint);
|
||||
var redirectContext = new RedirectContext<TwitterOptions>(Context, Scheme, Options, properties, twitterAuthenticationEndpoint);
|
||||
await Events.RedirectToAuthorizationEndpoint(redirectContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,31 +19,6 @@
|
|||
"TypeId": "public interface Microsoft.AspNetCore.Authentication.Twitter.ITwitterEvents : Microsoft.AspNetCore.Authentication.IRemoteAuthenticationEvents",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterRedirectToAuthorizationEndpointContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.TwitterOptions options, Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties, System.String redirectUri)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterRedirectToAuthorizationEndpointContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.TwitterOptions options, System.String userId, System.String screenName, System.String accessToken, System.String accessTokenSecret, Newtonsoft.Json.Linq.JObject user)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.RequestToken",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
|
@ -58,5 +33,13 @@
|
|||
"TypeId": "public static class Microsoft.AspNetCore.Builder.TwitterAppBuilderExtensions",
|
||||
"MemberId": "public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseTwitterAuthentication(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Builder.TwitterOptions options)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.Twitter.TwitterRedirectToAuthorizationEndpointContext : Microsoft.AspNetCore.Authentication.Twitter.BaseTwitterContext",
|
||||
"Kind": "Removal"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) .NET Foundation. 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.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to configure authentication
|
||||
/// </summary>
|
||||
public class AuthenticationBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="services">The services being configured.</param>
|
||||
public AuthenticationBuilder(IServiceCollection services)
|
||||
=> Services = services;
|
||||
|
||||
/// <summary>
|
||||
/// The services being configured.
|
||||
/// </summary>
|
||||
public virtual IServiceCollection Services { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="AuthenticationScheme"/> which can be used by <see cref="IAuthenticationService"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TOptions">The <see cref="AuthenticationSchemeOptions"/> type to configure the handler."/>.</typeparam>
|
||||
/// <typeparam name="THandler">The <see cref="AuthenticationHandler{TOptions}"/> used to handle this scheme.</typeparam>
|
||||
/// <param name="authenticationScheme">The name of this scheme.</param>
|
||||
/// <param name="displayName">The display name of this scheme.</param>
|
||||
/// <param name="configureOptions">Used to configure the scheme options.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
public virtual AuthenticationBuilder AddScheme<TOptions, THandler>(string authenticationScheme, string displayName, Action<TOptions> configureOptions)
|
||||
where TOptions : AuthenticationSchemeOptions, new()
|
||||
where THandler : AuthenticationHandler<TOptions>
|
||||
{
|
||||
Services.Configure<AuthenticationOptions>(o =>
|
||||
{
|
||||
o.AddScheme(authenticationScheme, scheme => {
|
||||
scheme.HandlerType = typeof(THandler);
|
||||
scheme.DisplayName = displayName;
|
||||
});
|
||||
});
|
||||
if (configureOptions != null)
|
||||
{
|
||||
Services.Configure(authenticationScheme, configureOptions);
|
||||
}
|
||||
Services.AddTransient<THandler>();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="AuthenticationScheme"/> which can be used by <see cref="IAuthenticationService"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TOptions">The <see cref="AuthenticationSchemeOptions"/> type to configure the handler."/>.</typeparam>
|
||||
/// <typeparam name="THandler">The <see cref="AuthenticationHandler{TOptions}"/> used to handle this scheme.</typeparam>
|
||||
/// <param name="authenticationScheme">The name of this scheme.</param>
|
||||
/// <param name="configureOptions">Used to configure the scheme options.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
public virtual AuthenticationBuilder AddScheme<TOptions, THandler>(string authenticationScheme, Action<TOptions> configureOptions)
|
||||
where TOptions : AuthenticationSchemeOptions, new()
|
||||
where THandler : AuthenticationHandler<TOptions>
|
||||
=> AddScheme<TOptions, THandler>(authenticationScheme, displayName: null, configureOptions: configureOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="RemoteAuthenticationHandler{TOptions}"/> based <see cref="AuthenticationScheme"/> that supports remote authentication
|
||||
/// which can be used by <see cref="IAuthenticationService"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TOptions">The <see cref="RemoteAuthenticationOptions"/> type to configure the handler."/>.</typeparam>
|
||||
/// <typeparam name="THandler">The <see cref="RemoteAuthenticationHandler{TOptions}"/> used to handle this scheme.</typeparam>
|
||||
/// <param name="authenticationScheme">The name of this scheme.</param>
|
||||
/// <param name="displayName">The display name of this scheme.</param>
|
||||
/// <param name="configureOptions">Used to configure the scheme options.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
public virtual AuthenticationBuilder AddRemoteScheme<TOptions, THandler>(string authenticationScheme, string displayName, Action<TOptions> configureOptions)
|
||||
where TOptions : RemoteAuthenticationOptions, new()
|
||||
where THandler : RemoteAuthenticationHandler<TOptions>
|
||||
{
|
||||
Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<TOptions>, EnsureSignInScheme<TOptions>>());
|
||||
return AddScheme<TOptions, THandler>(authenticationScheme, displayName, configureOptions: configureOptions);
|
||||
}
|
||||
|
||||
// Used to ensure that there's always a default data protection provider
|
||||
private class EnsureSignInScheme<TOptions> : IPostConfigureOptions<TOptions> where TOptions : RemoteAuthenticationOptions
|
||||
{
|
||||
private readonly AuthenticationOptions _authOptions;
|
||||
|
||||
public EnsureSignInScheme(IOptions<AuthenticationOptions> authOptions)
|
||||
{
|
||||
_authOptions = authOptions.Value;
|
||||
}
|
||||
|
||||
public void PostConfigure(string name, TOptions options)
|
||||
{
|
||||
options.SignInScheme = options.SignInScheme ?? _authOptions.DefaultSignInScheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -178,35 +178,6 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
|
||||
protected abstract Task<AuthenticateResult> HandleAuthenticateAsync();
|
||||
|
||||
public async Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
properties = properties ?? new AuthenticationProperties();
|
||||
await HandleSignInAsync(user, properties);
|
||||
Logger.AuthenticationSchemeSignedIn(Scheme.Name);
|
||||
}
|
||||
|
||||
protected virtual Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task SignOutAsync(AuthenticationProperties properties)
|
||||
{
|
||||
properties = properties ?? new AuthenticationProperties();
|
||||
await HandleSignOutAsync(properties);
|
||||
Logger.AuthenticationSchemeSignedOut(Scheme.Name);
|
||||
}
|
||||
|
||||
protected virtual Task HandleSignOutAsync(AuthenticationProperties properties)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override this method to handle Forbid.
|
||||
/// </summary>
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
/// </summary>
|
||||
public static class AuthenticationServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddAuthentication(this IServiceCollection services)
|
||||
public static AuthenticationBuilder AddAuthentication(this IServiceCollection services)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
|
@ -24,10 +24,10 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.AddDataProtection();
|
||||
services.AddWebEncoders();
|
||||
services.TryAddSingleton<ISystemClock, SystemClock>();
|
||||
return services;
|
||||
return new AuthenticationBuilder(services);
|
||||
}
|
||||
|
||||
public static IServiceCollection AddAuthentication(this IServiceCollection services, Action<AuthenticationOptions> configureOptions) {
|
||||
public static AuthenticationBuilder AddAuthentication(this IServiceCollection services, Action<AuthenticationOptions> configureOptions) {
|
||||
if (services == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
|
@ -38,11 +38,12 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
throw new ArgumentNullException(nameof(configureOptions));
|
||||
}
|
||||
|
||||
services.AddAuthentication();
|
||||
var builder = services.AddAuthentication();
|
||||
services.Configure(configureOptions);
|
||||
return services;
|
||||
return builder;
|
||||
}
|
||||
|
||||
// REMOVE below once callers have been updated
|
||||
public static IServiceCollection AddScheme<TOptions, THandler>(this IServiceCollection services, string authenticationScheme, string displayName, Action<AuthenticationSchemeBuilder> configureScheme, Action<TOptions> configureOptions)
|
||||
where TOptions : AuthenticationSchemeOptions, new()
|
||||
where THandler : AuthenticationHandler<TOptions>
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. 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.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Base context for authentication.
|
||||
/// </summary>
|
||||
public abstract class BaseAuthenticationContext : BaseContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="authenticationScheme">The name of the scheme.</param>
|
||||
/// <param name="properties">The properties.</param>
|
||||
protected BaseAuthenticationContext(HttpContext context, string authenticationScheme, AuthenticationProperties properties) : base(context)
|
||||
{
|
||||
if (string.IsNullOrEmpty(authenticationScheme))
|
||||
{
|
||||
throw new ArgumentException(nameof(authenticationScheme));
|
||||
}
|
||||
|
||||
AuthenticationScheme = authenticationScheme;
|
||||
Properties = properties ?? new AuthenticationProperties();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the scheme.
|
||||
/// </summary>
|
||||
public string AuthenticationScheme { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the extra meta-data arriving with the authentication. May be altered.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; protected set; }
|
||||
}
|
||||
}
|
|
@ -9,22 +9,44 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
/// <summary>
|
||||
/// Base class used by other context classes.
|
||||
/// </summary>
|
||||
public abstract class BaseContext
|
||||
public abstract class BaseContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="context">The request context.</param>
|
||||
protected BaseContext(HttpContext context)
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The authentication options associated with the scheme.</param>
|
||||
protected BaseContext(HttpContext context, AuthenticationScheme scheme, TOptions options)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
if (scheme == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(scheme));
|
||||
}
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
HttpContext = context;
|
||||
Scheme = scheme;
|
||||
Options = options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The authentication scheme.
|
||||
/// </summary>
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authentication options associated with the scheme.
|
||||
/// </summary>
|
||||
public TOptions Options { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The context.
|
||||
/// </summary>
|
||||
|
@ -33,17 +55,11 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
/// <summary>
|
||||
/// The request.
|
||||
/// </summary>
|
||||
public HttpRequest Request
|
||||
{
|
||||
get { return HttpContext.Request; }
|
||||
}
|
||||
public HttpRequest Request => HttpContext.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The response.
|
||||
/// </summary>
|
||||
public HttpResponse Response
|
||||
{
|
||||
get { return HttpContext.Response; }
|
||||
}
|
||||
public HttpResponse Response => HttpContext.Response;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
public class BaseControlContext : BaseContext
|
||||
{
|
||||
protected BaseControlContext(HttpContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public EventResultState State { get; set; }
|
||||
|
||||
public bool HandledResponse
|
||||
{
|
||||
get { return State == EventResultState.HandledResponse; }
|
||||
}
|
||||
|
||||
public bool Skipped
|
||||
{
|
||||
get { return State == EventResultState.Skipped; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue all processing for this request and return to the client.
|
||||
/// The caller is responsible for generating the full response.
|
||||
/// Set the <see cref="Ticket"/> to trigger SignIn.
|
||||
/// </summary>
|
||||
public void HandleResponse()
|
||||
{
|
||||
State = EventResultState.HandledResponse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue processing the request in the current handler.
|
||||
/// SignIn will not be called.
|
||||
/// </summary>
|
||||
public void Skip()
|
||||
{
|
||||
State = EventResultState.Skipped;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the <see cref="Ticket"/> to return if this event signals it handled the event.
|
||||
/// </summary>
|
||||
public AuthenticationTicket Ticket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the handler should be done processing.
|
||||
/// </summary>
|
||||
/// <param name="result">The result.</param>
|
||||
/// <returns>Whether the handler should be done processing.</returns>
|
||||
public bool IsProcessingComplete(out AuthenticateResult result)
|
||||
{
|
||||
if (HandledResponse)
|
||||
{
|
||||
if (Ticket == null)
|
||||
{
|
||||
result = AuthenticateResult.Handle();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = AuthenticateResult.Success(Ticket);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (Skipped)
|
||||
{
|
||||
result = AuthenticateResult.None();
|
||||
return true;
|
||||
}
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
public enum EventResultState
|
||||
{
|
||||
/// <summary>
|
||||
/// Continue with normal processing.
|
||||
/// </summary>
|
||||
Continue,
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue processing the request.
|
||||
/// </summary>
|
||||
Skipped,
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue all processing for this request.
|
||||
/// </summary>
|
||||
HandledResponse
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
public class HandleRequestContext<TOptions> : BaseContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
protected HandleRequestContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
TOptions options)
|
||||
: base(context, scheme, options) { }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="HandleRequestResult"/> which is used by the handler.
|
||||
/// </summary>
|
||||
public HandleRequestResult Result { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue all processing for this request and return to the client.
|
||||
/// The caller is responsible for generating the full response.
|
||||
/// </summary>
|
||||
public void HandleResponse() => Result = HandleRequestResult.Handle();
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue processing the request in the current handler.
|
||||
/// </summary>
|
||||
public void SkipHandler() => Result = HandleRequestResult.SkipHandler();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Base context for authentication events which deal with a ClaimsPrincipal.
|
||||
/// </summary>
|
||||
public abstract class PrincipalContext<TOptions> : PropertiesContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The authentication options associated with the scheme.</param>
|
||||
/// <param name="properties">The authentication properties.</param>
|
||||
protected PrincipalContext(HttpContext context, AuthenticationScheme scheme, TOptions options, AuthenticationProperties properties)
|
||||
: base(context, scheme, options, properties) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ClaimsPrincipal"/> containing the user claims.
|
||||
/// </summary>
|
||||
public virtual ClaimsPrincipal Principal { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Base context for authentication events which contain <see cref="AuthenticationProperties"/>.
|
||||
/// </summary>
|
||||
public abstract class PropertiesContext<TOptions> : BaseContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The authentication options associated with the scheme.</param>
|
||||
/// <param name="properties">The authentication properties.</param>
|
||||
protected PropertiesContext(HttpContext context, AuthenticationScheme scheme, TOptions options, AuthenticationProperties properties)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
Properties = properties ?? new AuthenticationProperties();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="AuthenticationProperties"/>.
|
||||
/// </summary>
|
||||
public virtual AuthenticationProperties Properties { get; protected set; }
|
||||
}
|
||||
}
|
|
@ -1,28 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Context passed when a Challenge, SignIn, or SignOut causes a redirect in the cookie handler
|
||||
/// Context passed for redirect events.
|
||||
/// </summary>
|
||||
public class CookieRedirectContext : BaseCookieContext
|
||||
public class RedirectContext<TOptions> : PropertiesContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The cookie handler options</param>
|
||||
/// <param name="options">The handler options</param>
|
||||
/// <param name="redirectUri">The initial redirect URI</param>
|
||||
/// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
|
||||
public CookieRedirectContext(HttpContext context, AuthenticationScheme scheme, CookieAuthenticationOptions options, string redirectUri, AuthenticationProperties properties)
|
||||
public RedirectContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
TOptions options,
|
||||
AuthenticationProperties properties,
|
||||
string redirectUri)
|
||||
: base(context, scheme, options, properties)
|
||||
{
|
||||
Properties = properties;
|
||||
RedirectUri = redirectUri;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Base context for remote authentication.
|
||||
/// </summary>
|
||||
public abstract class RemoteAuthenticationContext<TOptions> : HandleRequestContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The authentication options associated with the scheme.</param>
|
||||
/// <param name="properties">The authentication properties.</param>
|
||||
protected RemoteAuthenticationContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
TOptions options,
|
||||
AuthenticationProperties properties)
|
||||
: base(context, scheme, options)
|
||||
=> Properties = properties ?? new AuthenticationProperties();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ClaimsPrincipal"/> containing the user claims.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="AuthenticationProperties"/>.
|
||||
/// </summary>
|
||||
public virtual AuthenticationProperties Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calls success creating a ticket with the <see cref="Principal"/> and <see cref="Properties"/>.
|
||||
/// </summary>
|
||||
public void Success() => Result = HandleRequestResult.Success(new AuthenticationTicket(Principal, Properties, Scheme.Name));
|
||||
|
||||
public void Fail(Exception failure) => Result = HandleRequestResult.Fail(failure);
|
||||
|
||||
public void Fail(string failureMessage) => Result = HandleRequestResult.Fail(failureMessage);
|
||||
}
|
||||
}
|
|
@ -8,14 +8,14 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
public class RemoteAuthenticationEvents
|
||||
{
|
||||
public Func<FailureContext, Task> OnRemoteFailure { get; set; } = context => Task.CompletedTask;
|
||||
public Func<RemoteFailureContext, Task> OnRemoteFailure { get; set; } = context => Task.CompletedTask;
|
||||
|
||||
public Func<TicketReceivedContext, Task> OnTicketReceived { get; set; } = context => Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when there is a remote failure
|
||||
/// </summary>
|
||||
public virtual Task RemoteFailure(FailureContext context) => OnRemoteFailure(context);
|
||||
public virtual Task RemoteFailure(RemoteFailureContext context) => OnRemoteFailure(context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after the remote ticket has been received.
|
||||
|
|
|
@ -9,10 +9,14 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
/// <summary>
|
||||
/// Provides failure context information to handler providers.
|
||||
/// </summary>
|
||||
public class FailureContext : BaseControlContext
|
||||
public class RemoteFailureContext : HandleRequestContext<RemoteAuthenticationOptions>
|
||||
{
|
||||
public FailureContext(HttpContext context, Exception failure)
|
||||
: base(context)
|
||||
public RemoteFailureContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
RemoteAuthenticationOptions options,
|
||||
Exception failure)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
Failure = failure;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Base context for events that produce AuthenticateResults.
|
||||
/// </summary>
|
||||
public abstract class ResultContext<TOptions> : BaseContext<TOptions> where TOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The authentication options associated with the scheme.</param>
|
||||
protected ResultContext(HttpContext context, AuthenticationScheme scheme, TOptions options)
|
||||
: base(context, scheme, options) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ClaimsPrincipal"/> containing the user claims.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
|
||||
private AuthenticationProperties _properties;
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="AuthenticationProperties"/>.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties {
|
||||
get => _properties ?? (_properties = new AuthenticationProperties());
|
||||
set => _properties = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="AuthenticateResult"/> result.
|
||||
/// </summary>
|
||||
public AuthenticateResult Result { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calls success creating a ticket with the <see cref="Principal"/> and <see cref="Properties"/>.
|
||||
/// </summary>
|
||||
public void Success() => Result = HandleRequestResult.Success(new AuthenticationTicket(Principal, Properties, Scheme.Name));
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that there was no information returned for this authentication scheme.
|
||||
/// </summary>
|
||||
public void NoResult() => Result = AuthenticateResult.NoResult();
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that there was a failure during authentication.
|
||||
/// </summary>
|
||||
/// <param name="failure"></param>
|
||||
public void Fail(Exception failure) => Result = AuthenticateResult.Fail(failure);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that there was a failure during authentication.
|
||||
/// </summary>
|
||||
/// <param name="failureMessage"></param>
|
||||
public void Fail(string failureMessage) => Result = AuthenticateResult.Fail(failureMessage);
|
||||
}
|
||||
}
|
|
@ -3,30 +3,21 @@
|
|||
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides context information to handler providers.
|
||||
/// </summary>
|
||||
public class TicketReceivedContext : BaseControlContext
|
||||
public class TicketReceivedContext : RemoteAuthenticationContext<RemoteAuthenticationOptions>
|
||||
{
|
||||
public TicketReceivedContext(HttpContext context, RemoteAuthenticationOptions options, AuthenticationTicket ticket)
|
||||
: base(context)
|
||||
{
|
||||
Options = options;
|
||||
Ticket = ticket;
|
||||
if (ticket != null)
|
||||
{
|
||||
Principal = ticket.Principal;
|
||||
Properties = ticket.Properties;
|
||||
}
|
||||
}
|
||||
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
public RemoteAuthenticationOptions Options { get; set; }
|
||||
public TicketReceivedContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
RemoteAuthenticationOptions options,
|
||||
AuthenticationTicket ticket)
|
||||
: base(context, scheme, options, ticket?.Properties)
|
||||
=> Principal = ticket?.Principal;
|
||||
|
||||
public string ReturnUri { get; set; }
|
||||
}
|
||||
|
|
|
@ -9,14 +9,8 @@ namespace Microsoft.Extensions.Logging
|
|||
{
|
||||
private static Action<ILogger, string, Exception> _authSchemeAuthenticated;
|
||||
private static Action<ILogger, string, Exception> _authSchemeNotAuthenticated;
|
||||
private static Action<ILogger, string, string, Exception> _authSchemeNotAuthenticatedWithFailure;
|
||||
private static Action<ILogger, string, Exception> _authSchemeSignedIn;
|
||||
private static Action<ILogger, string, Exception> _authSchemeSignedOut;
|
||||
private static Action<ILogger, string, Exception> _authSchemeChallenged;
|
||||
private static Action<ILogger, string, Exception> _authSchemeForbidden;
|
||||
private static Action<ILogger, string, Exception> _userAuthorizationFailed;
|
||||
private static Action<ILogger, string, Exception> _userAuthorizationSucceeded;
|
||||
private static Action<ILogger, string, Exception> _userPrincipalMerged;
|
||||
private static Action<ILogger, string, Exception> _remoteAuthenticationError;
|
||||
private static Action<ILogger, Exception> _signInHandled;
|
||||
private static Action<ILogger, Exception> _signInSkipped;
|
||||
|
@ -26,18 +20,6 @@ namespace Microsoft.Extensions.Logging
|
|||
|
||||
static LoggingExtensions()
|
||||
{
|
||||
_userAuthorizationSucceeded = LoggerMessage.Define<string>(
|
||||
eventId: 1,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "Authorization was successful for user: {UserName}.");
|
||||
_userAuthorizationFailed = LoggerMessage.Define<string>(
|
||||
eventId: 2,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "Authorization failed for user: {UserName}.");
|
||||
_userPrincipalMerged = LoggerMessage.Define<string>(
|
||||
eventId: 3,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "HttpContext.User merged via AutomaticAuthentication from authenticationScheme: {AuthenticationScheme}.");
|
||||
_remoteAuthenticationError = LoggerMessage.Define<string>(
|
||||
eventId: 4,
|
||||
logLevel: LogLevel.Information,
|
||||
|
@ -50,10 +32,6 @@ namespace Microsoft.Extensions.Logging
|
|||
eventId: 6,
|
||||
logLevel: LogLevel.Debug,
|
||||
formatString: "The SigningIn event returned Skipped.");
|
||||
_authSchemeNotAuthenticatedWithFailure = LoggerMessage.Define<string, string>(
|
||||
eventId: 7,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "{AuthenticationScheme} was not authenticated. Failure message: {FailureMessage}");
|
||||
_authSchemeAuthenticated = LoggerMessage.Define<string>(
|
||||
eventId: 8,
|
||||
logLevel: LogLevel.Information,
|
||||
|
@ -62,14 +40,6 @@ namespace Microsoft.Extensions.Logging
|
|||
eventId: 9,
|
||||
logLevel: LogLevel.Debug,
|
||||
formatString: "AuthenticationScheme: {AuthenticationScheme} was not authenticated.");
|
||||
_authSchemeSignedIn = LoggerMessage.Define<string>(
|
||||
eventId: 10,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "AuthenticationScheme: {AuthenticationScheme} signed in.");
|
||||
_authSchemeSignedOut = LoggerMessage.Define<string>(
|
||||
eventId: 11,
|
||||
logLevel: LogLevel.Information,
|
||||
formatString: "AuthenticationScheme: {AuthenticationScheme} signed out.");
|
||||
_authSchemeChallenged = LoggerMessage.Define<string>(
|
||||
eventId: 12,
|
||||
logLevel: LogLevel.Information,
|
||||
|
@ -102,21 +72,6 @@ namespace Microsoft.Extensions.Logging
|
|||
_authSchemeNotAuthenticated(logger, authenticationScheme, null);
|
||||
}
|
||||
|
||||
public static void AuthenticationSchemeNotAuthenticatedWithFailure(this ILogger logger, string authenticationScheme, string failureMessage)
|
||||
{
|
||||
_authSchemeNotAuthenticatedWithFailure(logger, authenticationScheme, failureMessage, null);
|
||||
}
|
||||
|
||||
public static void AuthenticationSchemeSignedIn(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_authSchemeSignedIn(logger, authenticationScheme, null);
|
||||
}
|
||||
|
||||
public static void AuthenticationSchemeSignedOut(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_authSchemeSignedOut(logger, authenticationScheme, null);
|
||||
}
|
||||
|
||||
public static void AuthenticationSchemeChallenged(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_authSchemeChallenged(logger, authenticationScheme, null);
|
||||
|
@ -127,21 +82,6 @@ namespace Microsoft.Extensions.Logging
|
|||
_authSchemeForbidden(logger, authenticationScheme, null);
|
||||
}
|
||||
|
||||
public static void UserAuthorizationSucceeded(this ILogger logger, string userName)
|
||||
{
|
||||
_userAuthorizationSucceeded(logger, userName, null);
|
||||
}
|
||||
|
||||
public static void UserAuthorizationFailed(this ILogger logger, string userName)
|
||||
{
|
||||
_userAuthorizationFailed(logger, userName, null);
|
||||
}
|
||||
|
||||
public static void UserPrinicpalMerged(this ILogger logger, string authenticationScheme)
|
||||
{
|
||||
_userPrincipalMerged(logger, authenticationScheme, null);
|
||||
}
|
||||
|
||||
public static void RemoteAuthenticationError(this ILogger logger, string errorMessage)
|
||||
{
|
||||
_remoteAuthenticationError(logger, errorMessage, null);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -35,19 +34,13 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
}
|
||||
|
||||
protected RemoteAuthenticationHandler(IOptionsSnapshot<TOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
|
||||
: base(options, logger, encoder, clock)
|
||||
{
|
||||
}
|
||||
: base(options, logger, encoder, clock) { }
|
||||
|
||||
protected override Task<object> CreateEventsAsync()
|
||||
{
|
||||
return Task.FromResult<object>(new RemoteAuthenticationEvents());
|
||||
}
|
||||
=> Task.FromResult<object>(new RemoteAuthenticationEvents());
|
||||
|
||||
public virtual Task<bool> ShouldHandleRequestAsync()
|
||||
{
|
||||
return Task.FromResult(Options.CallbackPath == Request.Path);
|
||||
}
|
||||
=> Task.FromResult(Options.CallbackPath == Request.Path);
|
||||
|
||||
public virtual async Task<bool> HandleRequestAsync()
|
||||
{
|
||||
|
@ -69,7 +62,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
return true;
|
||||
}
|
||||
else if (authResult.Nothing)
|
||||
else if (authResult.Skipped || authResult.None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -89,25 +82,28 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
if (exception != null)
|
||||
{
|
||||
Logger.RemoteAuthenticationError(exception.Message);
|
||||
var errorContext = new FailureContext(Context, exception);
|
||||
var errorContext = new RemoteFailureContext(Context, Scheme, Options, exception);
|
||||
await Events.RemoteFailure(errorContext);
|
||||
|
||||
if (errorContext.HandledResponse)
|
||||
if (errorContext.Result != null)
|
||||
{
|
||||
if (errorContext.Result.Handled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (errorContext.Skipped)
|
||||
else if (errorContext.Result.Skipped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
throw new AggregateException("Unhandled remote failure.", exception);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
// We have a ticket if we get here
|
||||
var ticketContext = new TicketReceivedContext(Context, Options, ticket)
|
||||
var ticketContext = new TicketReceivedContext(Context, Scheme, Options, ticket)
|
||||
{
|
||||
ReturnUri = ticket.Properties.RedirectUri,
|
||||
ReturnUri = ticket.Properties.RedirectUri
|
||||
};
|
||||
// REVIEW: is this safe or good?
|
||||
ticket.Properties.RedirectUri = null;
|
||||
|
@ -117,16 +113,19 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
|
||||
await Events.TicketReceived(ticketContext);
|
||||
|
||||
if (ticketContext.HandledResponse)
|
||||
if (ticketContext.Result != null)
|
||||
{
|
||||
if (ticketContext.Result.Handled)
|
||||
{
|
||||
Logger.SigninHandled();
|
||||
return true;
|
||||
}
|
||||
else if (ticketContext.Skipped)
|
||||
else if (ticketContext.Result.Skipped)
|
||||
{
|
||||
Logger.SigninSkipped();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
await Context.SignInAsync(SignInScheme, ticketContext.Principal, ticketContext.Properties);
|
||||
|
||||
|
@ -145,7 +144,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
///
|
||||
/// The method process the request on the endpoint defined by CallbackPath.
|
||||
/// </summary>
|
||||
protected abstract Task<AuthenticateResult> HandleRemoteAuthenticateAsync();
|
||||
protected abstract Task<HandleRequestResult> HandleRemoteAuthenticateAsync();
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
|
@ -174,20 +173,8 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
return AuthenticateResult.Fail("Remote authentication does not directly support AuthenticateAsync");
|
||||
}
|
||||
|
||||
protected override Task HandleSignOutAsync(AuthenticationProperties properties)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
protected override Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
|
||||
{
|
||||
return Context.ForbidAsync(SignInScheme);
|
||||
}
|
||||
=> Context.ForbidAsync(SignInScheme);
|
||||
|
||||
protected virtual void GenerateCorrelationId(AuthenticationProperties properties)
|
||||
{
|
||||
|
|
|
@ -23,11 +23,6 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
throw new ArgumentException(Resources.FormatException_OptionMustBeProvided(nameof(CallbackPath)), nameof(CallbackPath));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(SignInScheme))
|
||||
{
|
||||
throw new ArgumentException(Resources.FormatException_OptionMustBeProvided(nameof(SignInScheme)), nameof(SignInScheme));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) .NET Foundation. 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.AspNetCore.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the result of an Authenticate call
|
||||
/// </summary>
|
||||
public class HandleRequestResult : AuthenticateResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that stage of authentication was directly handled by
|
||||
/// user intervention and no further processing should be attempted.
|
||||
/// </summary>
|
||||
public bool Handled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the default authentication logic should be
|
||||
/// skipped and that the rest of the pipeline should be invoked.
|
||||
/// </summary>
|
||||
public bool Skipped { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that authentication was successful.
|
||||
/// </summary>
|
||||
/// <param name="ticket">The ticket representing the authentication result.</param>
|
||||
/// <returns>The result.</returns>
|
||||
public static new HandleRequestResult Success(AuthenticationTicket ticket)
|
||||
{
|
||||
if (ticket == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ticket));
|
||||
}
|
||||
return new HandleRequestResult() { Ticket = ticket };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that there was a failure during authentication.
|
||||
/// </summary>
|
||||
/// <param name="failure">The failure exception.</param>
|
||||
/// <returns>The result.</returns>
|
||||
public static new HandleRequestResult Fail(Exception failure)
|
||||
{
|
||||
return new HandleRequestResult() { Failure = failure };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that there was a failure during authentication.
|
||||
/// </summary>
|
||||
/// <param name="failureMessage">The failure message.</param>
|
||||
/// <returns>The result.</returns>
|
||||
public static new HandleRequestResult Fail(string failureMessage)
|
||||
{
|
||||
return new HandleRequestResult() { Failure = new Exception(failureMessage) };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue all processing for this request and return to the client.
|
||||
/// The caller is responsible for generating the full response.
|
||||
/// </summary>
|
||||
/// <returns>The result.</returns>
|
||||
public static HandleRequestResult Handle()
|
||||
{
|
||||
return new HandleRequestResult() { Handled = true };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Discontinue processing the request in the current handler.
|
||||
/// </summary>
|
||||
/// <returns>The result.</returns>
|
||||
public static HandleRequestResult SkipHandler()
|
||||
{
|
||||
return new HandleRequestResult() { Skipped = true };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -83,44 +83,34 @@
|
|||
"TypeId": "public static class Microsoft.AspNetCore.Builder.ClaimsTransformationAppBuilderExtensions",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.TicketReceivedContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public .ctor(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.RemoteAuthenticationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationTicket ticket)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.TicketReceivedContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Builder.RemoteAuthenticationOptions get_Options()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.TicketReceivedContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties get_Properties()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.TicketReceivedContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public System.Void set_Options(Microsoft.AspNetCore.Builder.RemoteAuthenticationOptions value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.TicketReceivedContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"MemberId": "public System.Void set_Properties(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties value)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.Extensions.DependencyInjection.AuthenticationServiceCollectionExtensions",
|
||||
"MemberId": "public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddAuthentication(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<Microsoft.AspNetCore.Authentication.SharedAuthenticationOptions> configureOptions)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.BaseControlContext : Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"MemberId": "public System.Boolean CheckEventResult(out Microsoft.AspNetCore.Authentication.AuthenticateResult result)",
|
||||
"TypeId": "public abstract class Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.BaseControlContext : Microsoft.AspNetCore.Authentication.BaseContext",
|
||||
"MemberId": "public System.Void SkipToNextMiddleware()",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.FailureContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public class Microsoft.AspNetCore.Authentication.TicketReceivedContext : Microsoft.AspNetCore.Authentication.BaseControlContext",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public static class Microsoft.Extensions.DependencyInjection.AuthenticationServiceCollectionExtensions",
|
||||
"MemberId": "public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddAuthentication(this Microsoft.Extensions.DependencyInjection.IServiceCollection services)",
|
||||
"Kind": "Removal"
|
||||
},
|
||||
{
|
||||
"TypeId": "public enum Microsoft.AspNetCore.Authentication.EventResultState",
|
||||
"Kind": "Removal"
|
||||
}
|
||||
]
|
|
@ -52,13 +52,13 @@ namespace Microsoft.AspNetCore.Authorization.Policy
|
|||
else
|
||||
{
|
||||
context.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
return AuthenticateResult.None();
|
||||
return AuthenticateResult.NoResult();
|
||||
}
|
||||
}
|
||||
|
||||
return (context.User?.Identity?.IsAuthenticated ?? false)
|
||||
? AuthenticateResult.Success(new AuthenticationTicket(context.User, "context.User"))
|
||||
: AuthenticateResult.None();
|
||||
: AuthenticateResult.NoResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
@ -29,7 +30,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
[Fact]
|
||||
public async Task VerifySchemeDefaults()
|
||||
{
|
||||
var services = new ServiceCollection().AddCookieAuthentication();
|
||||
var services = new ServiceCollection();
|
||||
services.AddAuthentication().AddCookie();
|
||||
var sp = services.BuildServiceProvider();
|
||||
var schemeProvider = sp.GetRequiredService<IAuthenticationSchemeProvider>();
|
||||
var scheme = await schemeProvider.GetSchemeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
@ -124,7 +126,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
[Fact]
|
||||
public async Task SignInCausesDefaultCookieToBeCreated()
|
||||
{
|
||||
var server = CreateServerWithServices(s => s.AddCookieAuthentication(o =>
|
||||
var server = CreateServerWithServices(s => s.AddAuthentication().AddCookie(o =>
|
||||
{
|
||||
o.LoginPath = new PathString("/login");
|
||||
o.CookieName = "TestCookie";
|
||||
|
@ -772,7 +774,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
app.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Cookies", new AuthenticationProperties() { RedirectUri = "/" })));
|
||||
})
|
||||
.ConfigureServices(s => s.AddCookieAuthentication(o => o.LoginPath = new PathString("/page")));
|
||||
.ConfigureServices(s => s.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/page")));
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var transaction = await server.SendAsync("http://example.com/login");
|
||||
|
@ -803,7 +805,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme));
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication());
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie());
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var transaction = await server.SendAsync("http://example.com");
|
||||
|
@ -821,7 +823,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication();
|
||||
services.AddAuthentication().AddCookie();
|
||||
services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
o => o.CookieName = "One");
|
||||
});
|
||||
|
@ -844,7 +846,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication("Cookie1");
|
||||
services.AddAuthentication().AddCookie("Cookie1");
|
||||
services.Configure<CookieAuthenticationOptions>("Cookie1",
|
||||
o => o.CookieName = "One");
|
||||
});
|
||||
|
@ -866,7 +868,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
app.Map("/notlogin", signoutApp => signoutApp.Run(context => context.SignInAsync("Cookies",
|
||||
new ClaimsPrincipal())));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.LoginPath = new PathString("/login")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/login")));
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var transaction = await server.SendAsync("http://example.com/notlogin?ReturnUrl=%2Fpage");
|
||||
|
@ -883,7 +885,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
app.UseAuthentication();
|
||||
app.Map("/login", signoutApp => signoutApp.Run(context => context.SignInAsync("Cookies", new ClaimsPrincipal())));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.LoginPath = new PathString("/login")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/login")));
|
||||
|
||||
var server = new TestServer(builder);
|
||||
|
||||
|
@ -905,7 +907,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
app.UseAuthentication();
|
||||
app.Map("/notlogout", signoutApp => signoutApp.Run(context => context.SignOutAsync("Cookies")));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.LogoutPath = new PathString("/logout")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LogoutPath = new PathString("/logout")));
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var transaction = await server.SendAsync("http://example.com/notlogout?ReturnUrl=%2Fpage");
|
||||
|
@ -922,7 +924,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
app.UseAuthentication();
|
||||
app.Map("/logout", signoutApp => signoutApp.Run(context => context.SignOutAsync("Cookies")));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.LogoutPath = new PathString("/logout")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LogoutPath = new PathString("/logout")));
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var transaction = await server.SendAsync("http://example.com/logout?ReturnUrl=%2Fpage");
|
||||
|
@ -943,7 +945,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
app.UseAuthentication();
|
||||
app.Map("/forbid", signoutApp => signoutApp.Run(context => context.ForbidAsync("Cookies")));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.AccessDeniedPath = new PathString("/denied")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.AccessDeniedPath = new PathString("/denied")));
|
||||
var server = new TestServer(builder);
|
||||
var transaction = await server.SendAsync("http://example.com/forbid");
|
||||
|
||||
|
@ -963,7 +965,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
map.UseAuthentication();
|
||||
map.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Cookies", new AuthenticationProperties() { RedirectUri = "/" })));
|
||||
}))
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.LoginPath = new PathString("/page")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/page")));
|
||||
var server = new TestServer(builder);
|
||||
var transaction = await server.SendAsync("http://example.com/base/login");
|
||||
|
||||
|
@ -1073,7 +1075,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
map.UseAuthentication();
|
||||
map.Map("/forbid", signoutApp => signoutApp.Run(context => context.ForbidAsync("Cookies")));
|
||||
}))
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.AccessDeniedPath = new PathString("/denied")));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.AccessDeniedPath = new PathString("/denied")));
|
||||
var server = new TestServer(builder);
|
||||
var transaction = await server.SendAsync("http://example.com/base/forbid");
|
||||
|
||||
|
@ -1097,7 +1099,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))),
|
||||
new AuthenticationProperties()));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o =>
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o =>
|
||||
{
|
||||
o.TicketDataFormat = new TicketDataFormat(dp);
|
||||
o.CookieName = "Cookie";
|
||||
|
@ -1117,7 +1119,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
Describe(context.Response, result);
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication("Cookies", o =>
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie("Cookies", o =>
|
||||
{
|
||||
o.CookieName = "Cookie";
|
||||
o.TicketDataFormat = new TicketDataFormat(dp);
|
||||
|
@ -1132,7 +1134,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
public async Task NullExpiresUtcPropertyIsGuarded()
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o =>
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o =>
|
||||
{
|
||||
o.Events = new CookieAuthenticationEvents
|
||||
{
|
||||
|
@ -1229,7 +1231,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
=> CreateServerWithServices(s =>
|
||||
{
|
||||
s.AddSingleton<ISystemClock>(_clock);
|
||||
s.AddCookieAuthentication(configureOptions);
|
||||
s.AddAuthentication().AddCookie(configureOptions);
|
||||
s.AddSingleton<IClaimsTransformation, ClaimsTransformer>();
|
||||
}, testpath, baseAddress);
|
||||
|
||||
|
@ -1281,6 +1283,15 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
{
|
||||
await testpath(context);
|
||||
}
|
||||
else if (req.Path == new PathString("/checkforerrors"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); // this used to be "Automatic"
|
||||
if (result.Failure != null)
|
||||
{
|
||||
throw new Exception("Failed to authenticate", result.Failure);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
|
|
|
@ -85,9 +85,9 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
{
|
||||
options.DefaultSignInScheme = "External";
|
||||
options.DefaultAuthenticateScheme = "External";
|
||||
});
|
||||
services.AddCookieAuthentication("External", o => { });
|
||||
services.AddFacebookAuthentication(o =>
|
||||
})
|
||||
.AddCookie("External", o => { })
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = "Test App Id";
|
||||
o.AppSecret = "Test App Secret";
|
||||
|
@ -123,12 +123,12 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
}),
|
||||
services =>
|
||||
{
|
||||
services.AddCookieAuthentication("External", o => { });
|
||||
services.AddFacebookAuthentication(o =>
|
||||
services.AddAuthentication()
|
||||
.AddCookie("External", o => { })
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = "Test App Id";
|
||||
o.AppSecret = "Test App Secret";
|
||||
o.SignInScheme = "External";
|
||||
});
|
||||
},
|
||||
handler: null);
|
||||
|
@ -155,8 +155,9 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
},
|
||||
services =>
|
||||
{
|
||||
services.AddCookieAuthentication("External", o => { });
|
||||
services.AddFacebookAuthentication(o =>
|
||||
services.AddAuthentication()
|
||||
.AddCookie("External", o => { })
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = "Test App Id";
|
||||
o.AppSecret = "Test App Secret";
|
||||
|
@ -185,9 +186,9 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultSignInScheme = "External";
|
||||
});
|
||||
services.AddCookieAuthentication();
|
||||
services.AddFacebookAuthentication(o =>
|
||||
})
|
||||
.AddCookie()
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = "Test App Id";
|
||||
o.AppSecret = "Test App Secret";
|
||||
|
@ -217,19 +218,15 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
var finalUserInfoEndpoint = string.Empty;
|
||||
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("FacebookTest"));
|
||||
var server = CreateServer(
|
||||
app =>
|
||||
{
|
||||
app.UseAuthentication();
|
||||
},
|
||||
app => app.UseAuthentication(),
|
||||
services =>
|
||||
{
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
services.AddCookieAuthentication();
|
||||
services.AddFacebookAuthentication(o =>
|
||||
})
|
||||
.AddCookie()
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = "Test App Id";
|
||||
o.AppSecret = "Test App Secret";
|
||||
|
|
|
@ -516,7 +516,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
OnCreatingTicket = context =>
|
||||
{
|
||||
var refreshToken = context.RefreshToken;
|
||||
context.Ticket.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Google") }, "Google"));
|
||||
context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Google") }, "Google"));
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
};
|
||||
|
@ -595,7 +595,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
{
|
||||
OnTicketReceived = context =>
|
||||
{
|
||||
context.Ticket.Properties.RedirectUri = null;
|
||||
context.Properties.RedirectUri = null;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
};
|
||||
|
@ -985,7 +985,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
else if (req.Path == new PathString("/tokens"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync(TestExtensions.CookieAuthenticationScheme);
|
||||
var tokens = result.Ticket.Properties.GetTokens();
|
||||
var tokens = result.Properties.GetTokens();
|
||||
res.Describe(tokens);
|
||||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
|
@ -995,17 +995,17 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
else if (req.Path == new PathString("/authenticate"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync(TestExtensions.CookieAuthenticationScheme);
|
||||
res.Describe(result.Ticket.Principal);
|
||||
res.Describe(result.Principal);
|
||||
}
|
||||
else if (req.Path == new PathString("/authenticateGoogle"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Google");
|
||||
res.Describe(result?.Ticket?.Principal);
|
||||
res.Describe(result?.Principal);
|
||||
}
|
||||
else if (req.Path == new PathString("/authenticateFacebook"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Facebook");
|
||||
res.Describe(result?.Ticket?.Principal);
|
||||
res.Describe(result?.Principal);
|
||||
}
|
||||
else if (req.Path == new PathString("/unauthorized"))
|
||||
{
|
||||
|
@ -1024,15 +1024,15 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
}
|
||||
else if (req.Path == new PathString("/signIn"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignInAsync("Google", new ClaimsPrincipal()));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignInAsync("Google", new ClaimsPrincipal()));
|
||||
}
|
||||
else if (req.Path == new PathString("/signOut"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignOutAsync("Google"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignOutAsync("Google"));
|
||||
}
|
||||
else if (req.Path == new PathString("/forbid"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.ForbidAsync("Google"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.ForbidAsync("Google"));
|
||||
}
|
||||
else if (testpath != null)
|
||||
{
|
||||
|
@ -1050,12 +1050,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
services.AddAuthentication(o =>
|
||||
{
|
||||
o.DefaultAuthenticateScheme = TestExtensions.CookieAuthenticationScheme;
|
||||
o.DefaultSignInScheme = TestExtensions.CookieAuthenticationScheme;
|
||||
o.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
|
||||
});
|
||||
services.AddCookieAuthentication(TestExtensions.CookieAuthenticationScheme);
|
||||
services.AddGoogleAuthentication(configureOptions);
|
||||
services.AddFacebookAuthentication(o =>
|
||||
services.AddAuthentication()
|
||||
.AddCookie(TestExtensions.CookieAuthenticationScheme)
|
||||
.AddGoogle(configureOptions)
|
||||
.AddFacebook(o =>
|
||||
{
|
||||
o.AppId = "Test AppId";
|
||||
o.AppSecret = "Test AppSecrent";
|
||||
|
|
|
@ -127,11 +127,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
new Claim(ClaimsIdentity.DefaultNameClaimType, "bob")
|
||||
};
|
||||
|
||||
context.Ticket = new AuthenticationTicket(
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name)),
|
||||
new AuthenticationProperties(), context.Scheme.Name);
|
||||
|
||||
context.HandleResponse();
|
||||
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
|
||||
context.Success();
|
||||
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
|
@ -338,7 +335,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
// Retrieve the NameIdentifier claim from the identity
|
||||
// returned by the custom security token validator.
|
||||
var identity = (ClaimsIdentity)context.Ticket.Principal.Identity;
|
||||
var identity = (ClaimsIdentity)context.Principal.Identity;
|
||||
var identifier = identity.FindFirst(ClaimTypes.NameIdentifier);
|
||||
|
||||
Assert.Equal("Bob le Tout Puissant", identifier.Value);
|
||||
|
@ -396,7 +393,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
context.Skip();
|
||||
context.NoResult();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
|
@ -420,7 +417,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EventOnMessageReceivedHandled_NoMoreEventsExecuted()
|
||||
public async Task EventOnMessageReceivedReject_NoMoreEventsExecuted()
|
||||
{
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
|
@ -428,7 +425,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
context.HandleResponse();
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
|
@ -447,9 +444,12 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
};
|
||||
});
|
||||
|
||||
var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
|
||||
Assert.Equal(HttpStatusCode.Accepted, response.Response.StatusCode);
|
||||
Assert.Equal(string.Empty, response.ResponseText);
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.InnerException.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -461,7 +461,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
context.Skip();
|
||||
context.NoResult();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
|
@ -483,7 +483,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EventOnTokenValidatedHandled_NoMoreEventsExecuted()
|
||||
public async Task EventOnTokenValidatedReject_NoMoreEventsExecuted()
|
||||
{
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
|
@ -491,7 +491,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
context.HandleResponse();
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
|
@ -508,9 +508,12 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT"));
|
||||
});
|
||||
|
||||
var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
|
||||
Assert.Equal(HttpStatusCode.Accepted, response.Response.StatusCode);
|
||||
Assert.Equal(string.Empty, response.ResponseText);
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.InnerException.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -526,7 +529,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
context.Skip();
|
||||
context.NoResult();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnChallenge = context =>
|
||||
|
@ -544,7 +547,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EventOnAuthenticationFailedHandled_NoMoreEventsExecuted()
|
||||
public async Task EventOnAuthenticationFailedReject_NoMoreEventsExecuted()
|
||||
{
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
|
@ -556,7 +559,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
context.HandleResponse();
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
|
@ -569,9 +572,12 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT"));
|
||||
});
|
||||
|
||||
var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
|
||||
Assert.Equal(HttpStatusCode.Accepted, response.Response.StatusCode);
|
||||
Assert.Equal(string.Empty, response.ResponseText);
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.InnerException.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -583,7 +589,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
OnChallenge = context =>
|
||||
{
|
||||
context.Skip();
|
||||
context.HandleResponse();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
};
|
||||
|
@ -595,29 +601,6 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
Assert.Equal(string.Empty, response.ResponseText);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task EventOnChallengeHandled_ResponseNotModified()
|
||||
{
|
||||
var server = CreateServer(o =>
|
||||
{
|
||||
o.Events = new JwtBearerEvents()
|
||||
{
|
||||
OnChallenge = context =>
|
||||
{
|
||||
context.HandleResponse();
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
var response = await SendAsync(server, "http://example.com/unauthorized", "Bearer Token");
|
||||
Assert.Equal(HttpStatusCode.Accepted, response.Response.StatusCode);
|
||||
Assert.Empty(response.Response.Headers.WwwAuthenticate);
|
||||
Assert.Equal(string.Empty, response.ResponseText);
|
||||
}
|
||||
|
||||
class InvalidTokenValidator : ISecurityTokenValidator
|
||||
{
|
||||
public InvalidTokenValidator()
|
||||
|
@ -752,11 +735,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
else if (context.Request.Path == new PathString("/signIn"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignInAsync(JwtBearerDefaults.AuthenticationScheme, new ClaimsPrincipal()));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignInAsync(JwtBearerDefaults.AuthenticationScheme, new ClaimsPrincipal()));
|
||||
}
|
||||
else if (context.Request.Path == new PathString("/signOut"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignOutAsync(JwtBearerDefaults.AuthenticationScheme));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignOutAsync(JwtBearerDefaults.AuthenticationScheme));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
|
|||
OnCreatingTicket = context =>
|
||||
{
|
||||
var refreshToken = context.RefreshToken;
|
||||
context.Ticket.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft"));
|
||||
context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft"));
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
};
|
||||
|
@ -205,15 +205,15 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
|
|||
}
|
||||
else if (req.Path == new PathString("/signIn"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignInAsync("Microsoft", new ClaimsPrincipal()));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignInAsync("Microsoft", new ClaimsPrincipal()));
|
||||
}
|
||||
else if (req.Path == new PathString("/signOut"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignOutAsync("Microsoft"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignOutAsync("Microsoft"));
|
||||
}
|
||||
else if (req.Path == new PathString("/forbid"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.ForbidAsync("Microsoft"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.ForbidAsync("Microsoft"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -226,10 +226,10 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
|
|||
services.AddAuthentication(o =>
|
||||
{
|
||||
o.DefaultAuthenticateScheme = TestExtensions.CookieAuthenticationScheme;
|
||||
o.DefaultSignInScheme = TestExtensions.CookieAuthenticationScheme;
|
||||
});
|
||||
services.AddCookieAuthentication(TestExtensions.CookieAuthenticationScheme, o => { });
|
||||
services.AddMicrosoftAccountAuthentication(configureOptions);
|
||||
services.AddAuthentication()
|
||||
.AddCookie(TestExtensions.CookieAuthenticationScheme, o => { })
|
||||
.AddMicrosoftAccount(configureOptions);
|
||||
});
|
||||
return new TestServer(builder);
|
||||
}
|
||||
|
|
|
@ -143,29 +143,6 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsIfSignInSchemeMissing()
|
||||
{
|
||||
var server = CreateServer(
|
||||
app => { },
|
||||
services => services.AddOAuthAuthentication("weeblie", o =>
|
||||
{
|
||||
o.ClientId = "Whatever;";
|
||||
o.ClientSecret = "Whatever;";
|
||||
o.CallbackPath = "/";
|
||||
o.TokenEndpoint = "/";
|
||||
o.AuthorizationEndpoint = "/";
|
||||
}),
|
||||
context =>
|
||||
{
|
||||
// REVIEW: Gross.
|
||||
Assert.Throws<ArgumentException>("SignInScheme", () => context.ChallengeAsync("weeblie").GetAwaiter().GetResult());
|
||||
return true;
|
||||
});
|
||||
var transaction = await server.SendAsync("http://example.com/challenge");
|
||||
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RedirectToIdentityProvider_SetsCorrelationIdCookiePath_ToCallBackPath()
|
||||
{
|
||||
|
|
|
@ -335,7 +335,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
// This test can be further refined. When one auth handler skips, the authentication responsibility
|
||||
// will be flowed to the next one. A dummy auth handler can be added to ensure the correct logic.
|
||||
[Fact]
|
||||
public async Task OnRedirectToIdentityProviderEventSkipResponse()
|
||||
public async Task OnRedirectToIdentityProviderEventHandleResponse()
|
||||
{
|
||||
var settings = new TestSettings(
|
||||
opts =>
|
||||
|
@ -346,7 +346,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
OnRedirectToIdentityProvider = context =>
|
||||
{
|
||||
context.Skip();
|
||||
context.HandleResponse();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -22,8 +22,9 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication();
|
||||
services.AddOpenIdConnectAuthentication(o =>
|
||||
services.AddAuthentication()
|
||||
.AddCookie()
|
||||
.AddOpenIdConnect(o =>
|
||||
{
|
||||
o.Authority = TestServerBuilder.DefaultAuthority;
|
||||
o.ClientId = Guid.NewGuid().ToString();
|
||||
|
@ -45,19 +46,6 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ThrowsWhenSignInSchemeIsMissing()
|
||||
{
|
||||
return TestConfigurationException<ArgumentException>(
|
||||
o =>
|
||||
{
|
||||
o.ClientId = "Test Id";
|
||||
o.Authority = TestServerBuilder.DefaultAuthority;
|
||||
o.CallbackPath = "/";
|
||||
},
|
||||
ex => Assert.Equal("SignInScheme", ex.ParamName));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ThrowsWhenClientIdIsMissing()
|
||||
{
|
||||
|
@ -119,8 +107,9 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication();
|
||||
services.AddOpenIdConnectAuthentication(options);
|
||||
services.AddAuthentication()
|
||||
.AddCookie()
|
||||
.AddOpenIdConnect(options);
|
||||
})
|
||||
.Configure(app => app.UseAuthentication());
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
private readonly Func<UserInformationReceivedContext, Task> UserNotImpl = context => { throw new NotImplementedException("User"); };
|
||||
private readonly Func<AuthenticationFailedContext, Task> FailedNotImpl = context => { throw new NotImplementedException("Failed", context.Exception); };
|
||||
private readonly Func<TicketReceivedContext, Task> TicketNotImpl = context => { throw new NotImplementedException("Ticket"); };
|
||||
private readonly Func<FailureContext, Task> FailureNotImpl = context => { throw new NotImplementedException("Failure", context.Failure); };
|
||||
private readonly Func<RemoteFailureContext, Task> FailureNotImpl = context => { throw new NotImplementedException("Failure", context.Failure); };
|
||||
private readonly Func<RedirectContext, Task> RedirectNotImpl = context => { throw new NotImplementedException("Redirect"); };
|
||||
private readonly Func<RemoteSignOutContext, Task> RemoteSignOutNotImpl = context => { throw new NotImplementedException("Remote"); };
|
||||
private readonly RequestDelegate AppNotImpl = context => { throw new NotImplementedException("App"); };
|
||||
|
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = TokenNotImpl,
|
||||
|
@ -75,6 +75,51 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(messageReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnMessageReceived_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = TokenNotImpl,
|
||||
OnAuthorizationCodeReceived = CodeNotImpl,
|
||||
OnTokenResponseReceived = TokenResponseNotImpl,
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnMessageReceived_Handled_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -124,7 +169,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = CodeNotImpl,
|
||||
|
@ -151,6 +196,57 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(tokenValidated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnTokenValidated_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var tokenValidated = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = CodeNotImpl,
|
||||
OnTokenResponseReceived = TokenResponseNotImpl,
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "id_token=my_id_token&state=protected_state");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(tokenValidated);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnTokenValidated_HandledWithoutTicket_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -167,7 +263,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
tokenValidated = true;
|
||||
context.HandleResponse();
|
||||
context.Ticket = null;
|
||||
context.Principal = null;
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
|
@ -209,8 +305,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
context.HandleResponse();
|
||||
// context.Ticket = null;
|
||||
context.Success();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = CodeNotImpl,
|
||||
|
@ -262,7 +357,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = TokenResponseNotImpl,
|
||||
|
@ -289,6 +384,63 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(codeReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnAuthorizationCodeReceived_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var tokenValidated = false;
|
||||
var codeReceived = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = TokenResponseNotImpl,
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "id_token=my_id_token&state=protected_state&code=my_code");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(tokenValidated);
|
||||
Assert.True(codeReceived);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnAuthorizationCodeReceived_HandledWithoutTicket_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -311,7 +463,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
codeReceived = true;
|
||||
context.HandleResponse();
|
||||
context.Ticket = null;
|
||||
context.Principal = null;
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
|
@ -358,8 +510,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
context.HandleResponse();
|
||||
// context.Ticket = null;
|
||||
context.Success();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = TokenResponseNotImpl,
|
||||
|
@ -417,7 +568,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
|
@ -444,6 +595,69 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(tokenResponseReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnTokenResponseReceived_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var tokenValidated = false;
|
||||
var codeReceived = false;
|
||||
var tokenResponseReceived = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "id_token=my_id_token&state=protected_state&code=my_code");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(tokenValidated);
|
||||
Assert.True(codeReceived);
|
||||
Assert.True(tokenResponseReceived);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnTokenResponseReceived_HandledWithoutTicket_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -471,7 +685,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
context.Ticket = null;
|
||||
context.Principal = null;
|
||||
context.HandleResponse();
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
|
@ -525,8 +739,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
// context.Ticket = null;
|
||||
context.HandleResponse();
|
||||
context.Success();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
|
@ -584,7 +797,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
|
@ -611,6 +824,69 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(tokenValidated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnTokenValidatedBackchannel_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var codeReceived = false;
|
||||
var tokenResponseReceived = false;
|
||||
var tokenValidated = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "state=protected_state&code=my_code");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(codeReceived);
|
||||
Assert.True(tokenResponseReceived);
|
||||
Assert.True(tokenValidated);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnTokenValidatedBackchannel_HandledWithoutTicket_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -638,7 +914,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
context.Ticket = null;
|
||||
context.Principal = null;
|
||||
context.HandleResponse();
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
|
@ -692,8 +968,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
// context.Ticket = null;
|
||||
context.HandleResponse();
|
||||
context.Success();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = UserNotImpl,
|
||||
|
@ -757,7 +1032,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnUserInformationReceived = context =>
|
||||
{
|
||||
userInfoReceived = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
|
@ -784,6 +1059,75 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(userInfoReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnUserInformationReceived_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var tokenValidated = false;
|
||||
var codeReceived = false;
|
||||
var tokenResponseReceived = false;
|
||||
var userInfoReceived = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = context =>
|
||||
{
|
||||
userInfoReceived = true;
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "id_token=my_id_token&state=protected_state&code=my_code");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(tokenValidated);
|
||||
Assert.True(codeReceived);
|
||||
Assert.True(tokenResponseReceived);
|
||||
Assert.True(userInfoReceived);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnUserInformationReceived_HandledWithoutTicket_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -817,7 +1161,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnUserInformationReceived = context =>
|
||||
{
|
||||
userInfoReceived = true;
|
||||
context.Ticket = null;
|
||||
context.Principal = null;
|
||||
context.HandleResponse();
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
|
@ -878,7 +1222,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
userInfoReceived = true;
|
||||
// context.Ticket = null;
|
||||
context.HandleResponse();
|
||||
context.Success();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthenticationFailed = FailedNotImpl,
|
||||
|
@ -949,7 +1293,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
authFailed = true;
|
||||
Assert.Equal("TestException", context.Exception.Message);
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = FailureNotImpl,
|
||||
|
@ -976,6 +1320,82 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
Assert.True(authFailed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnAuthenticationFailed_Reject_NoMoreEventsRun()
|
||||
{
|
||||
var messageReceived = false;
|
||||
var tokenValidated = false;
|
||||
var codeReceived = false;
|
||||
var tokenResponseReceived = false;
|
||||
var userInfoReceived = false;
|
||||
var authFailed = false;
|
||||
var remoteFailure = false;
|
||||
var server = CreateServer(new OpenIdConnectEvents()
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
messageReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
tokenValidated = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnAuthorizationCodeReceived = context =>
|
||||
{
|
||||
codeReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
tokenResponseReceived = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnUserInformationReceived = context =>
|
||||
{
|
||||
userInfoReceived = true;
|
||||
throw new NotImplementedException("TestException");
|
||||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
authFailed = true;
|
||||
Assert.Equal("TestException", context.Exception.Message);
|
||||
context.Fail("Authentication was aborted from user code.");
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = context =>
|
||||
{
|
||||
remoteFailure = true;
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
||||
OnRedirectToIdentityProvider = RedirectNotImpl,
|
||||
OnRedirectToIdentityProviderForSignOut = RedirectNotImpl,
|
||||
OnRemoteSignOut = RemoteSignOutNotImpl,
|
||||
},
|
||||
context =>
|
||||
{
|
||||
return context.Response.WriteAsync(context.Request.Path);
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(delegate
|
||||
{
|
||||
return PostAsync(server, "signin-oidc", "id_token=my_id_token&state=protected_state&code=my_code");
|
||||
});
|
||||
|
||||
Assert.Equal("Authentication was aborted from user code.", exception.Message);
|
||||
|
||||
Assert.True(messageReceived);
|
||||
Assert.True(tokenValidated);
|
||||
Assert.True(codeReceived);
|
||||
Assert.True(tokenResponseReceived);
|
||||
Assert.True(userInfoReceived);
|
||||
Assert.True(authFailed);
|
||||
Assert.True(remoteFailure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnAuthenticationFailed_HandledWithoutTicket_NoMoreEventsRun()
|
||||
{
|
||||
|
@ -1016,7 +1436,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
authFailed = true;
|
||||
Assert.Equal("TestException", context.Exception.Message);
|
||||
Assert.Null(context.Ticket);
|
||||
Assert.Null(context.Principal);
|
||||
context.HandleResponse();
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
return Task.FromResult(0);
|
||||
|
@ -1083,7 +1503,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
authFailed = true;
|
||||
Assert.Equal("TestException", context.Exception.Message);
|
||||
Assert.Null(context.Ticket);
|
||||
Assert.Null(context.Principal);
|
||||
|
||||
var claims = new[]
|
||||
{
|
||||
|
@ -1092,11 +1512,8 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
new Claim(ClaimsIdentity.DefaultNameClaimType, "bob")
|
||||
};
|
||||
|
||||
context.Ticket = new AuthenticationTicket(
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name)),
|
||||
new AuthenticationProperties(), context.Scheme.Name);
|
||||
|
||||
context.HandleResponse();
|
||||
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
|
||||
context.Success();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnRemoteFailure = FailureNotImpl,
|
||||
|
@ -1174,7 +1591,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
remoteFailure = true;
|
||||
Assert.Equal("TestException", context.Failure.Message);
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
OnTicketReceived = TicketNotImpl,
|
||||
|
@ -1314,7 +1731,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
OnTicketReceived = context =>
|
||||
{
|
||||
ticektReceived = true;
|
||||
context.Skip();
|
||||
context.SkipHandler();
|
||||
return Task.FromResult(0);
|
||||
},
|
||||
|
||||
|
@ -1408,8 +1825,9 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication();
|
||||
services.AddOpenIdConnectAuthentication(o =>
|
||||
services.AddAuthentication()
|
||||
.AddCookie()
|
||||
.AddOpenIdConnect(o =>
|
||||
{
|
||||
o.Events = events;
|
||||
o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
@ -11,10 +10,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Xunit;
|
||||
|
||||
|
|
|
@ -112,10 +112,10 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
services.AddAuthentication(o =>
|
||||
{
|
||||
o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
services.AddCookieAuthentication();
|
||||
services.AddOpenIdConnectAuthentication(options);
|
||||
services.AddAuthentication()
|
||||
.AddCookie()
|
||||
.AddOpenIdConnect(options);
|
||||
});
|
||||
|
||||
return new TestServer(builder);
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
// return Task.FromResult(0);
|
||||
// }
|
||||
|
||||
// public Task ChallengeAsync(ChallengeContext context)
|
||||
// public Task ChallengeAsync(AuthenticationProperties properties)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
@ -144,12 +144,12 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public Task SignInAsync(SignInContext context)
|
||||
// public Task SignInAsync(ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public Task SignOutAsync(SignOutContext context)
|
||||
// public Task SignOutAsync(AuthenticationProperties properties)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
|
@ -13,7 +12,6 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||
|
@ -177,15 +175,15 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
var res = context.Response;
|
||||
if (req.Path == new PathString("/signIn"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignInAsync("Twitter", new ClaimsPrincipal()));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignInAsync("Twitter", new ClaimsPrincipal()));
|
||||
}
|
||||
else if (req.Path == new PathString("/signOut"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.SignOutAsync("Twitter"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.SignOutAsync("Twitter"));
|
||||
}
|
||||
else if (req.Path == new PathString("/forbid"))
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(() => context.ForbidAsync("Twitter"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.ForbidAsync("Twitter"));
|
||||
}
|
||||
else if (handler == null || !handler(context))
|
||||
{
|
||||
|
@ -195,13 +193,14 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication("External", _ => { });
|
||||
Action<TwitterOptions> wrapOptions = o =>
|
||||
{
|
||||
o.SignInScheme = "External";
|
||||
options(o);
|
||||
};
|
||||
services.AddTwitterAuthentication(wrapOptions);
|
||||
services.AddAuthentication()
|
||||
.AddCookie("External", _ => { })
|
||||
.AddTwitter(wrapOptions);
|
||||
});
|
||||
return new TestServer(builder);
|
||||
}
|
||||
|
|
|
@ -312,7 +312,7 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
|||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication(o =>
|
||||
services.AddAuthentication().AddCookie(o =>
|
||||
{
|
||||
o.CookieName = "TestCookie";
|
||||
o.CookieHttpOnly = false;
|
||||
|
@ -352,7 +352,7 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
|||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddCookieAuthentication(o =>
|
||||
services.AddAuthentication().AddCookie(o =>
|
||||
{
|
||||
o.CookieName = "TestCookie";
|
||||
o.CookieHttpOnly = false;
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Microsoft.Owin.Security.Interop
|
|||
await context.Response.WriteAsync(result.Ticket.Principal.Identity.Name);
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/login");
|
||||
|
@ -123,7 +123,7 @@ namespace Microsoft.Owin.Security.Interop
|
|||
await context.Response.WriteAsync(result.Ticket.Principal.Identity.Name);
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/login");
|
||||
|
@ -155,7 +155,7 @@ namespace Microsoft.Owin.Security.Interop
|
|||
app.UseAuthentication();
|
||||
app.Run(context => context.SignInAsync("Cookies", user));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var cookies = await SendAndGetCookies(newServer, "http://example.com/login");
|
||||
|
@ -202,7 +202,7 @@ namespace Microsoft.Owin.Security.Interop
|
|||
app.UseAuthentication();
|
||||
app.Run(context => context.SignInAsync("Cookies", user));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var cookies = await SendAndGetCookies(newServer, "http://example.com/login");
|
||||
|
|
Загрузка…
Ссылка в новой задаче