Винятки .NET, які я можу створити для неавторизованих або неаутентифікованих


78

У мене є частини коду, де я хочу створити виняток, коли користувач не аутентифікований / не авторизований.

Тож замість того, щоб писати власні NotAuthenticatedException та NotAuthorizedException, мені було цікаво, чи не існує вже деяких стандартів C # для них.

Я уявляю, що багато програм кидають подібні винятки, і було б не дуже корисно, якби кожен знову "писав своє колесо".


4
Ви можете використовувати SecurityExceptionобидва сценарії.
— jags

1
У чому проблема з throw new NotAuthorizedException? Якщо ви вважаєте, що він недостатньо інкапсульований, просто інкапсулюйте його в статичний клас.
— Fendy 19.03.13

1
@Fendy Досить впевнений, що він має на увазі написання власного NotAuthorizedException, а не фактичного коду throw new NotAuthorizedException();...
— anaximander

1
В asp.net я використовую HttpException (401, "Несанкціонований"), відповідно. my own HttpUnauthorizedExeption (): base ((int) HttpStatusCode.Unauthorized, "Unauthorized") {} для кращої читабельності
— Лієро,

1
@Liero навіщо піднімати винятки Http, коли це може бути авторизацією на рівні даних? Наприклад, Дірк, можливо, хоче підняти NotAuthorisedException, оскільки користувач не має доступу до записів конкретного замовника?
— Jacques

Відповіді:


31

19
Я не думаю, що ці винятки підходять для невдалої авторизації або неавторизованого (анонімного) користувача. Вони призначені для ситуації, коли клієнт представляє недійсні облікові дані, що відрізняється від неподання жодних облікових даних.
— Джо,

1
Я думаю, що AuthenticationException є цілком дійсним. Безпосередньо з MSDN: класи викидають цей виняток, коли клієнт або сервер не можуть бути автентифіковані, про що просить OP. Я вважаю, що для авторизації може бути кращий клас, як у вас та інших є згадка про закінчення SecurityException.
— Даррен,

7
Я не згоден з вашим тлумаченням. MSDN зазначає, що ці винятки використовуються "коли аутентифікація не вдається для потоку автентифікації", тобто під час процесу автентифікації клієнта. Я розумію ситуацію з ОП у тому, що процес автентифікації вже завершився, і йому потрібно вирішити, авторизувати анонімного або автентифікованого користувача.
— Джо,

20
Аутентифікація - це не авторизація. Наприклад, хтось може бути автентифікований як "заборонений користувач", але не має права користуватися сайтом.
— Седат Капаноглу

1
@DarrenDavies Мені шкода, що я вважав, що InvalidCredentialsException призначений для авторизації, а не автентифікації. Ось чому я хотів зазначити два поняття різні. OP, можливо, все ще думає про це. Те, як він написав запитання, це передбачає.
— Седат Капаноглу

56

Ви також можете використовувати UnauthorizedAccessException для порушень авторизації


13
Назва звучить добре, але в документації сказано: "Виняток UnauthorizedAccessException зазвичай створюється методом, який обгортає виклик Windows API". Для сценарію, представленого у цьому питанні, це потенційно може ввести в оману. Краще кинути спеціальний виняток, ніж повторно використовувати виняток фреймворку, призначений для зовсім іншого контексту.
— G-Mac

2
Я думаю, що ключове слово у цьому зауваженні РС - "типово", що свідчить про те, що текст для наслідування є прикладом. Якби я дивився на якийсь код, який зафіксував UnauthorizedAccessViolation, я б подумав, що була зроблена спроба несанкціонованого доступу, і не обов'язково "за допомогою методу, який обертає виклик API Windows".
— Gruff Bunny

7
Отже, тепер я справді розділяю волосся, але PrivilegeNotHeldException успадковується від UnauthorizedAccessException, що означає, що будь-який блок try / catch, який обробляє UnauthorizedAccessException, намагатиметься обробляти це виняток, і це зовсім не те, що ви мали намір відбутися. Це риторично і трохи розтягнуто, але якби ви писали програму чату і виявляли сплеск між двома учасниками, ви б кинули ArgumentException? Чи не намагаєтесь ви натякнути семантику навколо винятку, який не збігався б із тим, для якого оригінальний виняток призначався або використовувався іншими?
— G-Mac

Слід зазначити, що причина, через яку виклик Windows API викликає цей виняток, полягає в тому, що користувач не має дозволу на доступ до файла / папки. Тож він як і раніше відповідає загальній темі загального несанкціонованого винятку.
— Джонатан Аллен

Я погоджуюсь з @ G-Mac UnauthorizedAccessException, здається, не підходить для цього сценарію
— woodbase

9

Щоб уникнути винаходу колеса, я б використав PrincipalPermission.Demand або PrincipalPermissionAttribute .

A SecurityExceptionЗгенерує для вас , якщо вимога не виконується.

Якщо ви хочете явно викинути виняток, а не використовувати PrincipalPermission.Demand, ви можете розглянути можливість повторного використання існуючого типу System.UnauthorizedAccessException , який описаний у MSDN як:

Виняток, який виникає, коли операційна система забороняє доступ через помилку вводу-виводу або певний тип помилки безпеки.

Доступ забороняє ваша програма, а не ОС, але, можливо, досить близько.


IIRC, ми не повинні самі кидати похідні SystemException. Вони не призначені для загального користування.
— Седат Капаноглу

4
@ssg, я з цим не згоден. У інструкціях щодо обробки винятків MSDN ( msdn.microsoft.com/en-us/library/seyhszts.aspx ) зазначено "У більшості випадків використовуйте заздалегідь визначені типи винятків".
— Джо

Я бачу ваш MSDN і піднімаю свій власний: "Не кидайте System.Exception, System.SystemException, System.NullReferenceException або System.IndexOutOfRangeException навмисно із власного вихідного коду." msdn.microsoft.com/en-us/library/ms173163.aspx
— Седат Капаноглу

@ssg - ... і тому, маючи на увазі, ви можете перекидати інші вбудовані типи винятків із власного коду.
— Джо

8
@ssg - Ну, це також забороняє System.Exception, і, очевидно, це не може стосуватися його похідних.
— Джо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.