2016-05-17 1 views
4

Я работаю над настройкой скелета пользовательской авторизации на основе политики, которая будет иметь набор бизнес-правил для авторизации текущего пользователя. Но в настоящее время скелет всегда заканчивается 401 Unauthorized.На основе авторизации на основе основной политики Asp.Net заканчивается 401 Unauthorized

Вот мой код,

public class MyAuthorizationRequirement : IAuthorizationRequirement 
{ 
    public MyAuthorizationRequirement() 
    {  
    } 
} 

public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationRequirement> 
{ 
    public MyAuthorizationHandler() 
    { 
    } 

    protected override void Handle(AuthorizationContext context, MyAuthorizationRequirement requirement) 
    { 
     context.Succeed(requirement); 
    } 
} 

И следуя в Startup.cs

public void ConfigureServices(IServiceCollection services) 
    { 
     services.AddSingleton<IAuthorizationHandler, MyAuthorizationHandler>() 
     .AddAuthorization(options => 
     { 
      options.AddPolicy("MyAuthorization", 
           policy => policy.Requirements.Add(new MyAuthorizationRequirement())); 
     }); 
    } 

И это, как я использую его в моем HomeController (MVC 6)

[Authorize(Policy = "MyAuthorization")] 
public class HomeController : Controller 
{ 
    public IActionResult Index() 
    { 
     return View(); 
    } 
} 

When Я не помещаю атрибут Authorize, представление индекса отлично. Но, когда я включаю атрибут Authorize, я просто получаю пустой вид. И когда я проверяю инструменты разработчика (Сеть), я получаю следующее за деталями сцены.

Request URL:http://localhost:51129/ 
Request Method:GET 
Status Code:401 Unauthorized 
Remote Address:[::1]:51129 

В контрольных точках в конструкторы моих требований и обработчиков классов вызываются, но контрольные точки к Handle методе Handler класса и Index метода Controller класса никогда не получают вызов.

+0

Использовали ли вы какое-либо «промежуточное программное обеспечение аутентификации»? –

ответ

2

Это связано с тем, что добавленный к конвейеру AuthorizeFilter для каждого атрибута [Authorize] требует от пользователей аутентификации.

Если посмотреть на исходный код, вы увидите, что даже без вызова какой-либо политики, она убеждается аутентификации пользователя:

// Note: Default Anonymous User is new ClaimsPrincipal(new ClaimsIdentity()) 
if (httpContext.User == null || 
    !httpContext.User.Identities.Any(i => i.IsAuthenticated) || 
    !await authService.AuthorizeAsync(httpContext.User, context, Policy)) 
{ 
    context.Result = new ChallengeResult(Policy.AuthenticationSchemes.ToArray()); 
} 

Это условие httpContext.User.Identities.Any(i => i.IsAuthenticated) будет ложным для анонимных пользователей.

  • Существует также в AuthorizationOptions, который проверяет аутентификации пользователя DefaultPolicy. Вы можете установить, что в нуль в конфигурации AddAuthorization, но даже в этом случае выше AuthorizeFilter будет убедиться, что проверка подлинности пользователя

Самый простой способ как раз для вас, чтобы попробовать ваш код будет добавление с проверкой подлинности анонимного пользователя, так что любой анонимный пользователь получает назначен ClaimsPrincipal, что авторизован (как это имеет GenericIdentity вместо пустого ClaimsIdentity):

//Add this before app.UseMvc 
app.Use(async (context, next) => 
{ 
    if (!context.User.Identities.Any(i => i.IsAuthenticated)) 
    { 
     //Assign all anonymous users the same generic identity, which is authenticated 
     context.User = new ClaimsPrincipal(new GenericIdentity("anonymous")); 
    } 
    await next.Invoke(); 

}); 

В реальном приложении вы, вероятно, есть некоторые структуры аутентификации, где пользователи могут проходить проверку подлинности, так что у вас не было бы Эта проблема.

В противном случае вам может потребоваться сыграть с соглашениями об использовании и заменить AuthorizeFilter на вашу собственную измененную реализацию, которая не требует аутентифицированных пользователей, this answer идет в этом направлении.

+0

Большое вам спасибо за то, что потратили свое драгоценное время на предоставление мне идеального ориентира. Это один из лучших ответов, который я когда-либо получал. Он работает отлично. –

+0

В моем случае у меня есть полноценный ASP4.5, у которого есть все, что касается аутентификации и прочее, этот новый веб-сайт ASP Core был добавлен для добавления новых страниц в более сложные технологии. Пользователь будет перемещаться назад и вперед между этими двумя веб-сайтами, и я хочу убедиться, что он аутентифицирован и авторизирован. Сейчас мой план состоит в том, чтобы прочитать cookie «ASP.NET_SessionId» из «Запроса» и перейти к бизнес-логике для авторизации. –

+0

Не беспокойтесь, я рад, что смогу помочь! Я также изучаю ASP Core самостоятельно, так что это тоже в моих интересах :) Я вижу, как только вы закончите создание нового сайта, у вас будет надлежащая проверка подлинности и не столкнется с этой проблемой. –

Смежные вопросы