我可以为未授权或未验证的 .NET 异常抛出

Posted

技术标签:

【中文标题】我可以为未授权或未验证的 .NET 异常抛出【英文标题】:.NET exceptions I can throw for Not Authorized or Not Authenticated 【发布时间】:2013-03-07 22:10:37 【问题描述】:

我有部分代码希望在用户未经过身份验证/未授权时抛出异常。

因此,我没有编写自己的 NotAuthenticatedException 和 NotAuthorizedException,而是想知道是否还没有一些针对这些的 C# 标准。

我可以想象很多程序都会抛出类似的异常,如果每个人都再次“编写自己的***”,那将不是很有用。

【问题讨论】:

这两种情况您都可以使用SecurityException 抛出新的 NotAuthorizedException 有什么问题?如果你觉得封装不够,那就把它封装在一个静态类中吧。 @Fendy 很确定他的意思是写他的自己的 NotAuthorizedException,而不是实际的代码throw new NotAuthorizedException();... 在 asp.net 中我使用的是 HttpException(401, "Unauthorized") resp。我自己的 HttpUnauthorizedExeption() : base((int)HttpStatusCode.Unauthorized, "Unauthorized") 以提高可读性 @Liero 为什么在这可能是数据级授权时引发 Http 异常?例如。 Dirk 可能想要引发 NotAuthorisedException,因为用户无权访问特定客户的记录? 【参考方案1】:

使用 C# AuthenticationException 或 InvalidCredentialException 类。

https://docs.microsoft.com/en-us/dotnet/api/system.security.authentication.authenticationexception

【讨论】:

我认为这些异常不适用于授权失败或未经身份验证(匿名)的用户。它们适用于客户端提供无效凭据的情况,这与根本不提供任何凭据不同。 我认为 AuthenticationException 是完全有效的。直接来自 MSDN:当无法对客户端或服务器进行身份验证时,这些类会抛出此异常,而 IMO 正是 OP 所要求的。我相信可能会有更好的授权类,因为您和其他人都提到了SecurityException 我不同意你的解释。 MSDN 表示,这些异常用于“当身份验证流的身份验证失败时”,即在验证客户端的过程中。我对OP的情况的解读是认证过程已经完成,他需要决定是授权匿名用户还是认证用户。 认证不是授权。例如,一个人可以被认证为“被禁止的用户”,但不会被授权使用该网站。 @DarrenDavies 对不起,我认为 InvalidCredentialsException 是用于授权,而不是身份验证。这就是为什么我想指出两个不同的概念。 OP可能仍然在想这个。他写问题的方式暗示了这一点。【参考方案2】:

您也可以使用UnauthorizedAccessException 处理违反授权

【讨论】:

这个名字听起来不错,但文档说“UnauthorizedAccessException 异常通常由包装 Windows API 调用的方法引发。”对于这个问题中提出的场景,这可能会产生误导。抛出自定义异常比重用用于完全不同上下文的框架异常更好。 我认为 MS 评论中的关键词是“典型地”,这表明后面的文字是一个例子。如果我查看一些捕获 UnauthorizedAccessViolation 的代码,我会认为已经进行了未经授权的访问尝试,不一定是通过“包装 Windows API 调用的方法”进行的。 所以现在我承认我是在分心,但是 PrivilegeNotHeldException 继承自 UnauthorizedAccessException,这意味着任何处理 UnauthorizedAccessException 的 try/catch 块都会尝试处理该异常,这不是你想要发生的.这是夸夸其谈,有点牵强,但如果你正在编写一个聊天程序,并检测到两个参与者之间发生争执,你会抛出 ArgumentException 吗?您不是试图暗示与原始异常的预期用途或其他人使用的异常不匹配的异常语义吗? 需要注意的是,Windows API调用抛出这个异常的原因通常是因为用户没有访问文件/文件夹的权限。所以它仍然符合通用未授权异常的总体主题。 我同意@G-Mac UnauthorizedAccessException 似乎不适合这种情况【参考方案3】:

为避免重复造***,我会使用PrincipalPermission.Demand 或PrincipalPermissionAttribute。

如果请求失败,将为您抛出SecurityException

如果您确实想显式抛出异常而不是使用PrincipalPermission.Demand,则可以考虑重用现有类型System.UnauthorizedAccessException,MSDN 中将其描述为:

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

是您的应用程序而不是操作系统拒绝访问,但可能已经足够接近了。

【讨论】:

IIRC,我们不应该自己抛出 SystemException 派生类。它们不适用于一般用途。 @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 - ...因此暗示,您可以从自己的代码中抛出其他内置异常类型。 @ssg - 好吧,它也禁止 System.Exception,显然这不适用于它的衍生产品。

以上是关于我可以为未授权或未验证的 .NET 异常抛出的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net MVC 中的 jquery 验证错误 - 无法获取属性“调用”的值:对象为空或未定义

Spring 为未定义的 bean 抛出异常

PowerShell:使用参数验证而不抛出异常

Wcf 服务异常良好实践

ASP.NET Core 5.0 JWT 身份验证总是抛出 HTTP 401 代码

验证 Spock 中没有抛出异常