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); } } }