Как использовать новые роли ASP.NET Identity 2.0 и атрибут авторизации?
Я использую новую систему ASP.NET Identity 2.0. Я знаю, что могу проверить, имеет ли пользователь такую роль:
bool isAdmin = UserManager.IsInRole(User.Identity.GetUserId(),
"Customer Account Admin");
Я предполагаю, что этот код можно записать для проверки перед запуском определенного кода, но как насчет атрибута [Авторизовать]. Раньше я мог сказать:
[Authorize(Role="Customer Account Admin")]
Это больше не работает, потому что я больше не использую старое членство или управление ролью. Как я могу объединить эти два? Или как я могу защищать от определенных частей приложения, которые не доступны членам правильной роли?
Edit1: Я не считаю, что он работает. Я добавляю следующий атрибут Authorize на странице администратора, и я могу выполнить код как "пользователь учетной записи клиента"
[Authorize(Roles = "Customer Service Admin, Savitas Admin")]
public partial class _default : System.Web.UI.Page
Кроме того, я хотел бы заблокировать эту страницу от неавторизованных пользователей. У нас есть код для блокировки меню, но я все еще могу набрать URL-адрес на странице администратора, и его можно увидеть неавторизованными пользователями.
if (HttpContext.Current.User.IsInRole("Customer Account Admin"))
//
{
}
else
{
mi = radmenu1.Items.FindItemByText("Admin");
radmenu1.Items.Remove(mi);
}
EDIT2: Мы создали роли вручную в таблице ASpNetRoles и сопоставили пользователей с ролями в таблице ASPNetUsersToRoles. Существует сопоставление пользователей с такими ролями, как "Администратор службы поддержки клиентов". Мы добавляем пользователей к ролям со следующим, но я не думаю, что он работает:
if (manager.AddToRole(manager.FindByName(UserName.Text).Id, "Customer Account Admin").Succeeded)
{
c.logActivity("Register.aspx.cs", "REG_USER_ROLE", "Setting user to Admin role succeeded");
}
Когда обычный пользователь регистрируется, они не получают меню администратора на странице администратора, введя адресную строку:
http://localhost:53620/Admin/default
Как это остановить?
Edit3: я попытался заблокировать всех пользователей на странице администратора в вашем примере Eric, но еще раз, я могу войти в систему как пользователь-пользователь и все еще напечатать выше в адресной строке и перейти на страницу. Что не так с этим:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
<connectionStrings>
...
</connectionStrings>
<location path="~/Admin/default.aspx">
<system.web>
<authorization>
<allow roles="Customer Service Admin" />
<deny users="*"/>
</authorization>
Edit4: переход на путь = "Admin/default.aspx" дает следующую ошибку в файле конфигурации:
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
Source Error:
Line 66: </controls>
Line 67: </pages>
Line 68: <membership>
Line 69: <providers>
Line 70: <!-- ASP.NET Membership is disabled in this template. Please visit the following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn about the ASP.NET Membership support in this template
Ответы
Ответ 1
Я провел несколько тестов, и я не смог воссоздать вашу проблему. Я использовал роли с пробелами и без них, а также несколько ролей. И все работает так, как ожидалось.
Как вы добавляете роли? Вот как я это делаю.
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>());
roleManager.Create(new IdentityRole("This Is A Test"));
UserManager.AddToRole(user.Id, "This Is A Test");
UPDATE:
ASP.NET имеет три основных компонента: WebForms, MVC и Web-страницы. Вы используете WebForms (не классический asp.net или любой другой термин).
Существует несколько способов защитить страницу по ролям, но проще всего сделать это в web.config с помощью элемента location. И снова это не имеет ничего общего с тем фактом, что это ASP.NET Identity или роли старого стиля или что-то еще... все это работает с общими интерфейсами IPrincipal и IIdentity, которые являются частью базового asp.net. Например, следующее разрешает всем администраторам доступ к сайту и отказывает всем другим пользователям, но позволяет пользователям в роли MyUsers обращаться к CoolStuff.aspx:
<configuration>
<system.web>
<authorization>
<allow roles="Administrators" />
<deny users="*"/>
</authorization>
</system.web>
<!-- Allow all "MyUsers" role users to access CoolStuff.aspx -->
<location path="CoolStuff.aspx">
<system.web>
<authorization>
<allow roles="MyUsers" />
</authorization>
</system.web>
</location>
</configuration>
Помните, однако, если вы используете маршрутизацию, возможно, что одна и та же страница может быть перенаправлена на два разных URL-адреса, что означает, что он может быть доступен с одного URL-адреса, но не другой, если вы не будете осторожны с ваши права.
Ответ 2
В Identity 3 вы можете использовать это:
[Authorize(ClaimTypes.Role, "Administrator")]
Ответ 3
Если в файле Web.config включен роль roleManager, например:
<roleManager enabled="true"/>
вам нужно удалить его.
Ответ 4
У меня такая же проблема. Я хочу использовать AuthorizeAttribute, чтобы разрешить некоторые вызовы веб-api пользователю admin.
[Авторизовать] работает, но [Авторизовать (Роли = "Администратор" )] нет. API-вызовы с [Authorize (Roles = "Admin" )] выполняются очень долго, а затем у меня есть SQL Exception (невозможно подключиться).
Я добавил роль в диспетчере ролей. В моих таблицах данных роль администратора связана с моим пользователем.
Там что-то странное: роль в претензиях.
Если я это сделаю:
var claimIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;
var roleClaims = claimIdentity.Claims.Where(c => c.Type == ClaimTypes.Role);
У меня есть требование со значением "Admin" . Я использую его в вызове API для возврата другого результата пользователям admin, и он отлично работает.
Другой странный факт: я попытался использовать вместо User.IsInRole( "Admin" ), и он не работает. Поэтому я предполагаю, что AuthorizeAttribute использует IsInRole.
Я собираюсь написать свой собственный AuthorizeAttribute, используя проверку утверждений, но я бы предпочел использовать собственное решение.
Клеман
Ответ 5
Вы должны указать список ролей в атрибуте, разделенный запятыми:
[Authorize(Roles="Customer, Account, Admin")]
Я только что проверил его в примере проекта, и все сработало. О, и не забывайте переучивать пользователя, когда вы будете тестировать это:)