ASP.NET Web API:返回401 /未授权响应的正确方法

Goa*_*ine 85 c# asp.net-mvc authorization

我有一个MVC webapi站点,它使用OAuth /令牌身份验证来验证请求.所有相关的控制器都具有正确的属性,并且身份验证正常.

问题是并非所有请求都可以在属性范围内被授权 - 某些授权检查必须在由控制器方法调用的代码中执行 - 在这种情况下返回401未授权响应的正确方法是什么?

我试过了throw new HttpException(401, "Unauthorized access");,但是当我这样做时,响应状态代码是500,我也得到了堆栈跟踪.即使在我们的日志记录DelegatingHandler中,我们也可以看到响应是500,而不是401.

Luk*_*keH 125

你应该HttpResponseException从你的API方法中抛出一个,而不是HttpException:

throw new HttpResponseException(HttpStatusCode.Unauthorized);
Run Code Online (Sandbox Code Playgroud)

或者,如果要提供自定义消息:

var msg = new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "Oops!!!" };
throw new HttpResponseException(msg);
Run Code Online (Sandbox Code Playgroud)

  • ``HttpResponseException`` 是 NuGet 包 ``Microsoft.AspNetCore.Mvc.WebApiCompatShim`` 的一部分,它提供 ASP.NET Core MVC 与 ASP.NET Web API 2 的兼容性。也就是说,它允许您转到非 Core核心项目中的方式。所以对于核心项目来说,这不是“正确的方式”。 (3认同)
  • 'HttpResposeException 是否已从 .netcore 中删除?/sf/ask/3299949971/Exception-ihttpactionresponse-for-net-core-webapi-2 (2认同)
  • 这将返回 500,而不是 401。 (2认同)

Joh*_*sby 78

只需返回以下内容:

return Unauthorized();
Run Code Online (Sandbox Code Playgroud)

  • @Simon_Weaver不知道为什么,但你可以使用`return Content <string>(HttpStatusCode.Unauthorized,"Message");`来做到这一点. (5认同)
  • 我认为接受的答案专门回答了 OP 的问题。我的回答回答了问题的标题“ASP.NET Web API:返回 401/未经授权的响应的正确方法” (3认同)
  • 有谁知道为什么没有带有消息的重载版本? (3认同)
  • 这应该是正确的答案。1是正确的。2)如果这在以后的框架中有所更改,则不必更改代码。3)您不需要向401提供原因。应由客户端而非服务器处理。 (2认同)
  • 这是在哪个图书馆? (2认同)

Ale*_*AIT 16

作为其他答案的替代方法,如果要IActionResult在ASP.NET控制器中返回,也可以使用此代码.

ASP.NET

 return Content(HttpStatusCode.Unauthorized, "My error message");
Run Code Online (Sandbox Code Playgroud)

更新:ASP.NET核心

上面的代码在ASP.NET Core中不起作用,您可以使用以下代码之一:

 return StatusCode((int)System.Net.HttpStatusCode.Unauthorized, "My error message");
 return StatusCode(401, "My error message");
Run Code Online (Sandbox Code Playgroud)

显然,原因短语是非常可选的(HTTP响应可以省略Reason-Phrase吗?)

  • 这不再适用于 ASP.NET Core,`ControllerBase` 类(由 ASP.NET Core WebAPI 使用)不再具有接受 HTTP 状态代码的 `Content` 重载。 (2认同)
  • 在最新版本中改为使用 StatusCodeResult() (2认同)

DGi*_*bbs 7

你得到一个500响应代码,因为你抛出一个异常(HttpException),表明某种服务器错误,这是错误的方法.

只需设置响应状态代码.eg

Response.StatusCode = (int)HttpStatusCode.Unauthorized;
Run Code Online (Sandbox Code Playgroud)

  • 基本 Web API 控制器不公开 `Response` 属性。 (2认同)

Gab*_* P. 7

要添加到 ASP.NET Core >= 1.0 中的现有答案,您可以

return Unauthorized();

return Unauthorized(object value);
Run Code Online (Sandbox Code Playgroud)

要将信息传递给客户端,您可以进行如下调用:

return Unauthorized(new { Ok = false, Code = Constants.INVALID_CREDENTIALS, ...});
Run Code Online (Sandbox Code Playgroud)

在客户端上,除了 401 响应之外,您还将获得传递的数据。例如,在大多数客户端上,您可以await response.json()获取它。


mat*_*oke 5

在 .Net Core 中你可以使用

return new ForbidResult();
Run Code Online (Sandbox Code Playgroud)

代替

return Unauthorized();
Run Code Online (Sandbox Code Playgroud)

这有利于重定向到默认的未授权页面(Account/AccessDenied),而不是直接给出 401

更改默认位置修改您的startup.cs

services.AddAuthentication(options =>...)
            .AddOpenIdConnect(options =>...)
            .AddCookie(options =>
            {
                options.AccessDeniedPath = "/path/unauthorized";

            })
Run Code Online (Sandbox Code Playgroud)

  • 403 是禁止的,而不是 401 未经授权。关于差异有一个很好的解释[这里](/sf/answers/485592131/) (2认同)