2016-08-30 3 views
1

Я пытаюсь добавить настраиваемую политику авторизации, которая может проверять список групп, предоставленных в конфигурационном файле json. Я использую ASP.Net 5 - MVC 6, а также проверку подлинности Windows.ASP.Net 5 AuthorizationHandler Fail Redirect

Все работает нормально, за исключением случаев, когда я вызываю Fail. Тогда ничего не происходит. Отображается пустой экран. Вот мой метод HandleRequirementAsync. Я пробовал различные значения для результата задачи. Я бегаю, как сумасшедший, но без везения. Надеюсь, кто-то может помочь.

ЖЕЛАТЕЛЬНЫЙ РЕЗУЛЬТАТ: Я хотел бы перенаправить на пользовательскую страницу при сбое, но если это невозможно, по крайней мере, можно перенаправить обратно на страницу входа. Единственное, что, кажется, имеет какой-либо эффект, - это выбросить исключение.

Соответствующий регистрационный код в Startup:

var appSettings = Configuration.GetSection("AppSettings"); 
services.Configure<Models.AppSettings>(appSettings); 

services.AddMvc(); 

services.AddAuthorization(options => 
{ 
    options.AddPolicy("RoleAuth", policy => policy.Requirements.Add(new RolesRequirement(appSettings["AllowedGroups"]))); 
}); 

services.AddSingleton<IAuthorizationHandler, RoleAuthorizationHandler>(); 

И авторизации классов:

public class RolesRequirement : IAuthorizationRequirement 
{ 
    public RolesRequirement(string groups) 
    { 
     Groups = groups; 
    } 

    public string Groups { get; private set; } 
} 

public class RoleAuthorizationHandler : AuthorizationHandler<RolesRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesRequirement requirement) 
    { 
     if (!string.IsNullOrWhiteSpace(requirement.Groups)) 
     { 
      Console.WriteLine(requirement.Groups); 
      var groups = requirement.Groups.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); 

      //we could check for group membership here.... maybe??? 
      foreach (var group in groups) 
      { 
       if (context.User.IsInRole(group)) 
       { 
        context.Succeed(requirement); 
        return Task.FromResult(0); 
       } 
      } 
     } 
     else 
     { 
      context.Succeed(requirement); 
     } 

     context.Fail(); 
     return Task.FromResult(0); 
    } 
} 
+0

Также в настоящее время ищет способ перенаправления при возникновении сбоя, вам когда-либо не повезло? –

+0

Nope Alex. Не повезло. Сожалею. – SpaceGhost440

ответ

0

Я пошел с предложенным героизмом, но Политики могут бросить вызов или запретить.После яркости излучателя луча подсветки исследований я наткнулся на то, что дает прямой доступ к AuthorizationFilterContext, как это (потому что они следуют соглашению об именах и наследоваться от AuthorizeAttribute:

public class BudgetAccessFilterAttribute : AuthorizeAttribute, IAuthorizationFilter 
{ 
    public void OnAuthorization(AuthorizationFilterContext context) 
    { 
     //context.HttpContext.User.Identity.Name 
     //TODO: determine if user has access to budget controllers, all of them could inherit from a Common Controller with this Filter 
     if (false) 
     { 
      //if no access then 
      context.Result = new RedirectToActionResult("Index", "Home", null); 
     } 
    }  
} 

Вы можете украсить свои контроллеры, как это:

[BudgetAccessFilter] 
public class BudgetItemController : Controller 
{ 

} 

И если у вас будет много контроллеров с одной и той же проверки, то все они могут наследовать от базового класса с аннотацией, как это:

[BudgetAccessFilter] 
public class BCommonController : Controller 
{ 
} 

И затем чистые контроллеры:

public class BudgetItemController : BCommonController 
{ 
} 
-2

Я использую проверку подлинности печенья вместо окон, но в моем методе Configure в Startup.cs I имеют следующий фрагмент кода, в котором говорится, куда следует направлять

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    LoginPath = "/account/login", 
    AuthenticationScheme = "Cookies", 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true 
}); 
+0

Это решение будет иметь отношение только к аутентификации cookie. –

-2

Я не знаю, если вы можете настроить результат перенаправления, но, по крайней мере, мне удалось создать такой файл «Account/AccessDenied.cshtml», который будет показан в случае сбоя. «Учетная запись» - это имя моего класса, и когда произошел сбой, браузер был перенаправлен на этот URL: (http://localhost:39339/Account/AccessDenied?ReturnUrl=%2Fapp%2Fequipments)

Вот мой код контроллера (Web/AccountController.cs).

public class AccountController : Controller 
{ 
    public IActionResult AccessDenied() 
    { 
     return View(); 
    } 
} 
+0

Этот код не имеет отношения к вопросу. –

2

Единственный способ я нашел делать это, не используйте context.Fail(), вместо того, чтобы сделать это:

заменить:

context.Fail(); 

с:

var mvcContext = context.Resource as AuthorizationFilterContext; 
mvcContext.Result = new RedirectToActionResult("Action", "Controller", null); 
context.Succeed(requirement); 

, позволяющий контексту преуспеть, выполнит контекст, который теперь является перенаправлением.