Move AuthManager methods to Context and Response.
This commit is contained in:
parent
63dc9ad719
commit
c638c74bc9
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Abstractions.Security;
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Abstractions
|
namespace Microsoft.AspNet.Abstractions
|
||||||
|
|
@ -11,8 +13,6 @@ namespace Microsoft.AspNet.Abstractions
|
||||||
|
|
||||||
public abstract HttpResponse Response { get; }
|
public abstract HttpResponse Response { get; }
|
||||||
|
|
||||||
public abstract AuthenticationManager Authentication { get; }
|
|
||||||
|
|
||||||
public abstract ClaimsPrincipal User { get; set; }
|
public abstract ClaimsPrincipal User { get; set; }
|
||||||
|
|
||||||
public abstract IDictionary<object, object> Items { get; }
|
public abstract IDictionary<object, object> Items { get; }
|
||||||
|
|
@ -36,5 +36,21 @@ namespace Microsoft.AspNet.Abstractions
|
||||||
{
|
{
|
||||||
SetFeature(typeof(T), instance);
|
SetFeature(typeof(T), instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract IEnumerable<AuthenticationDescription> GetAuthenticationTypes();
|
||||||
|
|
||||||
|
public virtual AuthenticationResult Authenticate(string authenticationType)
|
||||||
|
{
|
||||||
|
return Authenticate(new[] { authenticationType }).SingleOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract IEnumerable<AuthenticationResult> Authenticate(IList<string> authenticationTypes);
|
||||||
|
|
||||||
|
public virtual async Task<AuthenticationResult> AuthenticateAsync(string authenticationType)
|
||||||
|
{
|
||||||
|
return (await AuthenticateAsync(new[] { authenticationType })).SingleOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Abstractions
|
namespace Microsoft.AspNet.Abstractions
|
||||||
{
|
{
|
||||||
|
|
@ -23,5 +26,61 @@ namespace Microsoft.AspNet.Abstractions
|
||||||
public abstract void Redirect(string location);
|
public abstract void Redirect(string location);
|
||||||
|
|
||||||
public abstract Task WriteAsync(string data);
|
public abstract Task WriteAsync(string data);
|
||||||
|
|
||||||
|
public virtual void Challenge()
|
||||||
|
{
|
||||||
|
Challenge(new string[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Challenge(AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
Challenge(new string[0], properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Challenge(string authenticationType)
|
||||||
|
{
|
||||||
|
Challenge(new[] { authenticationType });
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Challenge(string authenticationType, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
Challenge(new[] { authenticationType }, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Challenge(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
Challenge(authenticationTypes, properties: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Challenge(IList<string> authenticationTypes, AuthenticationProperties properties);
|
||||||
|
|
||||||
|
public virtual void SignIn(ClaimsIdentity identity)
|
||||||
|
{
|
||||||
|
SignIn(identity, properties: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SignIn(ClaimsIdentity identity, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
SignIn(new[] { identity }, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SignIn(IList<ClaimsIdentity> identities)
|
||||||
|
{
|
||||||
|
SignIn(identities, properties: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void SignIn(IList<ClaimsIdentity> identities, AuthenticationProperties properties);
|
||||||
|
|
||||||
|
public virtual void SignOut()
|
||||||
|
{
|
||||||
|
SignOut(new string[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SignOut(string authenticationType)
|
||||||
|
{
|
||||||
|
SignOut(new[] { authenticationType });
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void SignOut(IList<string> authenticationTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
// 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 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Abstractions.Security
|
||||||
/// Initializes a new instance of the <see cref="AuthenticationProperties"/> class
|
/// Initializes a new instance of the <see cref="AuthenticationProperties"/> class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public AuthenticationProperties()
|
public AuthenticationProperties()
|
||||||
: this(null)
|
: this(dictionary: null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Microsoft.AspNet.HttpFeature.Security
|
||||||
{
|
{
|
||||||
public interface ISignInContext
|
public interface ISignInContext
|
||||||
{
|
{
|
||||||
ClaimsPrincipal User { get; }
|
IList<ClaimsIdentity> Identities { get; }
|
||||||
IDictionary<string, string> Properties { get; }
|
IDictionary<string, string> Properties { get; }
|
||||||
|
|
||||||
void Ack(string authenticationType, IDictionary<string, object> description);
|
void Ack(string authenticationType, IDictionary<string, object> description);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.Abstractions.Security;
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
using Microsoft.AspNet.FeatureModel;
|
using Microsoft.AspNet.FeatureModel;
|
||||||
|
|
@ -14,11 +16,10 @@ 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 FeatureReference<IHttpAuthentication> _authentication;
|
||||||
private IFeatureCollection _features;
|
private IFeatureCollection _features;
|
||||||
|
|
||||||
public DefaultHttpContext(IFeatureCollection features)
|
public DefaultHttpContext(IFeatureCollection features)
|
||||||
|
|
@ -26,11 +27,10 @@ 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;
|
_authentication = FeatureReference<IHttpAuthentication>.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
ICanHasItems CanHasItems
|
ICanHasItems CanHasItems
|
||||||
|
|
@ -45,15 +45,13 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
|
|
||||||
private IHttpAuthentication HttpAuthentication
|
private IHttpAuthentication HttpAuthentication
|
||||||
{
|
{
|
||||||
get { return _auth.Fetch(_features) ?? _auth.Update(_features, new DefaultHttpAuthentication()); }
|
get { return _authentication.Fetch(_features) ?? _authentication.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
|
public override ClaimsPrincipal User
|
||||||
{
|
{
|
||||||
get { return HttpAuthentication.User; }
|
get { return HttpAuthentication.User; }
|
||||||
|
|
@ -95,5 +93,76 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
{
|
{
|
||||||
_features[type] = instance;
|
_features[type] = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Use context, not a delegate, like all the other APIs
|
||||||
|
private static DescriptionDelegate GetAuthenticationTypesDelegate = GetAuthenticationTypesCallback;
|
||||||
|
|
||||||
|
public override IEnumerable<AuthenticationDescription> GetAuthenticationTypes()
|
||||||
|
{
|
||||||
|
// TODO: Use context, not a delegate, like all the other APIs
|
||||||
|
var descriptions = new List<AuthenticationDescription>();
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler.GetDescriptions(GetAuthenticationTypesDelegate, 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 IEnumerable<AuthenticationResult> Authenticate(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No authentication handlers present.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticateContext = new AuthenticateContext(authenticationTypes);
|
||||||
|
handler.Authenticate(authenticateContext);
|
||||||
|
|
||||||
|
// Verify all types ack'd
|
||||||
|
IEnumerable<string> leftovers = authenticationTypes.Except(authenticateContext.Acked);
|
||||||
|
if (leftovers.Any())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticateContext.Results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No authentication handlers present.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticateContext = new AuthenticateContext(authenticationTypes);
|
||||||
|
await handler.AuthenticateAsync(authenticateContext);
|
||||||
|
|
||||||
|
// Verify all types ack'd
|
||||||
|
IEnumerable<string> leftovers = authenticationTypes.Except(authenticateContext.Acked);
|
||||||
|
if (leftovers.Any())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticateContext.Results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.Abstractions.Infrastructure;
|
using Microsoft.AspNet.Abstractions.Infrastructure;
|
||||||
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
using Microsoft.AspNet.FeatureModel;
|
using Microsoft.AspNet.FeatureModel;
|
||||||
using Microsoft.AspNet.HttpFeature;
|
using Microsoft.AspNet.HttpFeature;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
using Microsoft.AspNet.PipelineCore.Collections;
|
using Microsoft.AspNet.PipelineCore.Collections;
|
||||||
using Microsoft.AspNet.PipelineCore.Infrastructure;
|
using Microsoft.AspNet.PipelineCore.Infrastructure;
|
||||||
|
using Microsoft.AspNet.PipelineCore.Security;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.PipelineCore
|
namespace Microsoft.AspNet.PipelineCore
|
||||||
{
|
{
|
||||||
|
|
@ -18,6 +23,7 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
private FeatureReference<IHttpResponseInformation> _response = FeatureReference<IHttpResponseInformation>.Default;
|
private FeatureReference<IHttpResponseInformation> _response = FeatureReference<IHttpResponseInformation>.Default;
|
||||||
private FeatureReference<ICanHasResponseCookies> _canHasCookies = FeatureReference<ICanHasResponseCookies>.Default;
|
private FeatureReference<ICanHasResponseCookies> _canHasCookies = FeatureReference<ICanHasResponseCookies>.Default;
|
||||||
|
private FeatureReference<IHttpAuthentication> _authentication = FeatureReference<IHttpAuthentication>.Default;
|
||||||
|
|
||||||
public DefaultHttpResponse(DefaultHttpContext context, IFeatureCollection features)
|
public DefaultHttpResponse(DefaultHttpContext context, IFeatureCollection features)
|
||||||
{
|
{
|
||||||
|
|
@ -35,6 +41,11 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
get { return _canHasCookies.Fetch(_features) ?? _canHasCookies.Update(_features, new DefaultCanHasResponseCookies(_features)); }
|
get { return _canHasCookies.Fetch(_features) ?? _canHasCookies.Update(_features, new DefaultCanHasResponseCookies(_features)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IHttpAuthentication HttpAuthentication
|
||||||
|
{
|
||||||
|
get { return _authentication.Fetch(_features) ?? _authentication.Update(_features, new DefaultHttpAuthentication()); }
|
||||||
|
}
|
||||||
|
|
||||||
public override HttpContext HttpContext { get { return _context; } }
|
public override HttpContext HttpContext { get { return _context; } }
|
||||||
|
|
||||||
public override int StatusCode
|
public override int StatusCode
|
||||||
|
|
@ -107,5 +118,75 @@ namespace Microsoft.AspNet.PipelineCore
|
||||||
var bytes = Encoding.UTF8.GetBytes(data);
|
var bytes = Encoding.UTF8.GetBytes(data);
|
||||||
return Body.WriteAsync(bytes, 0, bytes.Length);
|
return Body.WriteAsync(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Challenge(IList<string> authenticationTypes, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
HttpResponseInformation.StatusCode = 401;
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No authentication handlers present.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var challengeContext = new ChallengeContext(authenticationTypes, properties == null ? null : properties.Dictionary);
|
||||||
|
handler.Challenge(challengeContext);
|
||||||
|
|
||||||
|
// Verify all types ack'd
|
||||||
|
IEnumerable<string> leftovers = authenticationTypes.Except(challengeContext.Acked);
|
||||||
|
if (leftovers.Any())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignIn(IList<ClaimsIdentity> identities, AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
if (identities == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No authentication handlers present.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var signInContext = new SignInContext(identities, properties == null ? null : properties.Dictionary);
|
||||||
|
handler.SignIn(signInContext);
|
||||||
|
|
||||||
|
// Verify all types ack'd
|
||||||
|
IEnumerable<string> leftovers = identities.Select(identity => identity.AuthenticationType).Except(signInContext.Acked);
|
||||||
|
if (leftovers.Any())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SignOut(IList<string> authenticationTypes)
|
||||||
|
{
|
||||||
|
if (authenticationTypes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
|
var handler = HttpAuthentication.Handler;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No authentication handlers present.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var signOutContext = new SignOutContext(authenticationTypes);
|
||||||
|
handler.SignOut(signOutContext);
|
||||||
|
|
||||||
|
// Verify all types ack'd
|
||||||
|
IEnumerable<string> leftovers = authenticationTypes.Except(signOutContext.Acked);
|
||||||
|
if (leftovers.Any())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,233 +0,0 @@
|
||||||
// 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 static DescriptionDelegate GetAuthenticationTypesDelegate = GetAuthenticationTypesCallback;
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
var descriptions = new List<AuthenticationDescription>();
|
|
||||||
var handler = HttpAuthentication.Handler;
|
|
||||||
if (handler != null)
|
|
||||||
{
|
|
||||||
handler.GetDescriptions(GetAuthenticationTypesDelegate, 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)
|
|
||||||
{
|
|
||||||
if (authenticationTypes == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
var handler = HttpAuthentication.Handler;
|
|
||||||
if (handler == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("No authentication handlers present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var authenticateContext = new AuthenticateContext(authenticationTypes);
|
|
||||||
handler.Authenticate(authenticateContext);
|
|
||||||
|
|
||||||
// Verify all types ack'd
|
|
||||||
IEnumerable<string> leftovers = authenticationTypes.Except(authenticateContext.Acked);
|
|
||||||
if (leftovers.Any())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (authenticationTypes == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
var handler = HttpAuthentication.Handler;
|
|
||||||
if (handler == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("No authentication handlers present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var authenticateContext = new AuthenticateContext(authenticationTypes);
|
|
||||||
await handler.AuthenticateAsync(authenticateContext);
|
|
||||||
|
|
||||||
// Verify all types ack'd
|
|
||||||
IEnumerable<string> leftovers = authenticationTypes.Except(authenticateContext.Acked);
|
|
||||||
if (leftovers.Any())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (authenticationTypes == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
HttpResponseInformation.StatusCode = 401;
|
|
||||||
var handler = HttpAuthentication.Handler;
|
|
||||||
if (handler == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("No authentication handlers present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var challengeContext = new ChallengeContext(authenticationTypes, properties == null ? null : properties.Dictionary);
|
|
||||||
handler.Challenge(challengeContext);
|
|
||||||
|
|
||||||
// Verify all types ack'd
|
|
||||||
IEnumerable<string> leftovers = authenticationTypes.Except(challengeContext.Acked);
|
|
||||||
if (leftovers.Any())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SignIn(ClaimsPrincipal user)
|
|
||||||
{
|
|
||||||
SignIn(user, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SignIn(ClaimsPrincipal user, AuthenticationProperties properties)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
var handler = HttpAuthentication.Handler;
|
|
||||||
if (handler == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("No authentication handlers present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var signInContext = new SignInContext(user, properties == null ? null : properties.Dictionary);
|
|
||||||
handler.SignIn(signInContext);
|
|
||||||
|
|
||||||
// Verify all types ack'd
|
|
||||||
IEnumerable<string> leftovers = user.Identities.Select(identity => identity.AuthenticationType).Except(signInContext.Acked);
|
|
||||||
if (leftovers.Any())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SignOut()
|
|
||||||
{
|
|
||||||
SignOut(new string[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SignOut(string authenticationType)
|
|
||||||
{
|
|
||||||
SignOut(new[] { authenticationType });
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SignOut(IList<string> authenticationTypes)
|
|
||||||
{
|
|
||||||
if (authenticationTypes == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
var handler = HttpAuthentication.Handler;
|
|
||||||
if (handler == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("No authentication handlers present.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var signOutContext = new SignOutContext(authenticationTypes);
|
|
||||||
handler.SignOut(signOutContext);
|
|
||||||
|
|
||||||
// Verify all types ack'd
|
|
||||||
IEnumerable<string> leftovers = authenticationTypes.Except(signOutContext.Acked);
|
|
||||||
if (leftovers.Any())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("The following authentication types did not ack: " + string.Join(", ", leftovers));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,18 +7,18 @@ namespace Microsoft.AspNet.PipelineCore.Security
|
||||||
{
|
{
|
||||||
public class SignInContext : ISignInContext
|
public class SignInContext : ISignInContext
|
||||||
{
|
{
|
||||||
public SignInContext(ClaimsPrincipal user, IDictionary<string, string> dictionary)
|
public SignInContext(IList<ClaimsIdentity> identities, IDictionary<string, string> dictionary)
|
||||||
{
|
{
|
||||||
if (user == null)
|
if (identities == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("user");
|
throw new ArgumentNullException("identities");
|
||||||
}
|
}
|
||||||
User = user;
|
Identities = identities;
|
||||||
Properties = dictionary ?? new Dictionary<string, string>(StringComparer.Ordinal);
|
Properties = dictionary ?? new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
Acked = new List<string>();
|
Acked = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClaimsPrincipal User { get; private set; }
|
public IList<ClaimsIdentity> Identities { get; private set; }
|
||||||
|
|
||||||
public IDictionary<string, string> Properties { get; private set; }
|
public IDictionary<string, string> Properties { get; private set; }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue