Auth API changes (Async, ChallengeBehavior)
This commit is contained in:
parent
641a7fb82b
commit
5fe8037281
|
|
@ -1,44 +0,0 @@
|
|||
// 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 Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Http.Authentication
|
||||
{
|
||||
/// <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(ClaimsPrincipal principal, [NotNull] AuthenticationProperties properties, [NotNull] AuthenticationDescription description)
|
||||
{
|
||||
Principal = principal;
|
||||
Properties = properties;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the claims that were authenticated by the given AuthenticationScheme. If the authentication
|
||||
/// scheme was not successful the Identity property will be null.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { 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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http.Features.Authentication;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Http.Authentication
|
||||
{
|
||||
|
|
@ -11,41 +13,61 @@ namespace Microsoft.AspNet.Http.Authentication
|
|||
{
|
||||
public abstract IEnumerable<AuthenticationDescription> GetAuthenticationSchemes();
|
||||
|
||||
public abstract AuthenticationResult Authenticate(string authenticationScheme);
|
||||
public abstract Task AuthenticateAsync([NotNull] AuthenticateContext context);
|
||||
|
||||
public abstract Task<AuthenticationResult> AuthenticateAsync(string authenticationScheme);
|
||||
|
||||
public virtual void Challenge()
|
||||
public virtual async Task<ClaimsPrincipal> AuthenticateAsync([NotNull] string authenticationScheme)
|
||||
{
|
||||
Challenge(authenticationScheme: null, properties: null);
|
||||
var context = new AuthenticateContext(authenticationScheme);
|
||||
await AuthenticateAsync(context);
|
||||
return context.Principal;
|
||||
}
|
||||
|
||||
public virtual void Challenge(AuthenticationProperties properties)
|
||||
public virtual Task ChallengeAsync()
|
||||
{
|
||||
Challenge(authenticationScheme: null, properties: properties);
|
||||
return ChallengeAsync(properties: null);
|
||||
}
|
||||
|
||||
public virtual void Challenge(string authenticationScheme)
|
||||
public virtual Task ChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
Challenge(authenticationScheme: authenticationScheme, properties: null);
|
||||
return ChallengeAsync(authenticationScheme: string.Empty, properties: properties);
|
||||
}
|
||||
|
||||
public abstract void Challenge(string authenticationScheme, AuthenticationProperties properties);
|
||||
|
||||
public void SignIn(string authenticationScheme, ClaimsPrincipal principal)
|
||||
public virtual Task ChallengeAsync([NotNull] string authenticationScheme)
|
||||
{
|
||||
SignIn(authenticationScheme, principal, properties: null);
|
||||
return ChallengeAsync(authenticationScheme: authenticationScheme, properties: null);
|
||||
}
|
||||
|
||||
public abstract void SignIn(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties);
|
||||
|
||||
public virtual void SignOut()
|
||||
// Leave it up to authentication handler to do the right thing for the challenge
|
||||
public virtual Task ChallengeAsync([NotNull] string authenticationScheme, AuthenticationProperties properties)
|
||||
{
|
||||
SignOut(authenticationScheme: null, properties: null);
|
||||
return ChallengeAsync(authenticationScheme, properties, ChallengeBehavior.Automatic);
|
||||
}
|
||||
|
||||
public abstract void SignOut(string authenticationScheme);
|
||||
public virtual Task SignInAsync([NotNull] string authenticationScheme, [NotNull] ClaimsPrincipal principal)
|
||||
{
|
||||
return SignInAsync(authenticationScheme, principal, properties: null);
|
||||
}
|
||||
|
||||
public abstract void SignOut(string authenticationScheme, AuthenticationProperties properties);
|
||||
public virtual Task ForbidAsync([NotNull] string authenticationScheme)
|
||||
{
|
||||
return ForbidAsync(authenticationScheme, properties: null);
|
||||
}
|
||||
|
||||
// Deny access (typically a 403)
|
||||
public virtual Task ForbidAsync([NotNull] string authenticationScheme, AuthenticationProperties properties)
|
||||
{
|
||||
return ChallengeAsync(authenticationScheme, properties, ChallengeBehavior.Forbidden);
|
||||
}
|
||||
|
||||
public abstract Task ChallengeAsync([NotNull] string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior);
|
||||
|
||||
public abstract Task SignInAsync([NotNull] string authenticationScheme, [NotNull] ClaimsPrincipal principal, AuthenticationProperties properties);
|
||||
|
||||
public virtual Task SignOutAsync([NotNull] string authenticationScheme)
|
||||
{
|
||||
return SignOutAsync(authenticationScheme, properties: null);
|
||||
}
|
||||
|
||||
public abstract Task SignOutAsync([NotNull] string authenticationScheme, AuthenticationProperties properties);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,20 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Http
|
||||
{
|
||||
public abstract class HttpResponse
|
||||
{
|
||||
private static readonly Func<object, Task> _callbackDelegate = callback => ((Func<Task>)callback)();
|
||||
private static readonly Func<object, Task> _disposeDelegate = disposable =>
|
||||
{
|
||||
((IDisposable)disposable).Dispose();
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
public abstract HttpContext HttpContext { get; }
|
||||
|
||||
public abstract int StatusCode { get; set; }
|
||||
|
|
@ -24,14 +33,17 @@ namespace Microsoft.AspNet.Http
|
|||
|
||||
public abstract bool HasStarted { get; }
|
||||
|
||||
public abstract void OnResponseStarting(Action<object> callback, object state);
|
||||
public abstract void OnStarting([NotNull] Func<object, Task> callback, object state);
|
||||
|
||||
public abstract void OnResponseCompleted(Action<object> callback, object state);
|
||||
public virtual void OnStarting([NotNull] Func<Task> callback) => OnStarting(_callbackDelegate, callback);
|
||||
|
||||
public virtual void Redirect(string location)
|
||||
{
|
||||
Redirect(location, permanent: false);
|
||||
}
|
||||
public abstract void OnCompleted([NotNull] Func<object, Task> callback, object state);
|
||||
|
||||
public virtual void OnCompletedDispose([NotNull] IDisposable disposable) => OnCompleted(_disposeDelegate, disposable);
|
||||
|
||||
public virtual void OnCompleted([NotNull] Func<Task> callback) => OnCompleted(_callbackDelegate, callback);
|
||||
|
||||
public virtual void Redirect(string location) => Redirect(location, permanent: false);
|
||||
|
||||
public abstract void Redirect(string location, bool permanent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +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.
|
||||
|
||||
namespace Microsoft.AspNet.Http.Features.Authentication
|
||||
{
|
||||
public enum ChallengeBehavior
|
||||
{
|
||||
Automatic,
|
||||
Unauthorized,
|
||||
Forbidden
|
||||
}
|
||||
}
|
||||
|
|
@ -3,19 +3,27 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Http.Features.Authentication
|
||||
{
|
||||
public class ChallengeContext
|
||||
{
|
||||
public ChallengeContext(string authenticationScheme, IDictionary<string, string> properties)
|
||||
public ChallengeContext([NotNull] string authenticationScheme) : this(authenticationScheme, properties: null, behavior: ChallengeBehavior.Automatic)
|
||||
{
|
||||
}
|
||||
|
||||
public ChallengeContext([NotNull] string authenticationScheme, IDictionary<string, string> properties, ChallengeBehavior behavior)
|
||||
{
|
||||
AuthenticationScheme = authenticationScheme;
|
||||
Properties = properties ?? new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
Behavior = behavior;
|
||||
}
|
||||
|
||||
public string AuthenticationScheme { get; }
|
||||
|
||||
public ChallengeBehavior Behavior { get; }
|
||||
|
||||
public IDictionary<string, string> Properties { get; }
|
||||
|
||||
public bool Accepted { get; private set; }
|
||||
|
|
|
|||
|
|
@ -9,14 +9,12 @@ namespace Microsoft.AspNet.Http.Features.Authentication
|
|||
{
|
||||
void GetDescriptions(DescribeSchemesContext context);
|
||||
|
||||
void Authenticate(AuthenticateContext context);
|
||||
|
||||
Task AuthenticateAsync(AuthenticateContext context);
|
||||
|
||||
void Challenge(ChallengeContext context);
|
||||
Task ChallengeAsync(ChallengeContext context);
|
||||
|
||||
void SignIn(SignInContext context);
|
||||
Task SignInAsync(SignInContext context);
|
||||
|
||||
void SignOut(SignOutContext context);
|
||||
Task SignOutAsync(SignOutContext context);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Http.Features
|
||||
{
|
||||
|
|
@ -14,7 +15,7 @@ namespace Microsoft.AspNet.Http.Features
|
|||
IDictionary<string, string[]> Headers { get; set; }
|
||||
Stream Body { get; set; }
|
||||
bool HasStarted { get; }
|
||||
void OnResponseStarting(Action<object> callback, object state);
|
||||
void OnResponseCompleted(Action<object> callback, object state);
|
||||
void OnStarting(Func<object, Task> callback, object state);
|
||||
void OnCompleted(Func<object, Task> callback, object state);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,66 +48,29 @@ namespace Microsoft.AspNet.Http.Authentication.Internal
|
|||
return describeContext.Results.Select(description => new AuthenticationDescription(description));
|
||||
}
|
||||
|
||||
public override AuthenticationResult Authenticate([NotNull] string authenticationScheme)
|
||||
public override async Task AuthenticateAsync([NotNull] AuthenticateContext context)
|
||||
{
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
|
||||
var authenticateContext = new AuthenticateContext(authenticationScheme);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.Authenticate(authenticateContext);
|
||||
await handler.AuthenticateAsync(context);
|
||||
}
|
||||
|
||||
if (!authenticateContext.Accepted)
|
||||
if (!context.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}");
|
||||
throw new InvalidOperationException($"The following authentication scheme was not accepted: {context.AuthenticationScheme}");
|
||||
}
|
||||
|
||||
if (authenticateContext.Principal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AuthenticationResult(authenticateContext.Principal,
|
||||
new AuthenticationProperties(authenticateContext.Properties),
|
||||
new AuthenticationDescription(authenticateContext.Description));
|
||||
}
|
||||
|
||||
public override async Task<AuthenticationResult> AuthenticateAsync([NotNull] string authenticationScheme)
|
||||
public override async Task ChallengeAsync([NotNull] string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior)
|
||||
{
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
|
||||
var authenticateContext = new AuthenticateContext(authenticationScheme);
|
||||
var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items, behavior);
|
||||
if (handler != null)
|
||||
{
|
||||
await handler.AuthenticateAsync(authenticateContext);
|
||||
}
|
||||
|
||||
// Verify all types ack'd
|
||||
if (!authenticateContext.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}");
|
||||
}
|
||||
|
||||
if (authenticateContext.Principal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AuthenticationResult(authenticateContext.Principal,
|
||||
new AuthenticationProperties(authenticateContext.Properties),
|
||||
new AuthenticationDescription(authenticateContext.Description));
|
||||
}
|
||||
|
||||
public override void Challenge(string authenticationScheme, AuthenticationProperties properties)
|
||||
{
|
||||
HttpResponseFeature.StatusCode = 401;
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
|
||||
var challengeContext = new ChallengeContext(authenticationScheme, properties?.Items);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.Challenge(challengeContext);
|
||||
await handler.ChallengeAsync(challengeContext);
|
||||
}
|
||||
|
||||
// The default Challenge with no scheme is always accepted
|
||||
|
|
@ -117,43 +80,36 @@ namespace Microsoft.AspNet.Http.Authentication.Internal
|
|||
}
|
||||
}
|
||||
|
||||
public override void SignIn([NotNull] string authenticationScheme, [NotNull] ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
public override async Task SignInAsync([NotNull] string authenticationScheme, [NotNull] ClaimsPrincipal principal, AuthenticationProperties properties)
|
||||
{
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
|
||||
var signInContext = new SignInContext(authenticationScheme, principal, properties?.Items);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.SignIn(signInContext);
|
||||
await handler.SignInAsync(signInContext);
|
||||
}
|
||||
|
||||
// Verify all types ack'd
|
||||
if (!signInContext.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void SignOut(string authenticationScheme, AuthenticationProperties properties)
|
||||
public override async Task SignOutAsync([NotNull] string authenticationScheme, AuthenticationProperties properties)
|
||||
{
|
||||
var handler = HttpAuthenticationFeature.Handler;
|
||||
|
||||
var signOutContext = new SignOutContext(authenticationScheme, properties?.Items);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.SignOut(signOutContext);
|
||||
await handler.SignOutAsync(signOutContext);
|
||||
}
|
||||
|
||||
// Verify all types ack'd
|
||||
if (!string.IsNullOrWhiteSpace(authenticationScheme) && !signOutContext.Accepted)
|
||||
{
|
||||
throw new InvalidOperationException($"The following authentication scheme was not accepted: {authenticationScheme}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void SignOut(string authenticationScheme)
|
||||
{
|
||||
SignOut(authenticationScheme, properties: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.FeatureModel;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Features.Internal;
|
||||
|
|
@ -94,14 +95,14 @@ namespace Microsoft.AspNet.Http.Internal
|
|||
get { return HttpResponseFeature.HasStarted; }
|
||||
}
|
||||
|
||||
public override void OnResponseStarting(Action<object> callback, object state)
|
||||
public override void OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
HttpResponseFeature.OnResponseStarting(callback, state);
|
||||
HttpResponseFeature.OnStarting(callback, state);
|
||||
}
|
||||
|
||||
public override void OnResponseCompleted(Action<object> callback, object state)
|
||||
public override void OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
HttpResponseFeature.OnResponseCompleted(callback, state);
|
||||
HttpResponseFeature.OnCompleted(callback, state);
|
||||
}
|
||||
|
||||
public override void Redirect(string location, bool permanent)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Http.Features.Internal
|
||||
{
|
||||
|
|
@ -29,14 +30,14 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
|||
get { return false; }
|
||||
}
|
||||
|
||||
public void OnResponseStarting(Action<object> callback, object state)
|
||||
public void OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnResponseCompleted(Action<object> callback, object state)
|
||||
public void OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,15 @@ namespace Microsoft.AspNet.Owin
|
|||
{ OwinConstants.ResponseReasonPhrase, new FeatureMap<IHttpResponseFeature>(feature => feature.ReasonPhrase, (feature, value) => feature.ReasonPhrase = Convert.ToString(value)) },
|
||||
{ OwinConstants.ResponseHeaders, new FeatureMap<IHttpResponseFeature>(feature => feature.Headers, (feature, value) => feature.Headers = (IDictionary<string, string[]>)value) },
|
||||
{ OwinConstants.ResponseBody, new FeatureMap<IHttpResponseFeature>(feature => feature.Body, () => Stream.Null, (feature, value) => feature.Body = (Stream)value) },
|
||||
{ OwinConstants.CommonKeys.OnSendingHeaders, new FeatureMap<IHttpResponseFeature>(feature => new Action<Action<object>, object>(feature.OnResponseStarting)) },
|
||||
{ OwinConstants.CommonKeys.OnSendingHeaders, new FeatureMap<IHttpResponseFeature>(
|
||||
feature => new Action<Action<object>, object>((cb, state) => {
|
||||
feature.OnStarting(s =>
|
||||
{
|
||||
cb(s);
|
||||
return Task.FromResult(0);
|
||||
}, state);
|
||||
}))
|
||||
},
|
||||
|
||||
{ OwinConstants.CommonKeys.LocalPort, new FeatureMap<IHttpConnectionFeature>(feature => feature.LocalPort.ToString(CultureInfo.InvariantCulture),
|
||||
(feature, value) => feature.LocalPort = Convert.ToInt32(value, CultureInfo.InvariantCulture)) },
|
||||
|
|
|
|||
|
|
@ -147,17 +147,19 @@ namespace Microsoft.AspNet.Owin
|
|||
get { return _headersSent; }
|
||||
}
|
||||
|
||||
void IHttpResponseFeature.OnResponseStarting(Action<object> callback, object state)
|
||||
void IHttpResponseFeature.OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
var register = Prop<Action<Action<object>, object>>(OwinConstants.CommonKeys.OnSendingHeaders);
|
||||
if (register == null)
|
||||
{
|
||||
throw new NotSupportedException(OwinConstants.CommonKeys.OnSendingHeaders);
|
||||
}
|
||||
register(callback, state);
|
||||
|
||||
// Need to block on the callback since we can't change the OWIN signature to be async
|
||||
register(s => callback(s).GetAwaiter().GetResult(), state);
|
||||
}
|
||||
|
||||
void IHttpResponseFeature.OnResponseCompleted(Action<object> callback, object state)
|
||||
void IHttpResponseFeature.OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,50 +18,46 @@ namespace Microsoft.AspNet.Http.Authentication.Internal
|
|||
public async Task AuthenticateWithNoAuthMiddlewareThrows()
|
||||
{
|
||||
var context = CreateContext();
|
||||
Assert.Throws<InvalidOperationException>(() => context.Authentication.Authenticate("Foo"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await context.Authentication.AuthenticateAsync("Foo"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ChallengeWithNoAuthMiddlewareMayThrow()
|
||||
public async Task ChallengeWithNoAuthMiddlewareMayThrow()
|
||||
{
|
||||
var context = CreateContext();
|
||||
context.Authentication.Challenge();
|
||||
Assert.Equal(401, context.Response.StatusCode);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => context.Authentication.Challenge("Foo"));
|
||||
await context.Authentication.ChallengeAsync();
|
||||
Assert.Equal(200, context.Response.StatusCode);
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.Authentication.ChallengeAsync("Foo"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SignInWithNoAuthMiddlewareThrows()
|
||||
public async Task SignInWithNoAuthMiddlewareThrows()
|
||||
{
|
||||
var context = CreateContext();
|
||||
Assert.Throws<InvalidOperationException>(() => context.Authentication.SignIn("Foo", new ClaimsPrincipal()));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.Authentication.SignInAsync("Foo", new ClaimsPrincipal()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SignOutWithNoAuthMiddlewareMayThrow()
|
||||
public async Task SignOutWithNoAuthMiddlewareMayThrow()
|
||||
{
|
||||
var context = CreateContext();
|
||||
context.Authentication.SignOut();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => context.Authentication.SignOut("Foo"));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => context.Authentication.SignOutAsync("Foo"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SignInOutIn()
|
||||
public async Task SignInOutIn()
|
||||
{
|
||||
var context = CreateContext();
|
||||
var handler = new AuthHandler();
|
||||
context.SetFeature<IHttpAuthenticationFeature>(new HttpAuthenticationFeature() { Handler = handler });
|
||||
var user = new ClaimsPrincipal();
|
||||
context.Authentication.SignIn("ignored", user);
|
||||
await context.Authentication.SignInAsync("ignored", user);
|
||||
Assert.True(handler.SignedIn);
|
||||
context.Authentication.SignOut("ignored");
|
||||
await context.Authentication.SignOutAsync("ignored");
|
||||
Assert.False(handler.SignedIn);
|
||||
context.Authentication.SignIn("ignored", user);
|
||||
await context.Authentication.SignInAsync("ignored", user);
|
||||
Assert.True(handler.SignedIn);
|
||||
context.Authentication.SignOut("ignored", new AuthenticationProperties() { RedirectUri = "~/logout" });
|
||||
await context.Authentication.SignOutAsync("ignored", new AuthenticationProperties() { RedirectUri = "~/logout" });
|
||||
Assert.False(handler.SignedIn);
|
||||
}
|
||||
|
||||
|
|
@ -69,17 +65,12 @@ namespace Microsoft.AspNet.Http.Authentication.Internal
|
|||
{
|
||||
public bool SignedIn { get; set; }
|
||||
|
||||
public void Authenticate(AuthenticateContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task AuthenticateAsync(AuthenticateContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Challenge(ChallengeContext context)
|
||||
public Task ChallengeAsync(ChallengeContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
@ -89,16 +80,18 @@ namespace Microsoft.AspNet.Http.Authentication.Internal
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SignIn(SignInContext context)
|
||||
public Task SignInAsync(SignInContext context)
|
||||
{
|
||||
SignedIn = true;
|
||||
context.Accept();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public void SignOut(SignOutContext context)
|
||||
public Task SignOutAsync(SignOutContext context)
|
||||
{
|
||||
SignedIn = false;
|
||||
context.Accept();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue