Adding Controller.Challenge and Controller.Forbid

This commit is contained in:
Pranav K 2015-11-02 11:35:44 -08:00
parent af1142e7b5
commit 940fb7ba78
5 changed files with 192 additions and 26 deletions

View File

@ -11,43 +11,86 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
/// <summary>
/// An <see cref="ActionResult"/> that on execution invokes <see cref="AuthenticationManager.ChallengeAsync"/>.
/// </summary>
public class ChallengeResult : ActionResult public class ChallengeResult : ActionResult
{ {
/// <summary>
/// Initializes a new instance of <see cref="ChallengeResult"/>.
/// </summary>
public ChallengeResult() public ChallengeResult()
: this(new string[] { }) : this(new string[] { })
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="ChallengeResult"/> with the
/// specified authentication scheme.
/// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param>
public ChallengeResult(string authenticationScheme) public ChallengeResult(string authenticationScheme)
: this(new[] { authenticationScheme }) : this(new[] { authenticationScheme })
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="ChallengeResult"/> with the
/// specified authentication schemes.
/// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param>
public ChallengeResult(IList<string> authenticationSchemes) public ChallengeResult(IList<string> authenticationSchemes)
: this(authenticationSchemes, properties: null) : this(authenticationSchemes, properties: null)
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="ChallengeResult"/> with the
/// specified <paramref name="properties"/>.
/// </summary>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
public ChallengeResult(AuthenticationProperties properties) public ChallengeResult(AuthenticationProperties properties)
: this(new string[] { }, properties) : this(new string[] { }, properties)
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="ChallengeResult"/> with the
/// specified authentication scheme and <paramref name="properties"/>.
/// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
public ChallengeResult(string authenticationScheme, AuthenticationProperties properties) public ChallengeResult(string authenticationScheme, AuthenticationProperties properties)
: this(new[] { authenticationScheme }, properties) : this(new[] { authenticationScheme }, properties)
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="ChallengeResult"/> with the
/// specified authentication schemes and <paramref name="properties"/>.
/// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
public ChallengeResult(IList<string> authenticationSchemes, AuthenticationProperties properties) public ChallengeResult(IList<string> authenticationSchemes, AuthenticationProperties properties)
{ {
AuthenticationSchemes = authenticationSchemes; AuthenticationSchemes = authenticationSchemes;
Properties = properties; Properties = properties;
} }
/// <summary>
/// Gets or sets the authentication schemes that are challenged.
/// </summary>
public IList<string> AuthenticationSchemes { get; set; } public IList<string> AuthenticationSchemes { get; set; }
/// <summary>
/// Gets or sets the <see cref="AuthenticationProperties"/> used to perform the authentication challenge.
/// </summary>
public AuthenticationProperties Properties { get; set; } public AuthenticationProperties Properties { get; set; }
/// <inheritdoc />
public override async Task ExecuteResultAsync(ActionContext context) public override async Task ExecuteResultAsync(ActionContext context)
{ {
if (context == null) if (context == null)
@ -70,7 +113,7 @@ namespace Microsoft.AspNet.Mvc
{ {
await authentication.ChallengeAsync(Properties); await authentication.ChallengeAsync(Properties);
} }
logger.ChallengeResultExecuting(AuthenticationSchemes); logger.ChallengeResultExecuting(AuthenticationSchemes);
} }
} }

View File

@ -12,70 +12,69 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
/// <summary> /// <summary>
/// An <see cref="ActionResult"/> that on execution issues a 403 forbidden response /// An <see cref="ActionResult"/> that on execution invokes <see cref="AuthenticationManager.ForbidAsync"/>.
/// if the authentication challenge is unacceptable.
/// </summary> /// </summary>
public class ForbiddenResult : ActionResult public class ForbidResult : ActionResult
{ {
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ForbiddenResult"/>. /// Initializes a new instance of <see cref="ForbidResult"/>.
/// </summary> /// </summary>
public ForbiddenResult() public ForbidResult()
: this(new string[] { }) : this(new string[] { })
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ForbiddenResult"/> with the /// Initializes a new instance of <see cref="ForbidResult"/> with the
/// specified authentication scheme. /// specified authentication scheme.
/// </summary> /// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param> /// <param name="authenticationScheme">The authentication scheme to challenge.</param>
public ForbiddenResult(string authenticationScheme) public ForbidResult(string authenticationScheme)
: this(new[] { authenticationScheme }) : this(new[] { authenticationScheme })
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ForbiddenResult"/> with the /// Initializes a new instance of <see cref="ForbidResult"/> with the
/// specified authentication schemes. /// specified authentication schemes.
/// </summary> /// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param> /// <param name="authenticationScheme">The authentication schemes to challenge.</param>
public ForbiddenResult(IList<string> authenticationSchemes) public ForbidResult(IList<string> authenticationSchemes)
: this(authenticationSchemes, properties: null) : this(authenticationSchemes, properties: null)
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ForbiddenResult"/> with the /// Initializes a new instance of <see cref="ForbidResult"/> with the
/// specified <paramref name="properties"/>. /// specified <paramref name="properties"/>.
/// </summary> /// </summary>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param> /// challenge.</param>
public ForbiddenResult(AuthenticationProperties properties) public ForbidResult(AuthenticationProperties properties)
: this(new string[] { }, properties) : this(new string[] { }, properties)
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ForbiddenResult"/> with the /// Initializes a new instance of <see cref="ForbidResult"/> with the
/// specified authentication scheme and <paramref name="properties"/>. /// specified authentication scheme and <paramref name="properties"/>.
/// </summary> /// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param> /// <param name="authenticationScheme">The authentication schemes to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param> /// challenge.</param>
public ForbiddenResult(string authenticationScheme, AuthenticationProperties properties) public ForbidResult(string authenticationScheme, AuthenticationProperties properties)
: this(new[] { authenticationScheme }, properties) : this(new[] { authenticationScheme }, properties)
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ForbiddenResult"/> with the /// Initializes a new instance of <see cref="ForbidResult"/> with the
/// specified authentication schemes and <paramref name="properties"/>. /// specified authentication schemes and <paramref name="properties"/>.
/// </summary> /// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param> /// <param name="authenticationScheme">The authentication scheme to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication /// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param> /// challenge.</param>
public ForbiddenResult(IList<string> authenticationSchemes, AuthenticationProperties properties) public ForbidResult(IList<string> authenticationSchemes, AuthenticationProperties properties)
{ {
AuthenticationSchemes = authenticationSchemes; AuthenticationSchemes = authenticationSchemes;
Properties = properties; Properties = properties;
@ -100,7 +99,7 @@ namespace Microsoft.AspNet.Mvc
} }
var loggerFactory = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>(); var loggerFactory = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<ForbiddenResult>(); var logger = loggerFactory.CreateLogger<ForbidResult>();
var authentication = context.HttpContext.Authentication; var authentication = context.HttpContext.Authentication;
@ -116,7 +115,7 @@ namespace Microsoft.AspNet.Mvc
await authentication.ForbidAsync(Properties); await authentication.ForbidAsync(Properties);
} }
logger.ForbiddenResultExecuting(AuthenticationSchemes); logger.ForbidResultExecuting(AuthenticationSchemes);
} }
} }
} }

View File

@ -8,15 +8,15 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNet.Mvc.Logging namespace Microsoft.AspNet.Mvc.Logging
{ {
internal static class ForbiddenResultLoggerExtensions internal static class ForbidResultLoggerExtensions
{ {
private static readonly Action<ILogger, string[], Exception> _resultExecuting = private static readonly Action<ILogger, string[], Exception> _resultExecuting =
LoggerMessage.Define<string[]>( LoggerMessage.Define<string[]>(
LogLevel.Information, LogLevel.Information,
eventId: 1, eventId: 1,
formatString: $"Executing {nameof(ForbiddenResult)} with authentication schemes ({{Schemes}})."); formatString: $"Executing {nameof(ForbidResult)} with authentication schemes ({{Schemes}}).");
public static void ForbiddenResultExecuting(this ILogger logger, IList<string> authenticationSchemes) public static void ForbidResultExecuting(this ILogger logger, IList<string> authenticationSchemes)
{ {
_resultExecuting(logger, authenticationSchemes.ToArray(), null); _resultExecuting(logger, authenticationSchemes.ToArray(), null);
} }

View File

@ -2,12 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Security.Claims; using System.Security.Claims;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Mvc.Filters; using Microsoft.AspNet.Mvc.Filters;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.ModelBinding.Validation;
@ -1180,6 +1182,128 @@ namespace Microsoft.AspNet.Mvc
return new CreatedAtRouteResult(routeName, routeValues, value); return new CreatedAtRouteResult(routeName, routeValues, value);
} }
/// <summary>
/// Creates a <see cref="ChallengeResult"/>.
/// </summary>
/// <returns>The created <see cref="ChallengeResult"/> for the response.</returns>
[NonAction]
public virtual ChallengeResult Challenge()
=> new ChallengeResult();
/// <summary>
/// Creates a <see cref="ChallengeResult"/> with the specified authentication scheme.
/// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param>
/// <returns>The created <see cref="ChallengeResult"/> for the response.</returns>
[NonAction]
public virtual ChallengeResult Challenge(string authenticationScheme)
=> new ChallengeResult(authenticationScheme);
/// <summary>
/// Creates a <see cref="ChallengeResult"/> with the specified authentication schemes.
/// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param>
/// <returns>The created <see cref="ChallengeResult"/> for the response.</returns>
[NonAction]
public virtual ChallengeResult Challenge(IList<string> authenticationSchemes)
=> new ChallengeResult(authenticationSchemes);
/// <summary>
/// Creates a <see cref="ChallengeResult"/> with the specified <paramref name="properties" />.
/// </summary>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
/// <returns>The created <see cref="ChallengeResult"/> for the response.</returns>
[NonAction]
public virtual ChallengeResult Challenge(AuthenticationProperties properties)
=> new ChallengeResult(properties);
/// <summary>
/// Creates a <see cref="ChallengeResult"/> with the specified specified authentication scheme and
/// <paramref name="properties" />.
/// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
/// <returns>The created <see cref="ChallengeResult"/> for the response.</returns>
[NonAction]
public virtual ChallengeResult Challenge(string authenticationScheme, AuthenticationProperties properties)
=> new ChallengeResult(authenticationScheme, properties);
/// <summary>
/// Creates a <see cref="ChallengeResult"/> with the specified specified authentication schemes and
/// <paramref name="properties" />.
/// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
/// <returns>The created <see cref="ChallengeResult"/> for the response.</returns>
[NonAction]
public virtual ChallengeResult Challenge(
IList<string> authenticationSchemes,
AuthenticationProperties properties)
=> new ChallengeResult(authenticationSchemes, properties);
/// <summary>
/// Creates a <see cref="ForbidResult"/>.
/// </summary>
/// <returns>The created <see cref="ForbidResult"/> for the response.</returns>
[NonAction]
public virtual ForbidResult Forbid()
=> new ForbidResult();
/// <summary>
/// Creates a <see cref="ForbidResult"/> with the specified authentication scheme.
/// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param>
/// <returns>The created <see cref="ForbidResult"/> for the response.</returns>
[NonAction]
public virtual ForbidResult Forbid(string authenticationScheme)
=> new ForbidResult(authenticationScheme);
/// <summary>
/// Creates a <see cref="ForbidResult"/> with the specified authentication schemes.
/// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param>
/// <returns>The created <see cref="ForbidResult"/> for the response.</returns>
[NonAction]
public virtual ForbidResult Forbid(IList<string> authenticationSchemes)
=> new ForbidResult(authenticationSchemes);
/// <summary>
/// Creates a <see cref="ForbidResult"/> with the specified <paramref name="properties" />.
/// </summary>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
/// <returns>The created <see cref="ForbidResult"/> for the response.</returns>
[NonAction]
public virtual ForbidResult Forbid(AuthenticationProperties properties)
=> new ForbidResult(properties);
/// <summary>
/// Creates a <see cref="ForbidResult"/> with the specified specified authentication scheme and
/// <paramref name="properties" />.
/// </summary>
/// <param name="authenticationScheme">The authentication scheme to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
/// <returns>The created <see cref="ForbidResult"/> for the response.</returns>
[NonAction]
public virtual ForbidResult Forbid(string authenticationScheme, AuthenticationProperties properties)
=> new ForbidResult(authenticationScheme, properties);
/// <summary>
/// Creates a <see cref="ForbidResult"/> with the specified specified authentication schemes and
/// <paramref name="properties" />.
/// </summary>
/// <param name="authenticationScheme">The authentication schemes to challenge.</param>
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication
/// challenge.</param>
/// <returns>The created <see cref="ForbidResult"/> for the response.</returns>
[NonAction]
public virtual ForbidResult Forbid(IList<string> authenticationSchemes, AuthenticationProperties properties)
=> new ForbidResult(authenticationSchemes, properties);
/// <summary> /// <summary>
/// Called before the action method is invoked. /// Called before the action method is invoked.
/// </summary> /// </summary>

View File

@ -16,7 +16,7 @@ using Xunit;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public class ForbiddenResultTest public class ForbidResultTest
{ {
[Fact] [Fact]
public async Task ExecuteResultAsync_InvokesForbiddenAsyncOnAuthenticationManager() public async Task ExecuteResultAsync_InvokesForbiddenAsyncOnAuthenticationManager()
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();
httpContext.Setup(c => c.RequestServices).Returns(CreateServices()); httpContext.Setup(c => c.RequestServices).Returns(CreateServices());
httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object); httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object);
var result = new ForbiddenResult("", null); var result = new ForbidResult("", null);
var routeData = new RouteData(); var routeData = new RouteData();
var actionContext = new ActionContext( var actionContext = new ActionContext(
@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Mvc
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();
httpContext.Setup(c => c.RequestServices).Returns(CreateServices()); httpContext.Setup(c => c.RequestServices).Returns(CreateServices());
httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object); httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object);
var result = new ForbiddenResult(new[] { "Scheme1", "Scheme2" }, authProperties); var result = new ForbidResult(new[] { "Scheme1", "Scheme2" }, authProperties);
var routeData = new RouteData(); var routeData = new RouteData();
var actionContext = new ActionContext( var actionContext = new ActionContext(
@ -97,7 +97,7 @@ namespace Microsoft.AspNet.Mvc
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();
httpContext.Setup(c => c.RequestServices).Returns(CreateServices()); httpContext.Setup(c => c.RequestServices).Returns(CreateServices());
httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object); httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object);
var result = new ForbiddenResult(expected); var result = new ForbidResult(expected);
var routeData = new RouteData(); var routeData = new RouteData();
var actionContext = new ActionContext( var actionContext = new ActionContext(
@ -126,7 +126,7 @@ namespace Microsoft.AspNet.Mvc
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();
httpContext.Setup(c => c.RequestServices).Returns(CreateServices()); httpContext.Setup(c => c.RequestServices).Returns(CreateServices());
httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object); httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object);
var result = new ForbiddenResult(expected) var result = new ForbidResult(expected)
{ {
AuthenticationSchemes = new string[0] AuthenticationSchemes = new string[0]
}; };