using System;
using System.Diagnostics.CodeAnalysis;
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>
/// Initializes a new instance of <see cref="AuthenticationBuilder"/>.
/// </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; }
private AuthenticationBuilder AddSchemeHelper<TOptions, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]THandler>(string authenticationScheme, string? displayName, Action<TOptions>? configureOptions)
where TOptions : AuthenticationSchemeOptions, new()
where THandler : class, IAuthenticationHandler
{
Services.Configure<AuthenticationOptions>(o =>
{
o.AddScheme(authenticationScheme, scheme => {
scheme.HandlerType = typeof(THandler);
scheme.DisplayName = displayName;
});
});
if (configureOptions != null)
{
Services.Configure(authenticationScheme, configureOptions);
}
Services.AddOptions<TOptions>(authenticationScheme).Validate(o => {
o.Validate(authenticationScheme);
return true;
});
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="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, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]THandler>(string authenticationScheme, string? displayName, Action<TOptions>? configureOptions)
where TOptions : AuthenticationSchemeOptions, new()
where THandler : AuthenticationHandler<TOptions>
=> AddSchemeHelper<TOptions, THandler>(authenticationScheme, displayName, configureOptions);
/// <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, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]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, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]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);
}
/// <summary>
/// Adds a <see cref="PolicySchemeHandler"/> based authentication handler which can be used to
/// redirect to other authentication schemes.
/// </summary>
/// <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 AddPolicyScheme(string authenticationScheme, string? displayName, Action<PolicySchemeOptions> configureOptions)
=> AddSchemeHelper<PolicySchemeOptions, PolicySchemeHandler>(authenticationScheme, displayName, configureOptions);
// Used to ensure that there's always a default sign in scheme that's not itself
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 ??= _authOptions.DefaultSignInScheme ?? _authOptions.DefaultScheme;
}
}
}
}
using System;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods to configure cookie authentication.
/// </summary>
public static class CookieExtensions
{
/// <summary>
/// Adds cookie authentication to <see cref="AuthenticationBuilder"/> using the default scheme.
/// The default scheme is specified by <see cref="CookieAuthenticationDefaults.AuthenticationScheme"/>.
/// <para>
/// Cookie authentication uses a HTTP cookie persisted in the client to perform authentication.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder)
=> builder.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
/// <summary>
/// Adds cookie authentication to <see cref="AuthenticationBuilder"/> using the specified scheme.
/// <para>
/// Cookie authentication uses a HTTP cookie persisted in the client to perform authentication.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="authenticationScheme">The authentication scheme.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme)
=> builder.AddCookie(authenticationScheme, configureOptions: null!);
/// <summary>
/// Adds cookie authentication to <see cref="AuthenticationBuilder"/> using the default scheme.
/// The default scheme is specified by <see cref="CookieAuthenticationDefaults.AuthenticationScheme"/>.
/// <para>
/// Cookie authentication uses a HTTP cookie persisted in the client to perform authentication.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="configureOptions">A delegate to configure <see cref="CookieAuthenticationOptions"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, Action<CookieAuthenticationOptions> configureOptions)
=> builder.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, configureOptions);
/// <summary>
/// Adds cookie authentication to <see cref="AuthenticationBuilder"/> using the specified scheme.
/// <para>
/// Cookie authentication uses a HTTP cookie persisted in the client to perform authentication.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="authenticationScheme">The authentication scheme.</param>
/// <param name="configureOptions">A delegate to configure <see cref="CookieAuthenticationOptions"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, Action<CookieAuthenticationOptions> configureOptions)
=> builder.AddCookie(authenticationScheme, displayName: null, configureOptions: configureOptions);
/// <summary>
/// Adds cookie authentication to <see cref="AuthenticationBuilder"/> using the specified scheme.
/// <para>
/// Cookie authentication uses a HTTP cookie persisted in the client to perform authentication.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="authenticationScheme">The authentication scheme.</param>
/// <param name="displayName">A display name for the authentication handler.</param>
/// <param name="configureOptions">A delegate to configure <see cref="CookieAuthenticationOptions"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, string? displayName, Action<CookieAuthenticationOptions> configureOptions)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
builder.Services.AddOptions<CookieAuthenticationOptions>(authenticationScheme).Validate(o => o.Cookie.Expiration == null, "Cookie.Expiration is ignored, use ExpireTimeSpan instead.");
return builder.AddScheme<CookieAuthenticationOptions, CookieAuthenticationHandler>(authenticationScheme, displayName, configureOptions);
}
}
}
using System;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods to configure JWT bearer authentication.
/// </summary>
public static class JwtBearerExtensions
{
/// <summary>
/// Enables JWT-bearer authentication using the default scheme <see cref="JwtBearerDefaults.AuthenticationScheme"/>.
/// <para>
/// JWT bearer authentication performs authentication by extracting and validating a JWT token from the <c>Authorization</c> request header.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder)
=> builder.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, _ => { });
/// <summary>
/// Enables JWT-bearer authentication using the default scheme <see cref="JwtBearerDefaults.AuthenticationScheme"/>.
/// <para>
/// JWT bearer authentication performs authentication by extracting and validating a JWT token from the <c>Authorization</c> request header.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="configureOptions">A delegate that allows configuring <see cref="JwtBearerOptions"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, Action<JwtBearerOptions> configureOptions)
=> builder.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, configureOptions);
/// <summary>
/// Enables JWT-bearer authentication using the specified scheme.
/// <para>
/// JWT bearer authentication performs authentication by extracting and validating a JWT token from the <c>Authorization</c> request header.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="authenticationScheme">The authentication scheme.</param>
/// <param name="configureOptions">A delegate that allows configuring <see cref="JwtBearerOptions"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, string authenticationScheme, Action<JwtBearerOptions> configureOptions)
=> builder.AddJwtBearer(authenticationScheme, displayName: null, configureOptions: configureOptions);
/// <summary>
/// Enables JWT-bearer authentication using the specified scheme.
/// <para>
/// JWT bearer authentication performs authentication by extracting and validating a JWT token from the <c>Authorization</c> request header.
/// </para>
/// </summary>
/// <param name="builder">The <see cref="AuthenticationBuilder"/>.</param>
/// <param name="authenticationScheme">The authentication scheme.</param>
/// <param name="displayName">The display name for the authentication handler.</param>
/// <param name="configureOptions">A delegate that allows configuring <see cref="JwtBearerOptions"/>.</param>
/// <returns>A reference to <paramref name="builder"/> after the operation has completed.</returns>
public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, string authenticationScheme, string? displayName, Action<JwtBearerOptions> configureOptions)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>, JwtBearerPostConfigureOptions>());
return builder.AddScheme<JwtBearerOptions, JwtBearerHandler>(authenticationScheme, displayName, configureOptions);
}
}
}