diff --git a/HttpAbstractions.sln b/HttpAbstractions.sln
index 9525343a..6434e357 100644
--- a/HttpAbstractions.sln
+++ b/HttpAbstractions.sln
@@ -57,6 +57,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{ED7BCAC5
build\Key.snk = build\Key.snk
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Abstractions", "src\Microsoft.AspNetCore.Authentication.Abstractions\Microsoft.AspNetCore.Authentication.Abstractions.csproj", "{3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Core", "src\Microsoft.AspNetCore.Authentication.Core\Microsoft.AspNetCore.Authentication.Core.csproj", "{73CA3145-91BD-4DA5-BC74-40008DE7EA98}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Core.Test", "test\Microsoft.AspNetCore.Authentication.Core.Test\Microsoft.AspNetCore.Authentication.Core.Test.csproj", "{A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -223,6 +229,42 @@ Global
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|x86.ActiveCfg = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|x86.Build.0 = Release|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Debug|x86.Build.0 = Debug|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852}.Release|x86.Build.0 = Release|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Debug|x86.Build.0 = Debug|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Release|Any CPU.Build.0 = Release|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Release|x86.ActiveCfg = Release|Any CPU
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98}.Release|x86.Build.0 = Release|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Debug|x86.Build.0 = Debug|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Release|x86.ActiveCfg = Release|Any CPU
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -244,5 +286,8 @@ Global
{E6BB7AD1-BD10-4A23-B780-F4A86ADF00D1} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
{1D0764B4-1DEB-4232-A714-D4B7E846918A} = {982F09D8-621E-4872-BA7B-BBDEA47D1EFD}
{ED7BCAC5-2796-44BD-9954-7C248263BC8B} = {C6C48D5F-B289-4150-A6FC-77A5C7064BCE}
+ {3D8C9A87-5DFB-4EC0-9CB6-174AD3B33852} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
+ {73CA3145-91BD-4DA5-BC74-40008DE7EA98} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
+ {A85950C5-2794-47E2-8EAA-05A1DC7C6DA7} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
EndGlobalSection
EndGlobal
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticateContext.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticateContext.cs
new file mode 100644
index 00000000..814d7024
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticateContext.cs
@@ -0,0 +1,21 @@
+// 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
+{
+ ///
+ /// Base class used by methods.
+ ///
+ public class AuthenticateContext : BaseAuthenticationContext
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ public AuthenticateContext(HttpContext context, string authenticationScheme) : base(context, authenticationScheme, properties: null)
+ { }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticateResult.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticateResult.cs
new file mode 100644
index 00000000..bb9bbb97
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticateResult.cs
@@ -0,0 +1,105 @@
+// 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;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Contains the result of an Authenticate call
+ ///
+ public class AuthenticateResult
+ {
+ private AuthenticateResult() { }
+
+ ///
+ /// If a ticket was produced, authenticate was successful.
+ ///
+ public bool Succeeded => Ticket != null;
+
+ ///
+ /// The authentication ticket.
+ ///
+ public AuthenticationTicket Ticket { get; private set; }
+
+ ///
+ /// Gets the claims-principal with authenticated user identities.
+ ///
+ public ClaimsPrincipal Principal => Ticket?.Principal;
+
+ ///
+ /// Additional state values for the authentication session.
+ ///
+ public AuthenticationProperties Properties => Ticket?.Properties;
+
+ ///
+ /// Holds failure information from the authentication.
+ ///
+ public Exception Failure { get; private set; }
+
+ ///
+ /// Indicates that stage of authentication was directly handled by user intervention and no
+ /// further processing should be attempted.
+ ///
+ public bool Handled { get; private set; }
+
+ ///
+ /// Indicates that there was no information returned for this authentication scheme.
+ ///
+ public bool Nothing { get; private set; }
+
+ ///
+ /// Indicates that authentication was successful.
+ ///
+ /// The ticket representing the authentication result.
+ /// The result.
+ public static AuthenticateResult Success(AuthenticationTicket ticket)
+ {
+ if (ticket == null)
+ {
+ throw new ArgumentNullException(nameof(ticket));
+ }
+ return new AuthenticateResult() { Ticket = ticket };
+ }
+
+ ///
+ /// Indicates that stage of authentication was directly handled by user intervention and no
+ /// further processing should be attempted.
+ ///
+ /// The result.
+ public static AuthenticateResult Handle()
+ {
+ return new AuthenticateResult() { Handled = true };
+ }
+
+ ///
+ /// Indicates that there was no information returned for this authentication scheme.
+ ///
+ /// The result.
+ public static AuthenticateResult None()
+ {
+ return new AuthenticateResult() { Nothing = true };
+ }
+
+ ///
+ /// Indicates that there was a failure during authentication.
+ ///
+ /// The failure exception.
+ /// The result.
+ public static AuthenticateResult Fail(Exception failure)
+ {
+ return new AuthenticateResult() { Failure = failure };
+ }
+
+ ///
+ /// Indicates that there was a failure during authentication.
+ ///
+ /// The failure message.
+ /// The result.
+ public static AuthenticateResult Fail(string failureMessage)
+ {
+ return new AuthenticateResult() { Failure = new Exception(failureMessage) };
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationHttpContextExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationHttpContextExtensions.cs
new file mode 100644
index 00000000..a1fd3756
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationHttpContextExtensions.cs
@@ -0,0 +1,158 @@
+// 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 System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Extension methods to expose Authentication on HttpContext.
+ ///
+ public static class AuthenticationHttpContextExtensions
+ {
+ ///
+ /// Extension method for authenticate using the scheme.
+ ///
+ /// The context.
+ /// The .
+ public static Task AuthenticateAsync(this HttpContext context) =>
+ context.AuthenticateAsync(scheme: null);
+
+ ///
+ /// Extension method for authenticate.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The .
+ public static Task AuthenticateAsync(this HttpContext context, string scheme) =>
+ context.RequestServices.GetRequiredService().AuthenticateAsync(context, scheme);
+
+ ///
+ /// Extension method for Challenge.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The result.
+ public static Task ChallengeAsync(this HttpContext context, string scheme) =>
+ context.ChallengeAsync(scheme, properties: null);
+
+ ///
+ /// Extension method for authenticate using the scheme.
+ ///
+ /// The context.
+ /// The task.
+ public static Task ChallengeAsync(this HttpContext context) =>
+ context.ChallengeAsync(scheme: null, properties: null);
+
+ ///
+ /// Extension method for Challenge.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The properties.
+ /// The task.
+ public static Task ChallengeAsync(this HttpContext context, string scheme, AuthenticationProperties properties) =>
+ context.ChallengeAsync(scheme, properties: properties, behavior: ChallengeBehavior.Automatic);
+
+ ///
+ /// Extension method for Challenge.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The properties.
+ /// The behavior.
+ /// The task.
+ public static Task ChallengeAsync(this HttpContext context, string scheme, AuthenticationProperties properties, ChallengeBehavior behavior) =>
+ context.RequestServices.GetRequiredService().ChallengeAsync(context, scheme, properties, behavior);
+
+ ///
+ /// Extension method for Forbid.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The task.
+ public static Task ForbidAsync(this HttpContext context, string scheme) =>
+ context.ForbidAsync(scheme, properties: null);
+
+ ///
+ /// Extension method for Forbid.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The properties.
+ /// The task.
+ public static Task ForbidAsync(this HttpContext context, string scheme, AuthenticationProperties properties) =>
+ context.RequestServices.GetRequiredService().ChallengeAsync(context, scheme, properties, ChallengeBehavior.Forbidden);
+
+ ///
+ /// Extension method for SignIn.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The user.
+ /// The task.
+ public static Task SignInAsync(this HttpContext context, string scheme, ClaimsPrincipal principal) =>
+ context.SignInAsync(scheme, principal, properties: null);
+
+ ///
+ /// Extension method for SignIn using the .
+ ///
+ /// The context.
+ /// The user.
+ /// The task.
+ public static Task SignInAsync(this HttpContext context, ClaimsPrincipal principal) =>
+ context.SignInAsync(scheme: null, principal: principal, properties: null);
+
+ ///
+ /// Extension method for SignIn using the .
+ ///
+ /// The context.
+ /// The user.
+ /// The properties.
+ /// The task.
+ public static Task SignInAsync(this HttpContext context, ClaimsPrincipal principal, AuthenticationProperties properties) =>
+ context.SignInAsync(scheme: null, principal: principal, properties: properties);
+
+ ///
+ /// Extension method for SignIn.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The user.
+ /// The properties.
+ /// The task.
+ public static Task SignInAsync(this HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) =>
+ context.RequestServices.GetRequiredService().SignInAsync(context, scheme, principal, properties);
+
+ ///
+ /// Extension method for SignOut.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The task.
+ public static Task SignOutAsync(this HttpContext context, string scheme) => context.SignOutAsync(scheme, properties: null);
+
+ ///
+ /// Extension method for SignOut.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The properties.
+ ///
+ public static Task SignOutAsync(this HttpContext context, string scheme, AuthenticationProperties properties) =>
+ context.RequestServices.GetRequiredService().SignOutAsync(context, scheme, properties);
+
+ ///
+ /// Extension method for getting the value of an authentication token.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The name of the token.
+ /// The value of the token.
+ public static Task GetTokenAsync(this HttpContext context, string scheme, string tokenName) =>
+ context.RequestServices.GetRequiredService().GetTokenAsync(context, scheme, tokenName);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs
new file mode 100644
index 00000000..5f688d0f
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs
@@ -0,0 +1,64 @@
+// 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.Collections.Generic;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ public class AuthenticationOptions
+ {
+ private readonly IList _schemes = new List();
+
+ ///
+ /// Returns the schemes in the order they were added (important for request handling priority)
+ ///
+ public IEnumerable Schemes => _schemes;
+
+ ///
+ /// Maps schemes by name.
+ ///
+ public IDictionary SchemeMap { get; } = new Dictionary(StringComparer.Ordinal);
+
+ ///
+ /// Adds an .
+ ///
+ /// The name of the scheme being added.
+ /// Configures the scheme.
+ public void AddScheme(string name, Action configureBuilder)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (configureBuilder == null)
+ {
+ throw new ArgumentNullException(nameof(configureBuilder));
+ }
+ if (SchemeMap.ContainsKey(name))
+ {
+ throw new InvalidOperationException("Scheme already exists: " + name);
+ }
+
+ var builder = new AuthenticationSchemeBuilder(name);
+ configureBuilder(builder);
+ _schemes.Add(builder);
+ SchemeMap[name] = builder;
+ }
+
+ ///
+ /// Used by as the default scheme by .
+ ///
+ public string DefaultAuthenticationScheme { get; set; }
+
+ ///
+ /// Used by as the default scheme by .
+ ///
+ public string DefaultSignInScheme { get; set; }
+
+ ///
+ /// Used by as the default scheme by .
+ ///
+ public string DefaultChallengeScheme { get; set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationProperties.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationProperties.cs
new file mode 100644
index 00000000..609b6fad
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationProperties.cs
@@ -0,0 +1,197 @@
+// 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.Collections.Generic;
+using System.Globalization;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Dictionary used to store state values about the authentication session.
+ ///
+ public class AuthenticationProperties
+ {
+ internal const string IssuedUtcKey = ".issued";
+ internal const string ExpiresUtcKey = ".expires";
+ internal const string IsPersistentKey = ".persistent";
+ internal const string RedirectUriKey = ".redirect";
+ internal const string RefreshKey = ".refresh";
+ internal const string UtcDateTimeFormat = "r";
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ public AuthenticationProperties()
+ : this(items: null)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ ///
+ public AuthenticationProperties(IDictionary items)
+ {
+ Items = items ?? new Dictionary(StringComparer.Ordinal);
+ }
+
+ ///
+ /// State values about the authentication session.
+ ///
+ public IDictionary Items { get; }
+
+ ///
+ /// Gets or sets whether the authentication session is persisted across multiple requests.
+ ///
+ public bool IsPersistent
+ {
+ get { return Items.ContainsKey(IsPersistentKey); }
+ set
+ {
+ if (Items.ContainsKey(IsPersistentKey))
+ {
+ if (!value)
+ {
+ Items.Remove(IsPersistentKey);
+ }
+ }
+ else
+ {
+ if (value)
+ {
+ Items.Add(IsPersistentKey, string.Empty);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the full path or absolute URI to be used as an http redirect response value.
+ ///
+ public string RedirectUri
+ {
+ get
+ {
+ string value;
+ return Items.TryGetValue(RedirectUriKey, out value) ? value : null;
+ }
+ set
+ {
+ if (value != null)
+ {
+ Items[RedirectUriKey] = value;
+ }
+ else
+ {
+ if (Items.ContainsKey(RedirectUriKey))
+ {
+ Items.Remove(RedirectUriKey);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the time at which the authentication ticket was issued.
+ ///
+ public DateTimeOffset? IssuedUtc
+ {
+ get
+ {
+ string value;
+ if (Items.TryGetValue(IssuedUtcKey, out value))
+ {
+ DateTimeOffset dateTimeOffset;
+ if (DateTimeOffset.TryParseExact(value, UtcDateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
+ {
+ return dateTimeOffset;
+ }
+ }
+ return null;
+ }
+ set
+ {
+ if (value.HasValue)
+ {
+ Items[IssuedUtcKey] = value.Value.ToString(UtcDateTimeFormat, CultureInfo.InvariantCulture);
+ }
+ else
+ {
+ if (Items.ContainsKey(IssuedUtcKey))
+ {
+ Items.Remove(IssuedUtcKey);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the time at which the authentication ticket expires.
+ ///
+ public DateTimeOffset? ExpiresUtc
+ {
+ get
+ {
+ string value;
+ if (Items.TryGetValue(ExpiresUtcKey, out value))
+ {
+ DateTimeOffset dateTimeOffset;
+ if (DateTimeOffset.TryParseExact(value, UtcDateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
+ {
+ return dateTimeOffset;
+ }
+ }
+ return null;
+ }
+ set
+ {
+ if (value.HasValue)
+ {
+ Items[ExpiresUtcKey] = value.Value.ToString(UtcDateTimeFormat, CultureInfo.InvariantCulture);
+ }
+ else
+ {
+ if (Items.ContainsKey(ExpiresUtcKey))
+ {
+ Items.Remove(ExpiresUtcKey);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets if refreshing the authentication session should be allowed.
+ ///
+ public bool? AllowRefresh
+ {
+ get
+ {
+ string value;
+ if (Items.TryGetValue(RefreshKey, out value))
+ {
+ bool refresh;
+ if (bool.TryParse(value, out refresh))
+ {
+ return refresh;
+ }
+ }
+ return null;
+ }
+ set
+ {
+ if (value.HasValue)
+ {
+ Items[RefreshKey] = value.Value.ToString();
+ }
+ else
+ {
+ if (Items.ContainsKey(RefreshKey))
+ {
+ Items.Remove(RefreshKey);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationScheme.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationScheme.cs
new file mode 100644
index 00000000..4d30dd11
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationScheme.cs
@@ -0,0 +1,50 @@
+// 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.Reflection;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// AuthenticationSchemes are basically a name for a specific
+ /// handlerType.
+ ///
+ public class AuthenticationScheme
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The name for the authentication scheme.
+ /// The type that handles this scheme.
+ public AuthenticationScheme(string name, Type handlerType)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (handlerType == null)
+ {
+ throw new ArgumentNullException(nameof(handlerType));
+ }
+ if (!typeof(IAuthenticationHandler).IsAssignableFrom(handlerType))
+ {
+ throw new ArgumentException("handlerType must implement IAuthenticationSchemeHandler.");
+ }
+
+ Name = name;
+ HandlerType = handlerType;
+ }
+
+ // TODO: add display name?
+ ///
+ /// The name of the authentication scheme.
+ ///
+ public string Name { get; }
+
+ ///
+ /// The type that handles this scheme.
+ ///
+ public Type HandlerType { get; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationSchemeBuilder.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationSchemeBuilder.cs
new file mode 100644
index 00000000..e1ea0cbc
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationSchemeBuilder.cs
@@ -0,0 +1,38 @@
+// 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
+{
+ ///
+ /// Used to build s.
+ ///
+ public class AuthenticationSchemeBuilder
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The name of the scheme being built.
+ public AuthenticationSchemeBuilder(string name)
+ {
+ Name = name;
+ }
+
+ ///
+ /// The name of the scheme being built.
+ ///
+ public string Name { get; }
+
+ ///
+ /// The type responsible for this scheme.
+ ///
+ public Type HandlerType { get; set; }
+
+ ///
+ /// Builds the instance.
+ ///
+ ///
+ public AuthenticationScheme Build() => new AuthenticationScheme(Name, HandlerType);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationTicket.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationTicket.cs
new file mode 100644
index 00000000..c31f15ec
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationTicket.cs
@@ -0,0 +1,56 @@
+// 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;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Contains user identity information as well as additional authentication state.
+ ///
+ public class AuthenticationTicket
+ {
+ ///
+ /// Initializes a new instance of the class
+ ///
+ /// the that represents the authenticated user.
+ /// additional properties that can be consumed by the user or runtime.
+ /// the authentication middleware that was responsible for this ticket.
+ public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationScheme)
+ {
+ if (principal == null)
+ {
+ throw new ArgumentNullException(nameof(principal));
+ }
+
+ AuthenticationScheme = authenticationScheme;
+ Principal = principal;
+ Properties = properties ?? new AuthenticationProperties();
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ /// the that represents the authenticated user.
+ /// the authentication middleware that was responsible for this ticket.
+ public AuthenticationTicket(ClaimsPrincipal principal, string authenticationScheme)
+ : this(principal, properties: null, authenticationScheme: authenticationScheme)
+ { }
+
+ ///
+ /// Gets the authentication type.
+ ///
+ public string AuthenticationScheme { get; private set; }
+
+ ///
+ /// Gets the claims-principal with authenticated user identities.
+ ///
+ public ClaimsPrincipal Principal { get; private set; }
+
+ ///
+ /// Additional state values for the authentication session.
+ ///
+ public AuthenticationProperties Properties { get; private set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationToken.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationToken.cs
new file mode 100644
index 00000000..555da9e0
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationToken.cs
@@ -0,0 +1,22 @@
+// 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
+{
+ ///
+ /// Name/Value representing an token.
+ ///
+ public class AuthenticationToken
+ {
+ ///
+ /// Name.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Value.
+ ///
+ public string Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/BaseAuthenticationContext.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/BaseAuthenticationContext.cs
new file mode 100644
index 00000000..cfe5809c
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/BaseAuthenticationContext.cs
@@ -0,0 +1,41 @@
+// 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
+{
+ ///
+ /// Base context for authentication.
+ ///
+ public abstract class BaseAuthenticationContext : BaseContext
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The context.
+ /// The name of the scheme.
+ /// The properties.
+ 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();
+ }
+
+ ///
+ /// The name of the scheme.
+ ///
+ public string AuthenticationScheme { get; }
+
+ ///
+ /// Contains the extra meta-data arriving with the authentication. May be altered.
+ ///
+ public AuthenticationProperties Properties { get; protected set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/BaseContext.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/BaseContext.cs
new file mode 100644
index 00000000..3d65f0dd
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/BaseContext.cs
@@ -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 Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Base class used by other context classes.
+ ///
+ public abstract class BaseContext
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The request context.
+ protected BaseContext(HttpContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ HttpContext = context;
+ }
+
+ ///
+ /// The context.
+ ///
+ public HttpContext HttpContext { get; }
+
+ ///
+ /// The request.
+ ///
+ public HttpRequest Request
+ {
+ get { return HttpContext.Request; }
+ }
+
+ ///
+ /// The response.
+ ///
+ public HttpResponse Response
+ {
+ get { return HttpContext.Response; }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/ChallengeBehavior.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/ChallengeBehavior.cs
new file mode 100644
index 00000000..1506021d
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/ChallengeBehavior.cs
@@ -0,0 +1,15 @@
+// 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
+{
+ ///
+ /// Controls how challenge will behave (i.e. 401 vs 403).
+ ///
+ public enum ChallengeBehavior
+ {
+ Automatic,
+ Unauthorized,
+ Forbidden
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/ChallengeContext.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/ChallengeContext.cs
new file mode 100644
index 00000000..ee2392eb
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/ChallengeContext.cs
@@ -0,0 +1,45 @@
+// 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
+{
+ ///
+ /// Context used for challenges.
+ ///
+ public class ChallengeContext : BaseAuthenticationContext
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The context.
+ /// The name of the scheme.
+ public ChallengeContext(HttpContext httpContext, string authenticationScheme)
+ : this(httpContext, authenticationScheme, properties: null, behavior: ChallengeBehavior.Automatic)
+ { }
+
+ ///
+ /// Constructor
+ ///
+ /// The context.
+ /// The name of the scheme.
+ /// The properties.
+ /// The challenge behavior.
+ public ChallengeContext(HttpContext httpContext, string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior)
+ : base(httpContext, authenticationScheme, properties)
+ {
+ if (string.IsNullOrEmpty(authenticationScheme))
+ {
+ throw new ArgumentException(nameof(authenticationScheme));
+ }
+ Behavior = behavior;
+ }
+
+ ///
+ /// The challenge behavior.
+ ///
+ public ChallengeBehavior Behavior { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationFeature.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationFeature.cs
new file mode 100644
index 00000000..43e5a13b
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationFeature.cs
@@ -0,0 +1,23 @@
+// 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
+{
+ ///
+ /// Used to capture path info so redirects can be computed properly within an app.Map().
+ ///
+ public interface IAuthenticationFeature
+ {
+ ///
+ /// The original path base.
+ ///
+ PathString OriginalPathBase { get; set; }
+
+ ///
+ /// The original path.
+ ///
+ PathString OriginalPath { get; set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationHandler.cs
new file mode 100644
index 00000000..7a805f7a
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationHandler.cs
@@ -0,0 +1,50 @@
+// 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.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Created per request to handle authentication for to a particular scheme.
+ ///
+ public interface IAuthenticationHandler
+ {
+ ///
+ /// The handler should initialize anything it needs from the request and scheme here.
+ ///
+ /// The scheme.
+ /// The context.
+ ///
+ Task InitializeAsync(AuthenticationScheme scheme, HttpContext context);
+
+ ///
+ /// Authentication behavior.
+ ///
+ /// The context.
+ /// The result.
+ Task AuthenticateAsync(AuthenticateContext context);
+
+ ///
+ /// Challenge behavior.
+ ///
+ /// The context.
+ /// A task.
+ Task ChallengeAsync(ChallengeContext context);
+
+ ///
+ /// Handle sign in.
+ ///
+ /// The context.
+ /// A task.
+ Task SignInAsync(SignInContext context);
+
+ ///
+ /// Signout behavior.
+ ///
+ /// The context.
+ /// A task.
+ Task SignOutAsync(SignOutContext context);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationHandlerProvider.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationHandlerProvider.cs
new file mode 100644
index 00000000..0507f51d
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationHandlerProvider.cs
@@ -0,0 +1,22 @@
+// 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.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Provides the appropriate IAuthenticationHandler instance for the authenticationScheme and request.
+ ///
+ public interface IAuthenticationHandlerProvider
+ {
+ ///
+ /// Returns the handler instance that will be used.
+ ///
+ /// The context.
+ /// The name of the authentication scheme being handled.
+ /// The handler instance.
+ Task GetHandlerAsync(HttpContext context, string authenticationScheme);
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationRequestHandler.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationRequestHandler.cs
new file mode 100644
index 00000000..fffe08f4
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationRequestHandler.cs
@@ -0,0 +1,21 @@
+// 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.Threading.Tasks;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Used to determine if a handler wants to participate in request processing.
+ ///
+ public interface IAuthenticationRequestHandler : IAuthenticationHandler
+ {
+
+ ///
+ /// Returns true if request processing should stop.
+ ///
+ ///
+ Task HandleRequestAsync();
+ }
+
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs
new file mode 100644
index 00000000..4b36abda
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs
@@ -0,0 +1,70 @@
+// 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.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Responsible for managing what authenticationSchemes are supported.
+ ///
+ public interface IAuthenticationSchemeProvider
+ {
+ ///
+ /// Returns all currently registered s.
+ ///
+ /// All currently registered s.
+ Task> GetAllSchemesAsync();
+
+ ///
+ /// Returns the matching the name, or null.
+ ///
+ /// The name of the authenticationScheme.
+ /// The scheme or null if not found.
+ Task GetSchemeAsync(string name);
+
+ ///
+ /// Returns the scheme that will be used by default for .
+ /// This is typically specified via .
+ /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ ///
+ /// The scheme that will be used by default for .
+ Task GetDefaultAuthenticateSchemeAsync();
+
+ ///
+ /// Returns the scheme that will be used by default for .
+ /// This is typically specified via .
+ /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ ///
+ /// The scheme that will be used by default for .
+ Task GetDefaultChallengeSchemeAsync();
+
+ ///
+ /// Returns the scheme that will be used by default for .
+ /// This is typically specified via .
+ /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ ///
+ /// The scheme that will be used by default for .
+ Task GetDefaultSignInSchemeAsync();
+
+ ///
+ /// Registers a scheme for use by .
+ ///
+ /// The scheme.
+ void AddScheme(AuthenticationScheme scheme);
+
+ ///
+ /// Removes a scheme, preventing it from being used by .
+ ///
+ /// The name of the authenticationScheme being removed.
+ void RemoveScheme(string name);
+
+ ///
+ /// Returns the schemes in priority order for request handling.
+ ///
+ /// The schemes in priority order for request handling
+ Task> GetRequestHandlerSchemesAsync();
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationService.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationService.cs
new file mode 100644
index 00000000..ec54325e
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationService.cs
@@ -0,0 +1,52 @@
+// 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 System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Used to provide authentication.
+ ///
+ public interface IAuthenticationService
+ {
+ ///
+ /// Authenticate for the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The result.
+ Task AuthenticateAsync(HttpContext context, string scheme);
+
+ ///
+ /// Challenge the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The .
+ /// The .
+ /// A task.
+ Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties, ChallengeBehavior behavior);
+
+ ///
+ /// Sign a principal in for the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The to sign in.
+ /// The .
+ /// A task.
+ Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties);
+
+ ///
+ /// Sign out the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The .
+ /// A task.
+ Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IClaimsTransformation.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IClaimsTransformation.cs
new file mode 100644
index 00000000..3aed710a
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IClaimsTransformation.cs
@@ -0,0 +1,21 @@
+// 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 System.Threading.Tasks;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Used by the for claims transformation.
+ ///
+ public interface IClaimsTransformation
+ {
+ ///
+ /// Provides a central transformation point to change the specified principal.
+ ///
+ /// The to transform.
+ /// The transformed principal.
+ Task TransformAsync(ClaimsPrincipal principal);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/Microsoft.AspNetCore.Authentication.Abstractions.csproj b/src/Microsoft.AspNetCore.Authentication.Abstractions/Microsoft.AspNetCore.Authentication.Abstractions.csproj
new file mode 100644
index 00000000..aa2fae7f
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/Microsoft.AspNetCore.Authentication.Abstractions.csproj
@@ -0,0 +1,24 @@
+
+
+
+ ASP.NET Core common types used by the various authentication components.
+ netstandard1.3;net46
+ $(NoWarn);CS1591
+ true
+ aspnetcore;authentication;security
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/SignInContext.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/SignInContext.cs
new file mode 100644
index 00000000..e89b663a
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/SignInContext.cs
@@ -0,0 +1,37 @@
+// 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
+{
+ ///
+ /// Context used for sign out.
+ ///
+ public class SignInContext : BaseAuthenticationContext
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The user to sign in.
+ /// The properties.
+ public SignInContext(HttpContext context, string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties)
+ : base(context, authenticationScheme, properties)
+ {
+ if (principal == null)
+ {
+ throw new ArgumentNullException(nameof(principal));
+ }
+ Principal = principal;
+ }
+
+ ///
+ /// The user to sign in.
+ ///
+ public ClaimsPrincipal Principal { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/SignOutContext.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/SignOutContext.cs
new file mode 100644
index 00000000..307a3af8
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/SignOutContext.cs
@@ -0,0 +1,23 @@
+// 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
+{
+ ///
+ /// Context used to sign out.
+ ///
+ public class SignOutContext : BaseAuthenticationContext
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The properties.
+ public SignOutContext(HttpContext context, string authenticationScheme, AuthenticationProperties properties)
+ : base(context, authenticationScheme, properties)
+ { }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/TokenExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/TokenExtensions.cs
new file mode 100644
index 00000000..24f66d90
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/TokenExtensions.cs
@@ -0,0 +1,155 @@
+// 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.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Extension methods for storing authentication tokens in .
+ ///
+ public static class AuthenticationTokenExtensions
+ {
+ private static string TokenNamesKey = ".TokenNames";
+ private static string TokenKeyPrefix = ".Token.";
+
+ ///
+ /// Stores a set of authentication tokens, after removing any old tokens.
+ ///
+ /// The properties.
+ /// The tokens to store.
+ public static void StoreTokens(this AuthenticationProperties properties, IEnumerable tokens)
+ {
+ if (properties == null)
+ {
+ throw new ArgumentNullException(nameof(properties));
+ }
+ if (tokens == null)
+ {
+ throw new ArgumentNullException(nameof(tokens));
+ }
+
+ // Clear old tokens first
+ var oldTokens = properties.GetTokens();
+ foreach (var t in oldTokens)
+ {
+ properties.Items.Remove(TokenKeyPrefix + t.Name);
+ }
+ properties.Items.Remove(TokenNamesKey);
+
+ var tokenNames = new List();
+ foreach (var token in tokens)
+ {
+ // REVIEW: should probably check that there are no ; in the token name and throw or encode
+ tokenNames.Add(token.Name);
+ properties.Items[TokenKeyPrefix+token.Name] = token.Value;
+ }
+ if (tokenNames.Count > 0)
+ {
+ properties.Items[TokenNamesKey] = string.Join(";", tokenNames.ToArray());
+ }
+ }
+
+ ///
+ /// Returns the value of a token.
+ ///
+ /// The properties.
+ /// The token name.
+ /// The token value.
+ public static string GetTokenValue(this AuthenticationProperties properties, string tokenName)
+ {
+ if (properties == null)
+ {
+ throw new ArgumentNullException(nameof(properties));
+ }
+ if (tokenName == null)
+ {
+ throw new ArgumentNullException(nameof(tokenName));
+ }
+
+ var tokenKey = TokenKeyPrefix + tokenName;
+ return properties.Items.ContainsKey(tokenKey)
+ ? properties.Items[tokenKey]
+ : null;
+ }
+
+ public static bool UpdateTokenValue(this AuthenticationProperties properties, string tokenName, string tokenValue)
+ {
+ if (properties == null)
+ {
+ throw new ArgumentNullException(nameof(properties));
+ }
+ if (tokenName == null)
+ {
+ throw new ArgumentNullException(nameof(tokenName));
+ }
+
+ var tokenKey = TokenKeyPrefix + tokenName;
+ if (!properties.Items.ContainsKey(tokenKey))
+ {
+ return false;
+ }
+ properties.Items[tokenKey] = tokenValue;
+ return true;
+ }
+
+ ///
+ /// Returns all of the AuthenticationTokens contained in the properties.
+ ///
+ /// The properties.
+ /// The authentication toekns.
+ public static IEnumerable GetTokens(this AuthenticationProperties properties)
+ {
+ if (properties == null)
+ {
+ throw new ArgumentNullException(nameof(properties));
+ }
+
+ var tokens = new List();
+ if (properties.Items.ContainsKey(TokenNamesKey))
+ {
+ var tokenNames = properties.Items[TokenNamesKey].Split(';');
+ foreach (var name in tokenNames)
+ {
+ var token = properties.GetTokenValue(name);
+ if (token != null)
+ {
+ tokens.Add(new AuthenticationToken { Name = name, Value = token });
+ }
+ }
+ }
+
+ return tokens;
+ }
+
+ ///
+ /// Extension method for getting the value of an authentication token.
+ ///
+ /// The .
+ /// The context.
+ /// The name of the authentication scheme.
+ /// The name of the token.
+ /// The value of the token.
+ public static async Task GetTokenAsync(this IAuthenticationService auth, HttpContext context, string scheme, string tokenName)
+ {
+ if (auth == null)
+ {
+ throw new ArgumentNullException(nameof(auth));
+ }
+ if (scheme == null)
+ {
+ throw new ArgumentNullException(nameof(scheme));
+ }
+ if (tokenName == null)
+ {
+ throw new ArgumentNullException(nameof(tokenName));
+ }
+
+ var result = await auth.AuthenticateAsync(context, scheme);
+ return result?.Properties?.GetTokenValue(tokenName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationCoreServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationCoreServiceCollectionExtensions.cs
new file mode 100644
index 00000000..fdf85a9b
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationCoreServiceCollectionExtensions.cs
@@ -0,0 +1,56 @@
+// 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.Authentication;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ ///
+ /// Extension methods for setting up authentication services in an .
+ ///
+ public static class AuthenticationCoreServiceCollectionExtensions
+ {
+ ///
+ /// Add core authentication services needed for .
+ ///
+ /// The .
+ /// The service collection.
+ public static IServiceCollection AddAuthenticationCore(this IServiceCollection services)
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ services.TryAddScoped();
+ services.TryAddSingleton(); // Can be replaced with scoped ones that use DbContext
+ services.TryAddScoped();
+ services.TryAddSingleton();
+ return services;
+ }
+
+ ///
+ /// Add core authentication services needed for .
+ ///
+ /// The .
+ /// Used to configure the .
+ /// The service collection.
+ public static IServiceCollection AddAuthenticationCore(this IServiceCollection services, Action configureOptions) {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ if (configureOptions == null)
+ {
+ throw new ArgumentNullException(nameof(configureOptions));
+ }
+
+ services.AddAuthenticationCore();
+ services.Configure(configureOptions);
+ return services;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationFeature.cs b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationFeature.cs
new file mode 100644
index 00000000..3282cbf4
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationFeature.cs
@@ -0,0 +1,23 @@
+// 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
+{
+ ///
+ /// Used to capture path info so redirects can be computed properly within an app.Map().
+ ///
+ public class AuthenticationFeature : IAuthenticationFeature
+ {
+ ///
+ /// The original path base.
+ ///
+ public PathString OriginalPathBase { get; set; }
+
+ ///
+ /// The original path.
+ ///
+ public PathString OriginalPath { get; set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationHandlerProvider.cs b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationHandlerProvider.cs
new file mode 100644
index 00000000..c4921e53
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationHandlerProvider.cs
@@ -0,0 +1,63 @@
+// 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.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Implementation of .
+ ///
+ public class AuthenticationHandlerProvider : IAuthenticationHandlerProvider
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The .
+ public AuthenticationHandlerProvider(IAuthenticationSchemeProvider schemes)
+ {
+ Schemes = schemes;
+ }
+
+ ///
+ /// The .
+ ///
+ public IAuthenticationSchemeProvider Schemes { get; }
+
+ // handler instance cache, need to initialize once per request
+ private Dictionary _handlerMap = new Dictionary(StringComparer.Ordinal);
+
+ ///
+ /// Returns the handler instance that will be used.
+ ///
+ /// The context.
+ /// The name of the authentication scheme being handled.
+ /// The handler instance.
+ public async Task GetHandlerAsync(HttpContext context, string authenticationScheme)
+ {
+ if (_handlerMap.ContainsKey(authenticationScheme))
+ {
+ return _handlerMap[authenticationScheme];
+ }
+
+ var scheme = await Schemes.GetSchemeAsync(authenticationScheme);
+ if (scheme == null)
+ {
+ return null;
+ }
+ var handler = (context.RequestServices.GetService(scheme.HandlerType) ??
+ ActivatorUtilities.CreateInstance(context.RequestServices, scheme.HandlerType))
+ as IAuthenticationHandler;
+ if (handler != null)
+ {
+ await handler.InitializeAsync(scheme, context);
+ _handlerMap[authenticationScheme] = handler;
+ }
+ return handler;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs
new file mode 100644
index 00000000..fe347d6e
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs
@@ -0,0 +1,170 @@
+// 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.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Options;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Implements .
+ ///
+ public class AuthenticationSchemeProvider : IAuthenticationSchemeProvider
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The options.
+ public AuthenticationSchemeProvider(IOptions options)
+ {
+ _options = options.Value;
+
+ foreach (var builder in _options.Schemes)
+ {
+ var scheme = builder.Build();
+ AddScheme(scheme);
+ }
+ }
+
+ private readonly AuthenticationOptions _options;
+ private readonly object _lock = new object();
+
+ private IDictionary _map = new Dictionary(StringComparer.Ordinal);
+ private List _requestHandlers = new List();
+
+ ///
+ /// Returns the scheme that will be used by default for .
+ /// This is typically specified via .
+ /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ ///
+ /// The scheme that will be used by default for .
+ public Task GetDefaultAuthenticateSchemeAsync()
+ {
+ if (_options.DefaultAuthenticationScheme != null)
+ {
+ return GetSchemeAsync(_options.DefaultAuthenticationScheme);
+ }
+ if (_map.Count == 1)
+ {
+ return Task.FromResult(_map.Values.First());
+ }
+ return Task.FromResult(null);
+ }
+
+ ///
+ /// Returns the scheme that will be used by default for .
+ /// This is typically specified via .
+ /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ ///
+ /// The scheme that will be used by default for .
+ public Task GetDefaultChallengeSchemeAsync()
+ {
+ if (_options.DefaultChallengeScheme != null)
+ {
+ return GetSchemeAsync(_options.DefaultChallengeScheme);
+ }
+ if (_map.Count == 1)
+ {
+ return Task.FromResult(_map.Values.First());
+ }
+ return Task.FromResult(null);
+ }
+
+ ///
+ /// Returns the scheme that will be used by default for .
+ /// This is typically specified via .
+ /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ ///
+ /// The scheme that will be used by default for .
+ public Task GetDefaultSignInSchemeAsync()
+ {
+ if (_options.DefaultSignInScheme != null)
+ {
+ return GetSchemeAsync(_options.DefaultSignInScheme);
+ }
+ if (_map.Count == 1)
+ {
+ return Task.FromResult(_map.Values.First());
+ }
+ return Task.FromResult(null);
+ }
+
+ ///
+ /// Returns the matching the name, or null.
+ ///
+ /// The name of the authenticationScheme.
+ /// The scheme or null if not found.
+ public Task GetSchemeAsync(string name)
+ {
+ if (_map.ContainsKey(name))
+ {
+ return Task.FromResult(_map[name]);
+ }
+ return Task.FromResult(null);
+ }
+
+ ///
+ /// Returns the schemes in priority order for request handling.
+ ///
+ /// The schemes in priority order for request handling
+ public Task> GetRequestHandlerSchemesAsync()
+ {
+ return Task.FromResult>(_requestHandlers);
+ }
+
+ ///
+ /// Registers a scheme for use by .
+ ///
+ /// The scheme.
+ public void AddScheme(AuthenticationScheme scheme)
+ {
+ if (_map.ContainsKey(scheme.Name))
+ {
+ throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
+ }
+ lock (_lock)
+ {
+ if (_map.ContainsKey(scheme.Name))
+ {
+ throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
+ }
+ if (typeof(IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType))
+ {
+ _requestHandlers.Add(scheme);
+ }
+ _map[scheme.Name] = scheme;
+ }
+ }
+
+ ///
+ /// Removes a scheme, preventing it from being used by .
+ ///
+ /// The name of the authenticationScheme being removed.
+ public void RemoveScheme(string name)
+ {
+ if (!_map.ContainsKey(name))
+ {
+ return;
+ }
+ lock (_lock)
+ {
+ if (_map.ContainsKey(name))
+ {
+ var scheme = _map[name];
+ _requestHandlers.Remove(_requestHandlers.Where(s => s.Name == name).FirstOrDefault());
+ _map.Remove(name);
+ }
+ }
+ }
+
+ public Task> GetAllSchemesAsync()
+ {
+ return Task.FromResult>(_map.Values);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationService.cs b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationService.cs
new file mode 100644
index 00000000..9b8837f2
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationService.cs
@@ -0,0 +1,167 @@
+// 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 System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Implements .
+ ///
+ public class AuthenticationService : IAuthenticationService
+ {
+ ///
+ /// Constructor.
+ ///
+ /// The .
+ /// The .
+ /// The The .
+ public AuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform)
+ {
+ Schemes = schemes;
+ Handlers = handlers;
+ Transform = transform;
+ }
+
+ ///
+ /// Used to lookup AuthenticationSchemes.
+ ///
+ public IAuthenticationSchemeProvider Schemes { get; }
+
+ ///
+ /// Used to resolve IAuthenticationHandler instances.
+ ///
+ public IAuthenticationHandlerProvider Handlers { get; }
+
+ ///
+ /// Used for claims transformation.
+ ///
+ public IClaimsTransformation Transform { get; }
+
+ ///
+ /// Authenticate for the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The result.
+ public virtual async Task AuthenticateAsync(HttpContext context, string scheme)
+ {
+ if (scheme == null)
+ {
+ var defaultScheme = await Schemes.GetDefaultAuthenticateSchemeAsync();
+ scheme = defaultScheme?.Name;
+ if (scheme == null)
+ {
+ throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultAuthenticateScheme found.");
+ }
+ }
+
+ var handler = await Handlers.GetHandlerAsync(context, scheme);
+ if (handler == null)
+ {
+ throw new InvalidOperationException($"No authentication handler is configured to authenticate for the scheme: {scheme}");
+ }
+
+ var authContext = new AuthenticateContext(context, scheme);
+ var result = await handler.AuthenticateAsync(authContext);
+ if (result.Succeeded)
+ {
+ var transformed = await Transform.TransformAsync(result.Principal);
+ return AuthenticateResult.Success(new AuthenticationTicket(transformed, result.Properties, result.Ticket.AuthenticationScheme));
+ }
+ return result;
+ }
+
+ ///
+ /// Challenge the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The .
+ /// The .
+ /// A task.
+ public virtual async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties, ChallengeBehavior behavior)
+ {
+ if (scheme == null)
+ {
+ var defaultChallengeScheme = await Schemes.GetDefaultChallengeSchemeAsync();
+ scheme = defaultChallengeScheme?.Name;
+ if (scheme == null)
+ {
+ throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultChallengeScheme found.");
+ }
+ }
+
+ var handler = await Handlers.GetHandlerAsync(context, scheme);
+ if (handler == null)
+ {
+ throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {scheme}");
+ }
+
+ var challengeContext = new ChallengeContext(context, scheme, properties, behavior);
+ await handler.ChallengeAsync(challengeContext);
+ }
+
+ ///
+ /// Sign a principal in for the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The to sign in.
+ /// The .
+ /// A task.
+ public virtual async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
+ {
+ if (principal == null)
+ {
+ throw new ArgumentNullException(nameof(principal));
+ }
+
+ if (scheme == null)
+ {
+ var defaultScheme = await Schemes.GetDefaultSignInSchemeAsync();
+ scheme = defaultScheme?.Name;
+ if (scheme == null)
+ {
+ throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultSignInScheme found.");
+ }
+ }
+
+ var handler = await Handlers.GetHandlerAsync(context, scheme);
+ if (handler == null)
+ {
+ throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {scheme}");
+ }
+
+ var signInContext = new SignInContext(context, scheme, principal, properties);
+ await handler.SignInAsync(signInContext);
+ }
+
+ ///
+ /// Sign out the specified authentication scheme.
+ ///
+ /// The .
+ /// The name of the authentication scheme.
+ /// The .
+ /// A task.
+ public virtual async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)
+ {
+ if (string.IsNullOrEmpty(scheme))
+ {
+ throw new ArgumentException(nameof(scheme));
+ }
+
+ var handler = await Handlers.GetHandlerAsync(context, scheme);
+ if (handler == null)
+ {
+ throw new InvalidOperationException($"No authentication handler is configured to handle the scheme: {scheme}");
+ }
+
+ var signOutContext = new SignOutContext(context, scheme, properties);
+ await handler.SignOutAsync(signOutContext);
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/Microsoft.AspNetCore.Authentication.Core.csproj b/src/Microsoft.AspNetCore.Authentication.Core/Microsoft.AspNetCore.Authentication.Core.csproj
new file mode 100644
index 00000000..61628336
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/Microsoft.AspNetCore.Authentication.Core.csproj
@@ -0,0 +1,21 @@
+
+
+
+
+
+ ASP.NET Core common types used by the various authentication middleware components.
+ netstandard1.3;net46
+ $(NoWarn);CS1591
+ true
+ aspnetcore;authentication;security
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/NoopClaimsTransformation.cs b/src/Microsoft.AspNetCore.Authentication.Core/NoopClaimsTransformation.cs
new file mode 100644
index 00000000..83c488fe
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/NoopClaimsTransformation.cs
@@ -0,0 +1,24 @@
+// 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 System.Threading.Tasks;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ ///
+ /// Default claims transformation is a no-op.
+ ///
+ public class NoopClaimsTransformation : IClaimsTransformation
+ {
+ ///
+ /// Returns the principal unchanged.
+ ///
+ /// The user.
+ /// The principal unchanged.
+ public virtual Task TransformAsync(ClaimsPrincipal principal)
+ {
+ return Task.FromResult(principal);
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Authentication.Core/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..11e2e458
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/Properties/Resources.Designer.cs
@@ -0,0 +1,94 @@
+//
+namespace Microsoft.AspNetCore.Authentication
+{
+ using System.Globalization;
+ using System.Reflection;
+ using System.Resources;
+
+ internal static class Resources
+ {
+ private static readonly ResourceManager _resourceManager
+ = new ResourceManager("Microsoft.AspNetCore.Authentication.Resources", typeof(Resources).GetTypeInfo().Assembly);
+
+ ///
+ /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key.
+ ///
+ internal static string Exception_DefaultDpapiRequiresAppNameKey
+ {
+ get { return GetString("Exception_DefaultDpapiRequiresAppNameKey"); }
+ }
+
+ ///
+ /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key.
+ ///
+ internal static string FormatException_DefaultDpapiRequiresAppNameKey()
+ {
+ return GetString("Exception_DefaultDpapiRequiresAppNameKey");
+ }
+
+ ///
+ /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication.
+ ///
+ internal static string Exception_UnhookAuthenticationStateType
+ {
+ get { return GetString("Exception_UnhookAuthenticationStateType"); }
+ }
+
+ ///
+ /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication.
+ ///
+ internal static string FormatException_UnhookAuthenticationStateType()
+ {
+ return GetString("Exception_UnhookAuthenticationStateType");
+ }
+
+ ///
+ /// The AuthenticationTokenProvider's required synchronous events have not been registered.
+ ///
+ internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods
+ {
+ get { return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); }
+ }
+
+ ///
+ /// The AuthenticationTokenProvider's required synchronous events have not been registered.
+ ///
+ internal static string FormatException_AuthenticationTokenDoesNotProvideSyncMethods()
+ {
+ return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods");
+ }
+
+ ///
+ /// The '{0}' option must be provided.
+ ///
+ internal static string Exception_OptionMustBeProvided
+ {
+ get { return GetString("Exception_OptionMustBeProvided"); }
+ }
+
+ ///
+ /// The '{0}' option must be provided.
+ ///
+ internal static string FormatException_OptionMustBeProvided(object p0)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("Exception_OptionMustBeProvided"), p0);
+ }
+
+ private static string GetString(string name, params string[] formatterNames)
+ {
+ var value = _resourceManager.GetString(name);
+
+ System.Diagnostics.Debug.Assert(value != null);
+
+ if (formatterNames != null)
+ {
+ for (var i = 0; i < formatterNames.Length; i++)
+ {
+ value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
+ }
+ }
+
+ return value;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/Resources.resx b/src/Microsoft.AspNetCore.Authentication.Core/Resources.resx
new file mode 100644
index 00000000..54d22bcc
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Core/Resources.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key.
+
+
+ The state passed to UnhookAuthentication may only be the return value from HookAuthentication.
+
+
+ The AuthenticationTokenProvider's required synchronous events have not been registered.
+
+
+ The '{0}' option must be provided.
+
+
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticateInfo.cs b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticateInfo.cs
index 9e8e3fd5..3c893dbb 100644
--- a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticateInfo.cs
+++ b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticateInfo.cs
@@ -9,21 +9,25 @@ namespace Microsoft.AspNetCore.Http.Authentication
///
/// Used to store the results of an Authenticate call.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class AuthenticateInfo
{
///
/// The .
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public ClaimsPrincipal Principal { get; set; }
///
/// The .
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public AuthenticationProperties Properties { get; set; }
///
/// The .
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public AuthenticationDescription Description { get; set; }
}
}
diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationDescription.cs b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationDescription.cs
index fb0a073f..fb2d00c8 100644
--- a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationDescription.cs
+++ b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationDescription.cs
@@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.Http.Authentication
///
/// Contains information describing an authentication provider.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class AuthenticationDescription
{
private const string DisplayNamePropertyKey = "DisplayName";
diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationManager.cs b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationManager.cs
index 56d9dbad..164618dc 100644
--- a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationManager.cs
+++ b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationManager.cs
@@ -9,37 +9,47 @@
namespace Microsoft.AspNetCore.Http.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract class AuthenticationManager
{
///
/// Constant used to represent the automatic scheme
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public const string AutomaticScheme = "Automatic";
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract HttpContext HttpContext { get; }
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract IEnumerable GetAuthenticationSchemes();
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract Task GetAuthenticateInfoAsync(string authenticationScheme);
// Will remove once callees have been updated
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract Task AuthenticateAsync(AuthenticateContext context);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual async Task AuthenticateAsync(string authenticationScheme)
{
return (await GetAuthenticateInfoAsync(authenticationScheme))?.Principal;
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ChallengeAsync()
{
return ChallengeAsync(properties: null);
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ChallengeAsync(AuthenticationProperties properties)
{
return ChallengeAsync(authenticationScheme: AutomaticScheme, properties: properties);
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ChallengeAsync(string authenticationScheme)
{
if (string.IsNullOrEmpty(authenticationScheme))
@@ -51,6 +61,7 @@ public virtual Task ChallengeAsync(string authenticationScheme)
}
// Leave it up to authentication handler to do the right thing for the challenge
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties)
{
if (string.IsNullOrEmpty(authenticationScheme))
@@ -61,6 +72,7 @@ public virtual Task ChallengeAsync(string authenticationScheme, AuthenticationPr
return ChallengeAsync(authenticationScheme, properties, ChallengeBehavior.Automatic);
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task SignInAsync(string authenticationScheme, ClaimsPrincipal principal)
{
if (string.IsNullOrEmpty(authenticationScheme))
@@ -80,9 +92,11 @@ public virtual Task SignInAsync(string authenticationScheme, ClaimsPrincipal pri
/// Creates a challenge for the authentication manager with .
///
/// A that represents the asynchronous challenge operation.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ForbidAsync()
=> ForbidAsync(AutomaticScheme, properties: null);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ForbidAsync(string authenticationScheme)
{
if (authenticationScheme == null)
@@ -94,6 +108,7 @@ public virtual Task ForbidAsync(string authenticationScheme)
}
// Deny access (typically a 403)
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ForbidAsync(string authenticationScheme, AuthenticationProperties properties)
{
if (authenticationScheme == null)
@@ -109,13 +124,17 @@ public virtual Task ForbidAsync(string authenticationScheme, AuthenticationPrope
///
/// Additional arbitrary values which may be used by particular authentication types.
/// A that represents the asynchronous challenge operation.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task ForbidAsync(AuthenticationProperties properties)
=> ForbidAsync(AutomaticScheme, properties);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract Task SignInAsync(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public virtual Task SignOutAsync(string authenticationScheme)
{
if (authenticationScheme == null)
@@ -126,6 +145,7 @@ public virtual Task SignOutAsync(string authenticationScheme)
return SignOutAsync(authenticationScheme, properties: null);
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract Task SignOutAsync(string authenticationScheme, AuthenticationProperties properties);
}
}
diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationProperties.cs b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationProperties.cs
index 6e883efb..a01c5d4c 100644
--- a/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationProperties.cs
+++ b/src/Microsoft.AspNetCore.Http.Abstractions/Authentication/AuthenticationProperties.cs
@@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.Http.Authentication
///
/// Dictionary used to store state values about the authentication session.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class AuthenticationProperties
{
internal const string IssuedUtcKey = ".issued";
@@ -39,11 +40,13 @@ public AuthenticationProperties(IDictionary items)
///
/// State values about the authentication session.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public IDictionary Items { get; }
///
/// Gets or sets whether the authentication session is persisted across multiple requests.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public bool IsPersistent
{
get { return Items.ContainsKey(IsPersistentKey); }
@@ -69,6 +72,7 @@ public bool IsPersistent
///
/// Gets or sets the full path or absolute URI to be used as an http redirect response value.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public string RedirectUri
{
get
@@ -95,6 +99,7 @@ public string RedirectUri
///
/// Gets or sets the time at which the authentication ticket was issued.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public DateTimeOffset? IssuedUtc
{
get
@@ -129,6 +134,7 @@ public DateTimeOffset? IssuedUtc
///
/// Gets or sets the time at which the authentication ticket expires.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public DateTimeOffset? ExpiresUtc
{
get
@@ -163,6 +169,7 @@ public DateTimeOffset? ExpiresUtc
///
/// Gets or sets if refreshing the authentication session should be allowed.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public bool? AllowRefresh
{
get
diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/HttpContext.cs b/src/Microsoft.AspNetCore.Http.Abstractions/HttpContext.cs
index 7f72dcd8..6b38ae43 100644
--- a/src/Microsoft.AspNetCore.Http.Abstractions/HttpContext.cs
+++ b/src/Microsoft.AspNetCore.Http.Abstractions/HttpContext.cs
@@ -43,6 +43,7 @@ public abstract class HttpContext
///
/// Gets an object that facilitates authentication for this request.
///
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public abstract AuthenticationManager Authentication { get; }
///
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/AuthenticateContext.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/AuthenticateContext.cs
index e7306166..67e89f18 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/AuthenticateContext.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/AuthenticateContext.cs
@@ -7,6 +7,7 @@
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class AuthenticateContext
{
public AuthenticateContext(string authenticationScheme)
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeBehavior.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeBehavior.cs
index 549d5113..9fdceb0a 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeBehavior.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeBehavior.cs
@@ -1,8 +1,11 @@
// 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.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public enum ChallengeBehavior
{
Automatic,
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeContext.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeContext.cs
index c0fe4708..d8e04c14 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeContext.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/ChallengeContext.cs
@@ -6,6 +6,7 @@
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class ChallengeContext
{
public ChallengeContext(string authenticationScheme)
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/DescribeSchemesContext.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/DescribeSchemesContext.cs
index b25c2c97..e86f8475 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/DescribeSchemesContext.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/DescribeSchemesContext.cs
@@ -1,10 +1,12 @@
// 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.Collections.Generic;
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class DescribeSchemesContext
{
private List> _results;
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/IAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/IAuthenticationHandler.cs
index 3b723641..7d5b9c01 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/IAuthenticationHandler.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/IAuthenticationHandler.cs
@@ -1,20 +1,27 @@
// 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.Threading.Tasks;
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public interface IAuthenticationHandler
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
void GetDescriptions(DescribeSchemesContext context);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
Task AuthenticateAsync(AuthenticateContext context);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
Task ChallengeAsync(ChallengeContext context);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
Task SignInAsync(SignInContext context);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
Task SignOutAsync(SignOutContext context);
}
}
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/IHttpAuthenticationFeature.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/IHttpAuthenticationFeature.cs
index 080ce405..b018e51a 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/IHttpAuthenticationFeature.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/IHttpAuthenticationFeature.cs
@@ -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;
using System.Security.Claims;
namespace Microsoft.AspNetCore.Http.Features.Authentication
@@ -9,6 +10,7 @@ public interface IHttpAuthenticationFeature
{
ClaimsPrincipal User { get; set; }
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
IAuthenticationHandler Handler { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/SignInContext.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/SignInContext.cs
index f04dade5..982f4400 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/SignInContext.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/SignInContext.cs
@@ -7,6 +7,7 @@
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class SignInContext
{
public SignInContext(string authenticationScheme, ClaimsPrincipal principal, IDictionary properties)
diff --git a/src/Microsoft.AspNetCore.Http.Features/Authentication/SignOutContext.cs b/src/Microsoft.AspNetCore.Http.Features/Authentication/SignOutContext.cs
index c752f057..e99773e9 100644
--- a/src/Microsoft.AspNetCore.Http.Features/Authentication/SignOutContext.cs
+++ b/src/Microsoft.AspNetCore.Http.Features/Authentication/SignOutContext.cs
@@ -6,6 +6,7 @@
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class SignOutContext
{
public SignOutContext(string authenticationScheme, IDictionary properties)
diff --git a/src/Microsoft.AspNetCore.Http/Authentication/DefaultAuthenticationManager.cs b/src/Microsoft.AspNetCore.Http/Authentication/DefaultAuthenticationManager.cs
index 666e2179..028555f4 100644
--- a/src/Microsoft.AspNetCore.Http/Authentication/DefaultAuthenticationManager.cs
+++ b/src/Microsoft.AspNetCore.Http/Authentication/DefaultAuthenticationManager.cs
@@ -11,6 +11,7 @@
namespace Microsoft.AspNetCore.Http.Authentication.Internal
{
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public class DefaultAuthenticationManager : AuthenticationManager
{
// Lambda hoisted to static readonly field to improve inlining https://github.com/dotnet/roslyn/issues/13624
@@ -35,11 +36,13 @@ public virtual void Uninitialize()
_features = default(FeatureReferences);
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override HttpContext HttpContext => _context;
private IHttpAuthenticationFeature HttpAuthenticationFeature =>
_features.Fetch(ref _features.Cache, _newAuthenticationFeature);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override IEnumerable GetAuthenticationSchemes()
{
var handler = HttpAuthenticationFeature.Handler;
@@ -54,6 +57,7 @@ public override IEnumerable GetAuthenticationSchemes(
}
// Remove once callers have been switched to GetAuthenticateInfoAsync
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override async Task AuthenticateAsync(AuthenticateContext context)
{
if (context == null)
@@ -73,6 +77,7 @@ public override async Task AuthenticateAsync(AuthenticateContext context)
}
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override async Task GetAuthenticateInfoAsync(string authenticationScheme)
{
if (authenticationScheme == null)
@@ -100,6 +105,7 @@ public override async Task GetAuthenticateInfoAsync(string aut
};
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override async Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior)
{
if (string.IsNullOrEmpty(authenticationScheme))
@@ -121,6 +127,7 @@ public override async Task ChallengeAsync(string authenticationScheme, Authentic
}
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override async Task SignInAsync(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties)
{
if (string.IsNullOrEmpty(authenticationScheme))
@@ -147,6 +154,7 @@ public override async Task SignInAsync(string authenticationScheme, ClaimsPrinci
}
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override async Task SignOutAsync(string authenticationScheme, AuthenticationProperties properties)
{
if (string.IsNullOrEmpty(authenticationScheme))
diff --git a/src/Microsoft.AspNetCore.Http/DefaultHttpContext.cs b/src/Microsoft.AspNetCore.Http/DefaultHttpContext.cs
index d1e431c7..883cc33e 100644
--- a/src/Microsoft.AspNetCore.Http/DefaultHttpContext.cs
+++ b/src/Microsoft.AspNetCore.Http/DefaultHttpContext.cs
@@ -28,7 +28,9 @@ public class DefaultHttpContext : HttpContext
private HttpRequest _request;
private HttpResponse _response;
+#pragma warning disable 618
private AuthenticationManager _authenticationManager;
+#pragma warning restore 618
private ConnectionInfo _connection;
private WebSocketManager _websockets;
@@ -66,7 +68,9 @@ public virtual void Uninitialize()
}
if (_authenticationManager != null)
{
+#pragma warning disable 618
UninitializeAuthenticationManager(_authenticationManager);
+#pragma warning restore 618
_authenticationManager = null;
}
if (_connection != null)
@@ -111,6 +115,7 @@ public virtual void Uninitialize()
public override ConnectionInfo Connection => _connection ?? (_connection = InitializeConnectionInfo());
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public override AuthenticationManager Authentication => _authenticationManager ?? (_authenticationManager = InitializeAuthenticationManager());
public override WebSocketManager WebSockets => _websockets ?? (_websockets = InitializeWebSocketManager());
@@ -190,7 +195,9 @@ protected virtual void UninitializeHttpResponse(HttpResponse instance) { }
protected virtual ConnectionInfo InitializeConnectionInfo() => new DefaultConnectionInfo(Features);
protected virtual void UninitializeConnectionInfo(ConnectionInfo instance) { }
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
protected virtual AuthenticationManager InitializeAuthenticationManager() => new DefaultAuthenticationManager(this);
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
protected virtual void UninitializeAuthenticationManager(AuthenticationManager instance) { }
protected virtual WebSocketManager InitializeWebSocketManager() => new DefaultWebSocketManager(Features);
diff --git a/src/Microsoft.AspNetCore.Http/Features/Authentication/HttpAuthenticationFeature.cs b/src/Microsoft.AspNetCore.Http/Features/Authentication/HttpAuthenticationFeature.cs
index 9a14b657..89f06e3b 100644
--- a/src/Microsoft.AspNetCore.Http/Features/Authentication/HttpAuthenticationFeature.cs
+++ b/src/Microsoft.AspNetCore.Http/Features/Authentication/HttpAuthenticationFeature.cs
@@ -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;
using System.Security.Claims;
namespace Microsoft.AspNetCore.Http.Features.Authentication
@@ -13,6 +14,7 @@ public ClaimsPrincipal User
set;
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
public IAuthenticationHandler Handler
{
get;
diff --git a/src/Microsoft.AspNetCore.Owin/OwinFeatureCollection.cs b/src/Microsoft.AspNetCore.Owin/OwinFeatureCollection.cs
index 4838b99f..4a71310c 100644
--- a/src/Microsoft.AspNetCore.Owin/OwinFeatureCollection.cs
+++ b/src/Microsoft.AspNetCore.Owin/OwinFeatureCollection.cs
@@ -279,6 +279,7 @@ ClaimsPrincipal IHttpAuthenticationFeature.User
}
}
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470")]
IAuthenticationHandler IHttpAuthenticationFeature.Handler { get; set; }
///
diff --git a/test/Microsoft.AspNetCore.Authentication.Core.Test/Microsoft.AspNetCore.Authentication.Core.Test.csproj b/test/Microsoft.AspNetCore.Authentication.Core.Test/Microsoft.AspNetCore.Authentication.Core.Test.csproj
new file mode 100644
index 00000000..925f5aa0
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Authentication.Core.Test/Microsoft.AspNetCore.Authentication.Core.Test.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+ netcoreapp2.0;net46
+ netcoreapp2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs b/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs
new file mode 100644
index 00000000..3e3eb9c5
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs
@@ -0,0 +1,123 @@
+// 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.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Authentication
+{
+ public class TokenExtensionTests
+ {
+ [Fact]
+ public void CanStoreMultipleTokens()
+ {
+ var props = new AuthenticationProperties();
+ var tokens = new List();
+ var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
+ var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
+ var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
+ tokens.Add(tok1);
+ tokens.Add(tok2);
+ tokens.Add(tok3);
+ props.StoreTokens(tokens);
+
+ Assert.Equal("1", props.GetTokenValue("One"));
+ Assert.Equal("2", props.GetTokenValue("Two"));
+ Assert.Equal("3", props.GetTokenValue("Three"));
+ Assert.Equal(3, props.GetTokens().Count());
+ }
+
+ [Fact]
+ public void SubsequentStoreTokenDeletesPreviousTokens()
+ {
+ var props = new AuthenticationProperties();
+ var tokens = new List();
+ var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
+ var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
+ var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
+ tokens.Add(tok1);
+ tokens.Add(tok2);
+ tokens.Add(tok3);
+
+ props.StoreTokens(tokens);
+
+ props.StoreTokens(new[] { new AuthenticationToken { Name = "Zero", Value = "0" } });
+
+ Assert.Equal("0", props.GetTokenValue("Zero"));
+ Assert.Equal(null, props.GetTokenValue("One"));
+ Assert.Equal(null, props.GetTokenValue("Two"));
+ Assert.Equal(null, props.GetTokenValue("Three"));
+ Assert.Equal(1, props.GetTokens().Count());
+ }
+
+ [Fact]
+ public void CanUpdateTokens()
+ {
+ var props = new AuthenticationProperties();
+ var tokens = new List();
+ var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
+ var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
+ var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
+ tokens.Add(tok1);
+ tokens.Add(tok2);
+ tokens.Add(tok3);
+ props.StoreTokens(tokens);
+
+ tok1.Value = ".1";
+ tok2.Value = ".2";
+ tok3.Value = ".3";
+ props.StoreTokens(tokens);
+
+ Assert.Equal(".1", props.GetTokenValue("One"));
+ Assert.Equal(".2", props.GetTokenValue("Two"));
+ Assert.Equal(".3", props.GetTokenValue("Three"));
+ Assert.Equal(3, props.GetTokens().Count());
+ }
+
+ [Fact]
+ public void CanUpdateTokenValues()
+ {
+ var props = new AuthenticationProperties();
+ var tokens = new List();
+ var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
+ var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
+ var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
+ tokens.Add(tok1);
+ tokens.Add(tok2);
+ tokens.Add(tok3);
+ props.StoreTokens(tokens);
+
+ Assert.True(props.UpdateTokenValue("One", ".11"));
+ Assert.True(props.UpdateTokenValue("Two", ".22"));
+ Assert.True(props.UpdateTokenValue("Three", ".33"));
+
+ Assert.Equal(".11", props.GetTokenValue("One"));
+ Assert.Equal(".22", props.GetTokenValue("Two"));
+ Assert.Equal(".33", props.GetTokenValue("Three"));
+ Assert.Equal(3, props.GetTokens().Count());
+ }
+
+ [Fact]
+ public void UpdateTokenValueReturnsFalseForUnknownToken()
+ {
+ var props = new AuthenticationProperties();
+ var tokens = new List();
+ var tok1 = new AuthenticationToken { Name = "One", Value = "1" };
+ var tok2 = new AuthenticationToken { Name = "Two", Value = "2" };
+ var tok3 = new AuthenticationToken { Name = "Three", Value = "3" };
+ tokens.Add(tok1);
+ tokens.Add(tok2);
+ tokens.Add(tok3);
+ props.StoreTokens(tokens);
+
+ Assert.False(props.UpdateTokenValue("ONE", ".11"));
+ Assert.False(props.UpdateTokenValue("Jigglypuff", ".11"));
+
+ Assert.Null(props.GetTokenValue("ONE"));
+ Assert.Null(props.GetTokenValue("Jigglypuff"));
+ Assert.Equal(3, props.GetTokens().Count());
+
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Http.Features.Tests/Authentication/AuthenticateContextTest.cs b/test/Microsoft.AspNetCore.Http.Features.Tests/Authentication/AuthenticateContextTest.cs
index c4d90132..1fae5b0a 100644
--- a/test/Microsoft.AspNetCore.Http.Features.Tests/Authentication/AuthenticateContextTest.cs
+++ b/test/Microsoft.AspNetCore.Http.Features.Tests/Authentication/AuthenticateContextTest.cs
@@ -8,6 +8,7 @@
using System.Threading.Tasks;
using Xunit;
+#pragma warning disable 618
namespace Microsoft.AspNetCore.Http.Features.Authentication
{
public class AuthenticateContextTest
@@ -160,3 +161,4 @@ public void AuthenticateContext_NotAuthenticated_SetsUnusedPropertiesToDefault_F
}
}
}
+#pragma warning restore 618
diff --git a/test/Microsoft.AspNetCore.Http.Tests/Authentication/DefaultAuthenticationManagerTests.cs b/test/Microsoft.AspNetCore.Http.Tests/Authentication/DefaultAuthenticationManagerTests.cs
index 85968a94..73c0c931 100644
--- a/test/Microsoft.AspNetCore.Http.Tests/Authentication/DefaultAuthenticationManagerTests.cs
+++ b/test/Microsoft.AspNetCore.Http.Tests/Authentication/DefaultAuthenticationManagerTests.cs
@@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Http.Features.Authentication;
using Xunit;
+#pragma warning disable 618
namespace Microsoft.AspNetCore.Http.Authentication.Internal
{
public class DefaultAuthenticationManagerTests
@@ -100,3 +101,4 @@ private HttpContext CreateContext()
}
}
}
+#pragma warning restore 618
diff --git a/test/Microsoft.AspNetCore.Http.Tests/DefaultHttpContextTests.cs b/test/Microsoft.AspNetCore.Http.Tests/DefaultHttpContextTests.cs
index 13b9ee65..7766210e 100644
--- a/test/Microsoft.AspNetCore.Http.Tests/DefaultHttpContextTests.cs
+++ b/test/Microsoft.AspNetCore.Http.Tests/DefaultHttpContextTests.cs
@@ -191,7 +191,9 @@ void TestAllCachedFeaturesAreNull(HttpContext context, IFeatureCollection featur
TestCachedFeaturesAreNull(context, features);
TestCachedFeaturesAreNull(context.Request, features);
TestCachedFeaturesAreNull(context.Response, features);
+#pragma warning disable 618
TestCachedFeaturesAreNull(context.Authentication, features);
+#pragma warning restore 618
TestCachedFeaturesAreNull(context.Connection, features);
TestCachedFeaturesAreNull(context.WebSockets, features);
}
@@ -220,7 +222,9 @@ void TestAllCachedFeaturesAreSet(HttpContext context, IFeatureCollection feature
TestCachedFeaturesAreSet(context, features);
TestCachedFeaturesAreSet(context.Request, features);
TestCachedFeaturesAreSet(context.Response, features);
+#pragma warning disable 618
TestCachedFeaturesAreSet(context.Authentication, features);
+#pragma warning restore 618
TestCachedFeaturesAreSet(context.Connection, features);
TestCachedFeaturesAreSet(context.WebSockets, features);
}