Security contracts.
This commit is contained in:
parent
eaddb29577
commit
4347ddfd0f
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Abstractions
|
namespace Microsoft.AspNet.Abstractions
|
||||||
{
|
{
|
||||||
|
|
@ -8,6 +10,10 @@ namespace Microsoft.AspNet.Abstractions
|
||||||
public abstract HttpRequest Request { get; }
|
public abstract HttpRequest Request { get; }
|
||||||
|
|
||||||
public abstract HttpResponse Response { get; }
|
public abstract HttpResponse Response { get; }
|
||||||
|
|
||||||
|
public abstract AuthenticationManager Authentication { get; }
|
||||||
|
|
||||||
|
public abstract ClaimsPrincipal User { get; set; }
|
||||||
|
|
||||||
public abstract IDictionary<object, object> Items { get; }
|
public abstract IDictionary<object, object> Items { get; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Abstractions.Security
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Acts as the return value from calls to the IAuthenticationManager's AuthenticeAsync methods.
|
||||||
|
/// </summary>
|
||||||
|
public class AuthenticationResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Create an instance of the result object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="identity">Assigned to Identity. May be null.</param>
|
||||||
|
/// <param name="properties">Assigned to Properties. Contains extra information carried along with the identity.</param>
|
||||||
|
/// <param name="description">Assigned to Description. Contains information describing the authentication provider.</param>
|
||||||
|
public AuthenticationResult(IIdentity identity, AuthenticationProperties properties, AuthenticationDescription description)
|
||||||
|
{
|
||||||
|
if (properties == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("properties");
|
||||||
|
}
|
||||||
|
if (description == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("description");
|
||||||
|
}
|
||||||
|
if (identity != null)
|
||||||
|
{
|
||||||
|
Identity = identity as ClaimsIdentity ?? new ClaimsIdentity(identity);
|
||||||
|
}
|
||||||
|
Properties = properties;
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the claims that were authenticated by the given AuthenticationType. If the authentication
|
||||||
|
/// type was not successful the Identity property will be null.
|
||||||
|
/// </summary>
|
||||||
|
public ClaimsIdentity Identity { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains extra values that were provided with the original SignIn call.
|
||||||
|
/// </summary>
|
||||||
|
public AuthenticationProperties Properties { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains description properties for the middleware authentication type in general. Does not
|
||||||
|
/// vary per request.
|
||||||
|
/// </summary>
|
||||||
|
public AuthenticationDescription Description { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Abstractions.Security
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains information describing an authentication provider.
|
||||||
|
/// </summary>
|
||||||
|
public class AuthenticationDescription
|
||||||
|
{
|
||||||
|
private const string CaptionPropertyKey = "Caption";
|
||||||
|
private const string AuthenticationTypePropertyKey = "AuthenticationType";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AuthenticationDescription"/> class
|
||||||
|
/// </summary>
|
||||||
|
public AuthenticationDescription()
|
||||||
|
{
|
||||||
|
Dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AuthenticationDescription"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="properties"></param>
|
||||||
|
public AuthenticationDescription(IDictionary<string, object> properties)
|
||||||
|
{
|
||||||
|
if (properties == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("properties");
|
||||||
|
}
|
||||||
|
Dictionary = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains metadata about the authentication provider.
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<string, object> Dictionary { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the name used to reference the authentication middleware instance.
|
||||||
|
/// </summary>
|
||||||
|
public string AuthenticationType
|
||||||
|
{
|
||||||
|
get { return GetString(AuthenticationTypePropertyKey); }
|
||||||
|
set { Dictionary[AuthenticationTypePropertyKey] = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the display name for the authentication provider.
|
||||||
|
/// </summary>
|
||||||
|
public string Caption
|
||||||
|
{
|
||||||
|
get { return GetString(CaptionPropertyKey); }
|
||||||
|
set { Dictionary[CaptionPropertyKey] = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetString(string name)
|
||||||
|
{
|
||||||
|
object value;
|
||||||
|
if (Dictionary.TryGetValue(name, out value))
|
||||||
|
{
|
||||||
|
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Abstractions.Security
|
||||||
|
{
|
||||||
|
public abstract class AuthenticationManager
|
||||||
|
{
|
||||||
|
public abstract HttpContext HttpContext { get; }
|
||||||
|
|
||||||
|
public abstract IEnumerable<AuthenticationDescription> GetAuthenticationTypes();
|
||||||
|
public abstract IEnumerable<AuthenticationDescription> GetAuthenticationTypes(Func<AuthenticationDescription, bool> predicate);
|
||||||
|
|
||||||
|
public abstract AuthenticationResult Authenticate(string authenticationType); // TODO: Is sync a good idea?
|
||||||
|
public abstract IEnumerable<AuthenticationResult> Authenticate(IList<string> authenticationTypes);
|
||||||
|
|
||||||
|
public abstract Task<AuthenticationResult> AuthenticateAsync(string authenticationType);
|
||||||
|
public abstract Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes);
|
||||||
|
|
||||||
|
public abstract void Challenge();
|
||||||
|
public abstract void Challenge(AuthenticationProperties properties);
|
||||||
|
public abstract void Challenge(string authenticationType);
|
||||||
|
public abstract void Challenge(string authenticationType, AuthenticationProperties properties);
|
||||||
|
public abstract void Challenge(IList<string> authenticationTypes);
|
||||||
|
public abstract void Challenge(IList<string> authenticationTypes, AuthenticationProperties properties);
|
||||||
|
|
||||||
|
public abstract void SignIn(ClaimsPrincipal user); // TODO: This took multiple identities in Katana. Is that needed?
|
||||||
|
public abstract void SignIn(ClaimsPrincipal user, AuthenticationProperties properties); // TODO: ClaimsIdentity vs ClaimsPrincipal?
|
||||||
|
|
||||||
|
public abstract void SignOut();
|
||||||
|
public abstract void SignOut(string authenticationType);
|
||||||
|
public abstract void SignOut(IList<string> authenticationTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Abstractions.Security
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary used to store state values about the authentication session.
|
||||||
|
/// </summary>
|
||||||
|
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 UtcDateTimeFormat = "r";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AuthenticationProperties"/> class
|
||||||
|
/// </summary>
|
||||||
|
public AuthenticationProperties()
|
||||||
|
: this(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AuthenticationProperties"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dictionary"></param>
|
||||||
|
public AuthenticationProperties(IDictionary<string, string> dictionary)
|
||||||
|
{
|
||||||
|
Dictionary = dictionary ?? new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State values about the authentication session.
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<string, string> Dictionary { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether the authentication session is persisted across multiple requests.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPersistent
|
||||||
|
{
|
||||||
|
get { return Dictionary.ContainsKey(IsPersistentKey); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Dictionary.ContainsKey(IsPersistentKey))
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
Dictionary.Remove(IsPersistentKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
Dictionary.Add(IsPersistentKey, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the full path or absolute URI to be used as an http redirect response value.
|
||||||
|
/// </summary>
|
||||||
|
[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By design")]
|
||||||
|
public string RedirectUri
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string value;
|
||||||
|
return Dictionary.TryGetValue(RedirectUriKey, out value) ? value : null;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
Dictionary[RedirectUriKey] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Dictionary.ContainsKey(RedirectUriKey))
|
||||||
|
{
|
||||||
|
Dictionary.Remove(RedirectUriKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the time at which the authentication ticket was issued.
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset? IssuedUtc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string value;
|
||||||
|
if (Dictionary.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)
|
||||||
|
{
|
||||||
|
Dictionary[IssuedUtcKey] = value.Value.ToString(UtcDateTimeFormat, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Dictionary.ContainsKey(IssuedUtcKey))
|
||||||
|
{
|
||||||
|
Dictionary.Remove(IssuedUtcKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the time at which the authentication ticket expires.
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset? ExpiresUtc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string value;
|
||||||
|
if (Dictionary.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)
|
||||||
|
{
|
||||||
|
Dictionary[ExpiresUtcKey] = value.Value.ToString(UtcDateTimeFormat, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Dictionary.ContainsKey(ExpiresUtcKey))
|
||||||
|
{
|
||||||
|
Dictionary.Remove(ExpiresUtcKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": "0.1-alpha-*",
|
"version": "0.1-alpha-*",
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.HttpFeature": ""
|
||||||
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": {},
|
"net45": {},
|
||||||
"k10": {
|
"k10": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"System.Collections": "4.0.0.0",
|
||||||
"System.ComponentModel": "4.0.0.0",
|
"System.ComponentModel": "4.0.0.0",
|
||||||
"System.Diagnostics.Tools": "4.0.0.0",
|
"System.Diagnostics.Tools": "4.0.0.0",
|
||||||
|
"System.Globalization": "4.0.10.0",
|
||||||
"System.IO": "4.0.0.0",
|
"System.IO": "4.0.0.0",
|
||||||
"System.Linq": "4.0.0.0",
|
"System.Linq": "4.0.0.0",
|
||||||
"System.Runtime": "4.0.20.0",
|
"System.Runtime": "4.0.20.0",
|
||||||
"System.Runtime.Extensions": "4.0.10.0",
|
"System.Runtime.Extensions": "4.0.10.0",
|
||||||
"System.Runtime.InteropServices": "4.0.20.0",
|
"System.Runtime.InteropServices": "4.0.20.0",
|
||||||
|
"System.Security.Claims": "0.1-alpha-*",
|
||||||
|
"System.Security.Principal" : "4.0.0.0",
|
||||||
"System.Threading.Tasks": "4.0.10.0"
|
"System.Threading.Tasks": "4.0.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
|
{
|
||||||
|
public interface IAuthenticateContext
|
||||||
|
{
|
||||||
|
IList<string> AuthenticationTypes { get; }
|
||||||
|
|
||||||
|
void Authenticated(ClaimsIdentity identity, IDictionary<string, string> properties, IDictionary<string, object> description);
|
||||||
|
|
||||||
|
void NotAuthenticated(string authenticationType, IDictionary<string, string> properties, IDictionary<string, object> description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.HttpFeature.Security
|
|
||||||
{
|
|
||||||
public interface IAuthenticationChallenge
|
|
||||||
{
|
|
||||||
IEnumerable<string> AuthenticationTypes { get; }
|
|
||||||
IDictionary<string, string> Properties { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.HttpFeature.Security
|
|
||||||
{
|
|
||||||
public interface IAuthenticationDescription
|
|
||||||
{
|
|
||||||
IDictionary<string, object> Properties { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
|
{
|
||||||
|
public delegate void DescriptionDelegate(IDictionary<string, object> description, object state);
|
||||||
|
|
||||||
|
public interface IAuthenticationHandler
|
||||||
|
{
|
||||||
|
void GetDescriptions(DescriptionDelegate callback, object state);
|
||||||
|
|
||||||
|
void Authenticate(IAuthenticateContext context); // TODO: (maybe?)
|
||||||
|
Task AuthenticateAsync(IAuthenticateContext context);
|
||||||
|
|
||||||
|
void Challenge(IChallengeContext context);
|
||||||
|
void SignIn(ISignInContext context);
|
||||||
|
void SignOut(ISignOutContext context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNet.HttpFeature.Security;
|
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
|
||||||
namespace Microsoft.AspNet.Interfaces.Security
|
|
||||||
{
|
|
||||||
public interface IAuthenticationResult
|
|
||||||
{
|
|
||||||
ClaimsIdentity Identity { get; }
|
|
||||||
IDictionary<string, object> Properties { get; }
|
|
||||||
IAuthenticationDescription Description { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.HttpFeature.Security
|
|
||||||
{
|
|
||||||
public interface IAuthenticationSignOut
|
|
||||||
{
|
|
||||||
IEnumerable<string> AuthenticationTypes { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
|
{
|
||||||
|
public interface IChallengeContext
|
||||||
|
{
|
||||||
|
IList<string> AuthenticationTypes {get;}
|
||||||
|
IDictionary<string,string> Properties {get;}
|
||||||
|
|
||||||
|
void Ack(string authenticationType, IDictionary<string,object> description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Security.Claims;
|
||||||
using System.Security.Principal;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.Interfaces.Security;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.HttpFeature.Security
|
namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
{
|
{
|
||||||
public interface IHttpAuthentication
|
public interface IHttpAuthentication
|
||||||
{
|
{
|
||||||
IPrincipal User { get; set; }
|
ClaimsPrincipal User { get; set; }
|
||||||
|
IAuthenticationHandler Handler { get; set; }
|
||||||
IEnumerable<IAuthenticationResult> Authenticate(string[] authenticationTypes);
|
|
||||||
Task<IEnumerable<IAuthenticationResult>> AuthenticateAsync(string[] authenticationTypes);
|
|
||||||
|
|
||||||
IAuthenticationChallenge ChallengeDetails { get; set; }
|
|
||||||
IAuthenticationSignIn SignInDetails { get; set; }
|
|
||||||
IAuthenticationSignOut SignOutDetails { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,9 +3,11 @@ using System.Security.Claims;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.HttpFeature.Security
|
namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
{
|
{
|
||||||
public interface IAuthenticationSignIn
|
public interface ISignInContext
|
||||||
{
|
{
|
||||||
ClaimsPrincipal User { get; }
|
ClaimsPrincipal User { get; }
|
||||||
IDictionary<string, string> Properties { get; }
|
IDictionary<string, string> Properties { get; }
|
||||||
|
|
||||||
|
void Ack(string authenticationType, IDictionary<string, object> description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
|
{
|
||||||
|
public interface ISignOutContext
|
||||||
|
{
|
||||||
|
IList<string> AuthenticationTypes { get; }
|
||||||
|
|
||||||
|
void Ack(string authenticationType, IDictionary<string, object> description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
using Microsoft.AspNet.FeatureModel;
|
using Microsoft.AspNet.FeatureModel;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
using Microsoft.AspNet.PipelineCore.Infrastructure;
|
using Microsoft.AspNet.PipelineCore.Infrastructure;
|
||||||
|
using Microsoft.AspNet.PipelineCore.Security;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.PipelineCore
|
namespace Microsoft.AspNet.PipelineCore
|
||||||
{
|
{
|
||||||
|
|
@ -10,9 +14,11 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
{
|
{
|
||||||
private readonly HttpRequest _request;
|
private readonly HttpRequest _request;
|
||||||
private readonly HttpResponse _response;
|
private readonly HttpResponse _response;
|
||||||
|
private readonly AuthenticationManager _authentication;
|
||||||
|
|
||||||
private FeatureReference<ICanHasItems> _canHasItems;
|
private FeatureReference<ICanHasItems> _canHasItems;
|
||||||
private FeatureReference<ICanHasServiceProviders> _canHasServiceProviders;
|
private FeatureReference<ICanHasServiceProviders> _canHasServiceProviders;
|
||||||
|
private FeatureReference<IHttpAuthentication> _auth;
|
||||||
private IFeatureCollection _features;
|
private IFeatureCollection _features;
|
||||||
|
|
||||||
public DefaultHttpContext(IFeatureCollection features)
|
public DefaultHttpContext(IFeatureCollection features)
|
||||||
|
|
@ -20,9 +26,11 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
_features = features;
|
_features = features;
|
||||||
_request = new DefaultHttpRequest(this, features);
|
_request = new DefaultHttpRequest(this, features);
|
||||||
_response = new DefaultHttpResponse(this, features);
|
_response = new DefaultHttpResponse(this, features);
|
||||||
|
_authentication = new DefaultAuthenticationManager(this, features);
|
||||||
|
|
||||||
_canHasItems = FeatureReference<ICanHasItems>.Default;
|
_canHasItems = FeatureReference<ICanHasItems>.Default;
|
||||||
_canHasServiceProviders = FeatureReference<ICanHasServiceProviders>.Default;
|
_canHasServiceProviders = FeatureReference<ICanHasServiceProviders>.Default;
|
||||||
|
_auth = FeatureReference<IHttpAuthentication>.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
ICanHasItems CanHasItems
|
ICanHasItems CanHasItems
|
||||||
|
|
@ -35,10 +43,23 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
get { return _canHasServiceProviders.Fetch(_features) ?? _canHasServiceProviders.Update(_features, new DefaultCanHasServiceProviders()); }
|
get { return _canHasServiceProviders.Fetch(_features) ?? _canHasServiceProviders.Update(_features, new DefaultCanHasServiceProviders()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IHttpAuthentication HttpAuthentication
|
||||||
|
{
|
||||||
|
get { return _auth.Fetch(_features) ?? _auth.Update(_features, new DefaultHttpAuthentication()); }
|
||||||
|
}
|
||||||
|
|
||||||
public override HttpRequest Request { get { return _request; } }
|
public override HttpRequest Request { get { return _request; } }
|
||||||
|
|
||||||
public override HttpResponse Response { get { return _response; } }
|
public override HttpResponse Response { get { return _response; } }
|
||||||
|
|
||||||
|
public override AuthenticationManager Authentication { get { return _authentication; } }
|
||||||
|
|
||||||
|
public override ClaimsPrincipal User
|
||||||
|
{
|
||||||
|
get { return HttpAuthentication.User; }
|
||||||
|
set { HttpAuthentication.User = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public override IDictionary<object, object> Items
|
public override IDictionary<object, object> Items
|
||||||
{
|
{
|
||||||
get { return CanHasItems.Items; }
|
get { return CanHasItems.Items; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
|
{
|
||||||
|
public class AuthenticateContext : IAuthenticateContext
|
||||||
|
{
|
||||||
|
public AuthenticateContext(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("authenticationType");
|
||||||
|
}
|
||||||
|
AuthenticationTypes = authenticationTypes;
|
||||||
|
Results = new List<AuthenticationResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<string> AuthenticationTypes { get; private set; }
|
||||||
|
|
||||||
|
public IList<AuthenticationResult> Results { get; private set; }
|
||||||
|
|
||||||
|
public void Authenticated(ClaimsIdentity identity, IDictionary<string, string> properties, IDictionary<string, object> description)
|
||||||
|
{
|
||||||
|
Results.Add(new AuthenticationResult(identity, new AuthenticationProperties(properties), new AuthenticationDescription(description)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NotAuthenticated(string authenticationType, IDictionary<string, string> properties, IDictionary<string, object> description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
|
{
|
||||||
|
public class ChallengeContext : IChallengeContext
|
||||||
|
{
|
||||||
|
public ChallengeContext(IList<string> authenticationTypes, IDictionary<string, string> properties)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
AuthenticationTypes = authenticationTypes;
|
||||||
|
Properties = properties ?? new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<string> AuthenticationTypes { get; private set; }
|
||||||
|
|
||||||
|
public IDictionary<string, string> Properties { get; private set; }
|
||||||
|
|
||||||
|
public void Ack(string authenticationType, IDictionary<string, object> description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Abstractions;
|
||||||
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
using Microsoft.AspNet.FeatureModel;
|
||||||
|
using Microsoft.AspNet.HttpFeature;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
using Microsoft.AspNet.PipelineCore.Infrastructure;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
|
{
|
||||||
|
public class DefaultAuthenticationManager : AuthenticationManager
|
||||||
|
{
|
||||||
|
private readonly DefaultHttpContext _context;
|
||||||
|
private readonly IFeatureCollection _features;
|
||||||
|
|
||||||
|
private readonly FeatureReference<IHttpAuthentication> _authentication = FeatureReference<IHttpAuthentication>.Default;
|
||||||
|
private readonly FeatureReference<IHttpResponseInformation> _response = FeatureReference<IHttpResponseInformation>.Default;
|
||||||
|
|
||||||
|
public DefaultAuthenticationManager(DefaultHttpContext context, IFeatureCollection features)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_features = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IHttpAuthentication HttpAuthentication
|
||||||
|
{
|
||||||
|
get { return _authentication.Fetch(_features) ?? _authentication.Update(_features, new DefaultHttpAuthentication()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override HttpContext HttpContext { get { return _context; } }
|
||||||
|
|
||||||
|
private IHttpResponseInformation HttpResponseInformation
|
||||||
|
{
|
||||||
|
get { return _response.Fetch(_features); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<AuthenticationDescription> GetAuthenticationTypes()
|
||||||
|
{
|
||||||
|
return GetAuthenticationTypes(_ => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<AuthenticationDescription> GetAuthenticationTypes(Func<AuthenticationDescription, bool> predicate)
|
||||||
|
{
|
||||||
|
var descriptions = new List<AuthenticationDescription>();
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
// TODO: static delegate field
|
||||||
|
handler.GetDescriptions(GetAuthenticationTypesCallback, descriptions);
|
||||||
|
}
|
||||||
|
return descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GetAuthenticationTypesCallback(IDictionary<string, object> description, object state)
|
||||||
|
{
|
||||||
|
var localDescriptions = (List<AuthenticationDescription>)state;
|
||||||
|
localDescriptions.Add(new AuthenticationDescription(description));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override AuthenticationResult Authenticate(string authenticationType)
|
||||||
|
{
|
||||||
|
return Authenticate(new[] { authenticationType }).SingleOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<AuthenticationResult> Authenticate(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
HttpResponseInformation.StatusCode = 401;
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
// TODO: InvalidOperationException? No auth types supported?
|
||||||
|
return new AuthenticationResult[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticateContext = new AuthenticateContext(authenticationTypes);
|
||||||
|
handler.Authenticate(authenticateContext);
|
||||||
|
// TODO: Verify all types ack'd
|
||||||
|
|
||||||
|
return authenticateContext.Results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<AuthenticationResult> AuthenticateAsync(string authenticationType)
|
||||||
|
{
|
||||||
|
return (await AuthenticateAsync(new[] { authenticationType })).SingleOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
HttpResponseInformation.StatusCode = 401;
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
// TODO: InvalidOperationException? No auth types supported?
|
||||||
|
return new AuthenticationResult[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticateContext = new AuthenticateContext(authenticationTypes);
|
||||||
|
await handler.AuthenticateAsync(authenticateContext);
|
||||||
|
// TODO: Verify all types ack'd
|
||||||
|
|
||||||
|
return authenticateContext.Results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Challenge()
|
||||||
|
{
|
||||||
|
Challenge(new string[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Challenge(AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
Challenge(new string[0], properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Challenge(string authenticationType)
|
||||||
|
{
|
||||||
|
Challenge(new[] { authenticationType });
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Challenge(string authenticationType, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
Challenge(new[] { authenticationType }, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Challenge(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
Challenge(authenticationTypes, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Challenge(IList<string> authenticationTypes, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
HttpResponseInformation.StatusCode = 401;
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
// TODO: InvalidOperationException? No auth types supported? If authTypes.Length > 1?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var challengeContext = new ChallengeContext(authenticationTypes, properties == null ? null : properties.Dictionary);
|
||||||
|
handler.Challenge(challengeContext);
|
||||||
|
// TODO: Verify all types ack'd
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignIn(ClaimsPrincipal user)
|
||||||
|
{
|
||||||
|
SignIn(user, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignIn(ClaimsPrincipal user, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
HttpResponseInformation.StatusCode = 401;
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
// TODO: InvalidOperationException? No auth types supported?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var signInContext = new SignInContext(user, properties == null ? null : properties.Dictionary);
|
||||||
|
handler.SignIn(signInContext);
|
||||||
|
// TODO: Verify all types ack'd
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignOut()
|
||||||
|
{
|
||||||
|
SignOut(new string[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignOut(string authenticationType)
|
||||||
|
{
|
||||||
|
SignOut(new[] { authenticationType });
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignOut(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
HttpResponseInformation.StatusCode = 401;
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
// TODO: InvalidOperationException? No auth types supported?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var signOutContext = new SignOutContext(authenticationTypes);
|
||||||
|
handler.SignOut(signOutContext);
|
||||||
|
// TODO: Verify all types ack'd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
|
{
|
||||||
|
public class DefaultHttpAuthentication : IHttpAuthentication
|
||||||
|
{
|
||||||
|
public DefaultHttpAuthentication()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClaimsPrincipal User
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAuthenticationHandler Handler
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
|
{
|
||||||
|
public class SignInContext : ISignInContext
|
||||||
|
{
|
||||||
|
public SignInContext(ClaimsPrincipal user, IDictionary<string, string> dictionary)
|
||||||
|
{
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("user");
|
||||||
|
}
|
||||||
|
User = user;
|
||||||
|
Properties = dictionary ?? new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClaimsPrincipal User { get; private set; }
|
||||||
|
|
||||||
|
public IDictionary<string, string> Properties { get; private set; }
|
||||||
|
|
||||||
|
public void Ack(string authenticationType, IDictionary<string, object> description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
|
{
|
||||||
|
public class SignOutContext : ISignOutContext
|
||||||
|
{
|
||||||
|
public SignOutContext(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("authenticationTypes");
|
||||||
|
}
|
||||||
|
AuthenticationTypes = authenticationTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<string> AuthenticationTypes { get; private set; }
|
||||||
|
|
||||||
|
public void Ack(string authenticationType, IDictionary<string, object> description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
"System.Runtime": "4.0.20.0",
|
"System.Runtime": "4.0.20.0",
|
||||||
"System.Runtime.Extensions": "4.0.10.0",
|
"System.Runtime.Extensions": "4.0.10.0",
|
||||||
"System.Runtime.InteropServices": "4.0.20.0",
|
"System.Runtime.InteropServices": "4.0.20.0",
|
||||||
|
"System.Security.Claims": "0.1-alpha-*",
|
||||||
|
"System.Security.Principal" : "4.0.0.0",
|
||||||
"System.Text.Encoding": "4.0.20.0",
|
"System.Text.Encoding": "4.0.20.0",
|
||||||
"System.Threading.Tasks": "4.0.10.0"
|
"System.Threading.Tasks": "4.0.10.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue