.NET异常:我可以抛出未经授权或未经身份验证的异常。

91

我有一些代码片段,当用户未经身份验证/未经授权时,我想抛出异常。

因此,我想知道是否已经有一些C#标准来处理这些情况,而不是编写自己的NotAuthenticatedException和NotAuthorizedException。

我可以想象很多程序会抛出类似的异常,如果每个人都再次“重新发明轮子”,那将不会非常有用。


6
可以在这两种情况下使用 SecurityException 异常。 - jags
1
throw new NotAuthorizedException有什么问题吗?如果您认为它的封装不够好,只需将其封装在静态类中即可。 - Fendy
1
@Fendy 很确定他的意思是编写自己的NotAuthorizedException,而不是实际的代码throw new NotAuthorizedException();... - anaximander
1
在asp.net中,我使用HttpException(401, "未经授权")或者我的自定义HttpUnauthorizedExeption() : base((int)HttpStatusCode.Unauthorized, "未经授权")来提高可读性。 - Liero
1
@Liero,为什么要抛出Http异常,而不是使用数据级别的授权呢?例如,Dirk可能希望引发NotAuthorisedException,因为用户无权访问特定客户的记录? - Jacques
3个回答

65

19
这个名字听起来不错,但文档中说:“UnauthorizedAccessException异常通常由封装Windows API调用的方法抛出。”对于本问题所提供的情景,这可能会产生误导。最好抛出自定义异常,而不是重用一个专为完全不同的上下文环境而设计的框架异常。 - G-Mac
3
我认为MS评论中的关键词是“typically”,这暗示接下来的文本是一个例子。如果我看到一些代码捕获了“UnauthorizedAccessViolation”,我会认为已经发生了未经授权的访问尝试,而不一定是“封装了Windows API调用的方法”所导致的。 - Gruff Bunny
7
现在我可能有点挑剔,但是PrivilegeNotHeldException继承自UnauthorizedAccessException,这意味着任何处理UnauthorizedAccessException的try/catch块都会尝试处理该异常,而这不是您的意图。 这是修辞手法,有些牵强附会,但如果您正在编写聊天程序,并检测到两个参与者之间的争吵,您会抛出ArgumentException吗?你不是试图暗示异常的语义与原始异常的预期或他人使用的语义不匹配吗? - G-Mac
需要注意的是,Windows API调用抛出此异常的原因通常是因为用户没有权限访问文件/文件夹。因此,它仍然符合通用未授权异常的总体主题。 - Jonathan Allen
1
我同意@G-Mac的观点,UnauthorizedAccessException似乎不适用于这种情况。 - woodbase

42

24
我认为这些例外并不适用于授权失败或未经身份验证(匿名)的用户。它们旨在处理客户端提供的无效凭据的情况,而这与根本没有提供任何凭据是不同的。 - Joe
1
我认为AuthenticationException是完全有效的。直接从MSDN:当客户端或服务器无法进行身份验证时,类抛出此异常,这就是OP所询问的内容。我相信可能有更好的授权类,正如你和其他人所提到的“SecurityException”。 - Darren
8
我不同意你的解释。MSDN表示这些异常是在“身份验证流程失败时”使用的,即在验证客户端的过程中。我的理解是OP的情况已经完成了身份验证过程,现在需要决定是否授权匿名用户或已认证用户。 - Joe
24
认证不等于授权。例如,一个用户可能被认证为“被禁止的用户”,但是却没有使用该网站的授权。 - Sedat Kapanoglu
1
@DarrenDavies 对不起,我以为InvalidCredentialsException是用于授权而不是身份验证。这就是为什么我想指出这两个概念是不同的原因。但是OP可能仍然认为它们是相同的。他提出问题的方式暗示了这一点。 - Sedat Kapanoglu
显示剩余4条评论

10
为了避免重复造轮子,我建议使用PrincipalPermission.DemandPrincipalPermissionAttribute
如果需求失败,将会为您抛出一个SecurityException异常。
如果您确实想要明确地抛出一个异常而不是使用PrincipalPermission.Demand,您可以考虑重用现有类型System.UnauthorizedAccessException,该类型在MSDN中被描述为:

由于I/O错误或特定类型的安全错误,操作系统拒绝访问时引发的异常。

这是您的应用程序而不是操作系统拒绝访问,但或许足够接近。

6
@ssg,我不同意这个观点。MSDN的异常处理指南(http://msdn.microsoft.com/en-us/library/seyhszts.aspx)指出:“在大多数情况下,请使用预定义的异常类型”。 - Joe
@ssg - 因此,您可能会从自己的代码中抛出其他内置异常类型,隐含地意味着这一点。 - Joe
UnauthorizedAccessException 派生自 SystemException。我希望文档能清楚地说明为什么“SystemException”被禁止以及它是否适用于其派生类。 - Sedat Kapanoglu
8
@ssg - 嗯,它也禁止了 System.Exception,但显然这不适用于其派生类。 - Joe
我意识到这是一个非常古老的问题,但仍然相关且仍然令人困惑。https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions 明确指出,抛出System.Exception派生类是可以的,并且像@Joe所指示的那样是首选(特别是ArgumentException和InvalidOperationException)。 - snort
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接