Update: Error UI Updated

This commit is contained in:
Gary Sharp
2013-11-14 13:34:53 +11:00
parent b1048588e7
commit fe00963cb0
19 changed files with 514 additions and 160 deletions
@@ -45,25 +45,26 @@ namespace Disco.Services.Authorization
#region Token Accessors
internal const string RequireAuthenticationMessage = "This Disco feature requires authentication.";
internal const string RequireDiscoAuthorizationMessage = "Your account does not have the required permission to access this Disco feature. This feature requires your account to be included in at least one Disco Authorization Role.";
internal const string RequireMessageTemplate = "Your account does not have the required permission ({0}) to access this Disco feature.";
internal const string RequireAllMessageTemplate = "Your account does not have the required permission to access this Disco feature. This feature requires permission for: {0}.";
internal const string RequireAnyMessageTemplate = "Your account does not have the required permission to access this Disco feature. This feature requires at least one of these permissions: {0}.";
internal const string RequireAuthenticationMessage = "This feature requires authentication.";
internal const string RequireDiscoAuthorizationMessage = "Your account does not have the required permission to access this feature. This feature requires your account to be included in at least one Disco Authorization Role.";
internal const string RequireMessageTemplate = "Your account does not have the required permission to access this feature.\r\n";
internal const string RequireMessageSingleTemplate = RequireMessageTemplate + "This feature requires the following permission:\r\n- {0}";
internal const string RequireAllMessageTemplate = RequireMessageTemplate + "This feature requires permission for:{0}.";
internal const string RequireAnyMessageTemplate = RequireMessageTemplate + "This feature requires at least one of these permissions:{0}.";
internal static string BuildRequireMessage(string ClaimKey)
{
return string.Format(RequireMessageTemplate, Claims.GetClaimDetails(ClaimKey).Item1);
return string.Format(RequireMessageSingleTemplate, Claims.GetClaimDetails(ClaimKey).Item1);
}
internal static string BuildRequireAllMessage(IEnumerable<string> ClaimKeys)
{
var claimFriendlyNames = ClaimKeys.Select(ck => Claims.GetClaimDetails(ck).Item1);
return string.Format(RequireAllMessageTemplate, string.Join("; ", claimFriendlyNames));
return string.Format(RequireAllMessageTemplate, string.Join("\r\n- ", claimFriendlyNames));
}
internal static string BuildRequireAnyMessage(IEnumerable<string> ClaimKeys)
{
var claimFriendlyNames = ClaimKeys.Select(ck => Claims.GetClaimDetails(ck).Item1);
return string.Format(RequireAnyMessageTemplate, string.Join("; ", claimFriendlyNames));
return string.Format(RequireAnyMessageTemplate, string.Join("\r\n- ", claimFriendlyNames));
}
/// <summary>
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
@@ -34,30 +35,44 @@ namespace Disco.Services.Authorization
protected sealed override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
string resultMessage = HandleUnauthorizedMessage();
string resultResource = BuildAuthorizeResource(filterContext);
LogAccessDenied(filterContext, resultMessage);
// Log Access Denied
if (Token != null) // Don't log anonymous
AuthorizationLog.LogAccessDenied(Token.User.Id, resultResource, resultMessage);
filterContext.Result = new HttpUnauthorizedResult(resultMessage);
// Build Response View
var ex = new AccessDeniedException(resultMessage, resultResource);
HandleErrorInfo model = new HandleErrorInfo(ex, filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName);
ViewResult result = new ViewResult
{
ViewName = "Error",
MasterName = Token == null ? "_PublicLayout" : "_Layout",
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
filterContext.Result = result;
var contextResponse = filterContext.HttpContext.Response;
contextResponse.Clear();
contextResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
contextResponse.TrySkipIisCustomErrors = true;
}
public void LogAccessDenied(AuthorizationContext FilterContext, string ResultMessage)
private string BuildAuthorizeResource(AuthorizationContext FilterContext)
{
// Don't log anonymous
if (Token != null)
var authResource = AuthorizeResource;
var url = FilterContext.HttpContext.Request.RawUrl;
if (authResource == null)
{
// Calculate Authorize Resource
if (AuthorizeResource == null)
{
var controllerName = FilterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var actionName = FilterContext.ActionDescriptor.ActionName;
var controllerName = FilterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var actionName = FilterContext.ActionDescriptor.ActionName;
AuthorizeResource = string.Format("{0}::{1}", controllerName, actionName);
}
var resource = string.Format("{0} [{1}]", AuthorizeResource, FilterContext.HttpContext.Request.RawUrl);
AuthorizationLog.LogAccessDenied(Token.User.Id, resource, ResultMessage);
authResource = string.Format("{0}::{1}", controllerName, actionName);
}
return string.Format("{0} [{1}]", authResource, url);
}
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ namespace Disco.Services.Web
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
HandleErrorInfo model = new HandleErrorInfo(ex, controllerName, actionName);
HandleErrorInfo model = new HandleErrorInfo(ex, controllerName ?? "Unknown", actionName ?? "Unknown");
ViewResult result = new ViewResult
{
ViewName = "Error",