|
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Net; |
|
using System.Net.Http; |
|
using System.Security.Principal; |
|
using System.Threading; |
|
using System.Web; |
|
using System.Web.Http; |
|
using System.Web.Http.Controllers; |
|
|
|
namespace Infrastructure |
|
{ |
|
public class NewAuthorize : AuthorizeAttribute |
|
{ |
|
|
|
private static readonly string[] _emptyArray = new string[0]; |
|
|
|
private readonly object _typeId = new object(); |
|
|
|
private string _roles; |
|
private string[] _rolesSplit = _emptyArray; |
|
private string _users; |
|
private string[] _usersSplit = _emptyArray; |
|
|
|
new public string Roles |
|
{ |
|
get { return _roles ?? String.Empty; } |
|
set |
|
{ |
|
_roles = value; |
|
_rolesSplit = SplitString(value); |
|
} |
|
} |
|
|
|
new public string Users |
|
{ |
|
get { return _users ?? String.Empty; } |
|
set |
|
{ |
|
_users = value; |
|
_usersSplit = SplitString(value); |
|
} |
|
} |
|
|
|
protected override bool IsAuthorized(HttpActionContext actionContext) |
|
{ |
|
if (actionContext == null) |
|
{ |
|
throw new ArgumentNullException("actionContext"); |
|
} |
|
|
|
IPrincipal user = Thread.CurrentPrincipal; |
|
if (user == null || !user.Identity.IsAuthenticated) |
|
{ |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
protected bool IsAllowed(HttpActionContext actionContext) |
|
{ |
|
if (actionContext == null) |
|
{ |
|
throw new ArgumentNullException("actionContext"); |
|
} |
|
|
|
IPrincipal user = Thread.CurrentPrincipal; |
|
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) |
|
{ |
|
return false; |
|
} |
|
|
|
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) |
|
{ |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override void OnAuthorization(HttpActionContext actionContext) |
|
{ |
|
if (actionContext == null) |
|
{ |
|
throw new ArgumentNullException("actionContext"); |
|
} |
|
|
|
if (SkipAuthorization(actionContext)) |
|
{ |
|
return; |
|
} |
|
|
|
if (!IsAuthorized(actionContext)) |
|
{ |
|
HandleUnauthorizedRequest(actionContext); |
|
} |
|
|
|
if (!IsAllowed(actionContext)) |
|
{ |
|
HandleForbiddenRequest(actionContext); |
|
} |
|
} |
|
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) |
|
{ |
|
if (actionContext == null) |
|
{ |
|
throw new ArgumentNullException("actionContext"); |
|
} |
|
|
|
HttpResponseMessage result = new HttpResponseMessage() |
|
{ |
|
StatusCode = HttpStatusCode.Unauthorized, |
|
RequestMessage = actionContext.Request |
|
}; |
|
|
|
actionContext.Response = result; |
|
} |
|
|
|
protected void HandleForbiddenRequest(HttpActionContext actionContext) |
|
{ |
|
if (actionContext == null) |
|
{ |
|
throw new ArgumentNullException("actionContext"); |
|
} |
|
|
|
HttpResponseMessage result = new HttpResponseMessage() |
|
{ |
|
StatusCode = HttpStatusCode.Forbidden, |
|
RequestMessage = actionContext.Request |
|
}; |
|
|
|
actionContext.Response = result; |
|
} |
|
|
|
private static bool SkipAuthorization(HttpActionContext actionContext) |
|
{ |
|
if (actionContext == null) |
|
{ |
|
throw new ArgumentNullException("actionContext"); |
|
} |
|
|
|
return actionContext.ActionDescriptor.GetCustomAttributes().Any() |
|
|| actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes().Any(); |
|
} |
|
|
|
internal static string[] SplitString(string original) |
|
{ |
|
if (String.IsNullOrEmpty(original)) |
|
{ |
|
return _emptyArray; |
|
} |
|
|
|
var split = from piece in original.Split(',') |
|
let trimmed = piece.Trim() |
|
where !String.IsNullOrEmpty(trimmed) |
|
select trimmed; |
|
return split.ToArray(); |
|
} |
|
} |
|
} |
Nice work on this! A comment and a question:
AuthorizationFilterAttribute
method has a compile error with the calls toGetCustomAttributes()
unless you pass a type parameter (like the original AuthorizeAttribute does:.GetCustomAttributes<AllowAnonymousAttribute>()
)