Винятки .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.