none
asp.net core mvc Authorize(Policy= ) не срабатывает RRS feed

  • Вопрос

  • Добрый день

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

    вот код 

     public void fauthorize(AuthorizationOptions op)
            {
                AuthorizationPolicyBuilder apb = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme);
                
                op.AddPolicy("OnlyAdmin", apb.RequireUserName("admin").Build());
            }

      public void ConfigureServices(IServiceCollection services)
      {

       services.AddAuthorization(new Action<Microsoft.AspNetCore.Authorization.AuthorizationOptions>(fauthorize));

     }

    и контроллер

    [Authorize(Policy = "OnlyAdmin")]
            [HttpPost]
            public IActionResult AddUser(string tbName,string SelectedRole)
            {
                return View();
            }

    А вот так авторизуюсь

    List<Claim> l = new List<Claim>();
                Claim c = new Claim(ClaimsIdentity.DefaultNameClaimType, "admin");
                l.Add(c);
                ClaimsIdentity id = new ClaimsIdentity(l, "ApplicationCookie");
                HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(id));

    Вроде все делаю правильно 

    но почему то вот так в метод AddUser меня не пускают

    Пожалуйста подскажите в чем ошибка

    13 декабря 2018 г. 8:40

Ответы

  • Спасибо за ответы

    Да завтра действительно может появиться два администратора и логичнее использовать роли

    Но для меня важен был мой изначальный вариант Просто в целях разобраться

    Вообщем мой код заработал Ошибка была вот тут

    Claim c = new Claim(ClaimsIdentity.DefaultNameClaimType, "admin");

    ClaimsIdentity это не для Claim

    Нужно было использовать ClaimTypes потому что ведь Claim создаем 

    Заменил на ClaimTypes.Name и все заработало

    19 декабря 2018 г. 12:31
  • "ClaimsIdentity это не для Claim Нужно было использовать ClaimTypes потому что ведь Claim создаем" - на самом деле не важно какой тип там используется, все они не что иное как просто строковые константы. Важно чтобы значение данной константы совпало с тем, что используется в классе:

    AuthorizationPolicyBuilder


    Это задаётся в конструкторе ClaimsIdentity, которую я привёл выше. Т.е. для строки

    var claimsIdentity = new ClaimsIdentity(claims, "AuthType",
        JwtClaimTypes.Name, JwtClaimTypes.Role);

    мы говорим AuthorizationPolicyBuilder бери значение для имени из клейма JwtClaimTypes.Name, а для роли из JwtClaimTypes.Role. Вместо них вы можете подставить какой клейм вы хотите, хоть адрес или почту, главное, чтобы он был в new List<Claim>().

    Т.е. в вашем случае только нужно было указать имя клейма в конструкторе new ClaimsIdentity. И он бы заработал с ClaimsIdentity.DefaultNameClaimType.


    Сделаем содержимое сообщества лучше, вместе!

    19 декабря 2018 г. 13:15
    Модератор

Все ответы

  • Клейм для роли берётся из JwtClaimTypes.Role. То есть вам нужно указать:

    new Claim(JwtClaimTypes.Role, "admin")


    Сделаем содержимое сообщества лучше, вместе!

    13 декабря 2018 г. 8:53
    Модератор
  • Получается так примерно:

    AddPolicy("AdminPolicy", policy => policy.RequireRole("Admin"));

    new Claim(JwtClaimTypes.Role, "Admin"),

    var claimsIdentity = new ClaimsIdentity(claims, "AuthType",
        JwtClaimTypes.Name, JwtClaimTypes.Role);
    
    var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    


    Сделаем содержимое сообщества лучше, вместе!

    13 декабря 2018 г. 9:02
    Модератор
  • стойте
    вы предлагаете использовать механизм ролей

    а мне именно claim  нужен

    Вообще задача состоит в том чтобы сделать так чтобы метод контроллера был доступен только пользователю с именем admin

    я бы сделал так [Authorize(Users="admin")] но в Core нету Users 

    А например в asp.net MVC он есть

    Поэтому решил использовать Claims

    13 декабря 2018 г. 12:09
  • "стойте вы предлагаете использовать механизм ролей" - нет, "механизм ролей" использует клеймы в данном случае, строка приведённая ниже.

    var claimsIdentity = new ClaimsIdentity(claims, "AuthType",
        JwtClaimTypes.Name, JwtClaimTypes.Role);

    "Вообще задача состоит в том чтобы сделать так чтобы метод контроллера был доступен только пользователю с именем admin" - завтра если у вас будет два пользователя администратора (а это будет), то вам не будет необходимо менять код, так как UserName скорее всего будет разный, а роль нет.


    Сделаем содержимое сообщества лучше, вместе!

    13 декабря 2018 г. 12:22
    Модератор
  • В ASP.NET Identity всё опирается на клеймы, не важно это AspNetWebStack (MVC 5.x, Web API 2.x, and Web Pages 3.x) или ASP.NET Core. Просто в старом у вас был выбор, в новом уже легаси код выпилили.

    Сделаем содержимое сообщества лучше, вместе!

    13 декабря 2018 г. 12:27
    Модератор
  • Спасибо за ответы

    Да завтра действительно может появиться два администратора и логичнее использовать роли

    Но для меня важен был мой изначальный вариант Просто в целях разобраться

    Вообщем мой код заработал Ошибка была вот тут

    Claim c = new Claim(ClaimsIdentity.DefaultNameClaimType, "admin");

    ClaimsIdentity это не для Claim

    Нужно было использовать ClaimTypes потому что ведь Claim создаем 

    Заменил на ClaimTypes.Name и все заработало

    19 декабря 2018 г. 12:31
  • "ClaimsIdentity это не для Claim Нужно было использовать ClaimTypes потому что ведь Claim создаем" - на самом деле не важно какой тип там используется, все они не что иное как просто строковые константы. Важно чтобы значение данной константы совпало с тем, что используется в классе:

    AuthorizationPolicyBuilder


    Это задаётся в конструкторе ClaimsIdentity, которую я привёл выше. Т.е. для строки

    var claimsIdentity = new ClaimsIdentity(claims, "AuthType",
        JwtClaimTypes.Name, JwtClaimTypes.Role);

    мы говорим AuthorizationPolicyBuilder бери значение для имени из клейма JwtClaimTypes.Name, а для роли из JwtClaimTypes.Role. Вместо них вы можете подставить какой клейм вы хотите, хоть адрес или почту, главное, чтобы он был в new List<Claim>().

    Т.е. в вашем случае только нужно было указать имя клейма в конструкторе new ClaimsIdentity. И он бы заработал с ClaimsIdentity.DefaultNameClaimType.


    Сделаем содержимое сообщества лучше, вместе!

    19 декабря 2018 г. 13:15
    Модератор