ASP.NET Web API 身份验证

20

我创建了一个新的ASP.NET Web API,目前一切都运行良好。现在我想保护这个API。

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

然而,我正在思考,对于想要进行API调用并通过授权的外部客户端,最佳实践是什么?还要考虑到我自定义的身份验证逻辑。

客户端应该如何发送凭据?何时处理这些凭据?

2个回答

21

我该如何发送客户端凭证?

发送身份验证信息的默认位置是授权头。您可以使用此选项进行基本身份验证,还可以用于其他类型的身份验证(JWT、Bearer等)。

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

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

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

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

我会编写一个DelegatingHandler并使用它来解析您的“principal”。然后,您可以将其设置为HttpContext.CurrentPrincipal,以便在请求范围内需要它的任何位置都可以使用。正如您在下面的图像中所看到的那样,DelegatingHandler是在控制器之前调用的,这使其非常适合进行身份验证逻辑。

enter image description here

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

最后但并非最不重要的是,我建议您不要编写自己的自定义身份验证逻辑,而是坚持使用默认框架之一。这可以只是使用HTTPS上的基本身份验证,也可以实现OAuth等复杂方案。但我会远离自行解决方案。

我还想邀请您查看我回答的一个类似问题的答案。

注意:ASP.NET Web Api是基于REST的,所以个人认为您不想保留会话信息。

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


这非常有帮助。还有一个问题。如果我想使用OAuth,我需要创建一个单独的OAuth服务,创建某种令牌,客户端在进行API调用之前首先获取该令牌,对吗?有没有好的示例可以参考?我似乎找不到任何关于使用OAuth保护ASP.NET Web API的简单资料。 - Adam Levitt
如果您想设置一个单独的服务来创建令牌,请查看ThinkTectures IdentityServer。这应该会在这种情况下真正帮助您:http://leastprivilege.com/2012/11/01/oauth2-in-thinktecture-identityserver-v2-resource-owner-password-flow/ 如果您想自己设置服务器或将其实现到您的服务中,请查看DotNetOpenAuth。然后设置自己的IAuthorizationServerHost。有关一些示例,请参见此处:https://github.com/ErikSchierboom/basicoauth2server.persistent。但请注意,OAuth 2.0并不是“简单”的。 - Jos Vinke

3
基本上,您需要将加密的用户名和密码通过网络发送到服务器应用程序,然后可以让您的API生成一个随机会话ID并将其保存在列表(服务器端)中,并将ID发送回客户端。现在,每当客户端向服务器发送任何内容时,请在数据包中包括他收到的ID,以便服务器每次都可以进行检查。
在客户端断开连接或固定超时时,您可以从服务器列表中删除ID并要求客户端重新进行身份验证。

谢谢您的帮助。如果客户端传回一个会话ID,他们如何将其传回给我?所有这些信息是从哪里发送的?Http头?我应该在哪里编写处理代码?是否有任何教程可以参考? - Adam Levitt
这完全取决于您构建应用程序的方式以及要使用的协议。例如,如果您只有一个telnet应用程序,在套接字流中发送和接收字符串,您可以将ID作为字符串消息中的第一个参数。客户端仅通过服务器记住接收到的ID,并将其用作凭证来证明身份,直到断开连接。 - Chuk Ultima
这是一个使用ASP.NET的所有内置基础设施的Web API。请求仅通过HTTP接受。 - Adam Levitt
避免通过网络发送API的用户名和密码。最好使用共享密钥和签名。 - Murray Foxcroft

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