C# 对 ASP.NET Web API 进行身份验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19793845/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:54:24  来源:igfitidea点击:

Authenticating ASP.NET Web API

c#asp.net-web-apiauthorization

提问by Adam Levitt

I've created a new ASP.NET Web API and things are working well. I'm at the point now where I want to secure the API.

我创建了一个新的 ASP.NET Web API,并且一切正常。我现在正处于要保护 API 的地步。

I put the [Authorize] attribute above my base controller and it's working properly if I want to make API calls within the ASP.NET application itself.

我将 [Authorize] 属性放在我的基本控制器上方,如果我想在 ASP.NET 应用程序本身内进行 API 调用,它可以正常工作。

However, I'm wondering, what's the best practice for an external client that wants to make API calls and get past the authorization? Also, keeping in mind I have custom authentication logic.

但是,我想知道,对于想要进行 API 调用并通过授权的外部客户端来说,最佳实践是什么?另外,请记住我有自定义身份验证逻辑。

How should the client send over credentials? At what point do I process these credentials?

客户端应该如何发送凭据?我在什么时候处理这​​些凭据?

采纳答案by Jos Vinke

How should I send the client credentials?

我应该如何发送客户端凭据?

The default location to send authentication info, is the authorizationheader. You can use this for basic authentication but also for other types of authentication (JWT, Bearer, etc.).

发送身份验证信息的默认位置是授权标头。您可以将其用于基本身份验证,也可以用于其他类型的身份验证(JWT、Bearer 等)。

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

To add, for example, a basic authentication header to your request you could use the following code on your client:

例如,要向您的请求添加基本身份验证标头,您可以在客户端上使用以下代码:

WebRequest request = (HttpWebRequest)WebRequest.Create("https://yoururl");
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("user:password")));

At what point do I process these credentials?

我在什么时候处理这​​些凭据?

I would write a DelegatingHandlerand use it to resolve your 'principal'. You can then set it to the HttpContext.CurrentPrincipalto have it available wherever you need it within the scope of the request. The DelegatingHandleris called before your controllers as you can see in the image below, which makes it ideal for authentication logic.

我会写一个DelegatingHandler并用它来解决你的“委托人”。然后,您可以将其设置为 ,HttpContext.CurrentPrincipal以使其在请求范围内的任何地方都可用。在DelegatingHandler你的控制器之前被称为你可以在下面的图片,这使得它非常适合认证逻辑中看到的。

enter image description here

在此处输入图片说明

I would do the same on the client (write a DelegatingHandleror ActionFilterAttribute) to add the authentication header on a default location. Note that DelegatingHandlers are part of the HTTP pipeline and ActionFilterAttributes belong to the MVC pipeline.

我会在客户端上做同样的事情(写 aDelegatingHandlerActionFilterAttribute)以在默认位置添加身份验证标头。请注意,DelegatingHandlers 是 HTTP 管道的一部分,而ActionFilterAttributes 属于 MVC 管道。

Last but not least I would recommend not to write your own custom authentication logic but stick with one off the default frameworks. This can be as easy as using basic authentication over HTTPS and as complicated as implementing OAuth. But I would stay away from do it yourself solutions.

最后但并非最不重要的一点,我建议不要编写自己的自定义身份验证逻辑,而是坚持使用默认框架。这可以像通过 HTTPS 使用基本身份验证一样简单,也可以像实现 OAuth 一样复杂。但我会远离自己动手解决方案。

I did like to also invite you to have a look at this answerI gave to a similair question.

我不喜欢也邀请您来看看这个答案我给一个similair问题。

Note:ASP.NET Web Api is REST based, so imho you don't want to keep session information at all.

注意:ASP.NET Web Api 是基于 REST 的,所以恕我直言,您根本不想保留会话信息。

Edit:For an example on how to implement a delegatinghandler that handle basic authentication see: basic http authentication in asp.net web api using message handlers.

编辑:有关如何实现处理基本身份验证的委托处理程序的示例,请参阅:使用消息处理程序的 asp.net web api 中的基本 http 身份验证。

回答by Chuk Ultima

Basically you'll want to send the username and password encrypted over the net to your server application, then you can let your API generate a random session ID and keep it in a list (serverside) and send the ID back to the client. Now each time your client sends something to the server, include the ID he received in the packets and so the server can check it each time.

基本上,您需要将通过网络加密的用户名和密码发送到您的服务器应用程序,然后您可以让您的 API 生成一个随机会话 ID 并将其保存在列表(服务器端)中,然后将该 ID 发送回客户端。现在每次你的客户端向服务器发送一些东西时,包括他在数据包中收到的 ID,这样服务器每次都可以检查它。

On client disconnection or fixed timeout you can remove the ID from the server list and ask the client to re-authenticate.

在客户端断开连接或固定超时时,您可以从服务器列表中删除 ID 并要求客户端重新进行身份验证。