ASP.NET Web API与自定义身份验证

13

我正在寻求帮助创建具有自定义用户名/密码身份验证的 Web API。

我有自己的数据库来验证用户,不想使用 Windows 身份验证。

我希望能够像 [Authorize] 这样的属性装饰我的 Web API 调用,这样未登录的调用将失败。

我不想每个方法都传递凭据作为参数。

此 API 将主要由使用 Xamarin PCL 的移动设备使用。

Web API 必须使用 SSL。

这似乎是一个简单的设置,但我的谷歌搜索没有发现任何超级有用的结果。

理想情况下,我希望有一个 Login 控制器,该控制器可以授权用户并允许后续方法调用。

是否可以提供一个基本示例或一些好的阅读材料?

3个回答

15

这是一个很大的主题,你可能需要花些时间来学习基础知识。

话虽如此,为了让后续方法调用得到认证,你需要有一个可以传递给每个请求的东西。如果你从网站中调用API,比如使用Angular或类似的技术,则一个简单的cookie(加密和MAC处理)就能满足需求。如何实现取决于你是否使用OWIN以及你的项目中是否还有MVC来提供页面服务。不要自己创建cookie,使用FormsAuthentication或等效的OWIN中间件即可。

你不需要使用Microsoft的Membership或Identity,但要知道自己处理密码不是一件简单的事情,你必须确切地知道自己在做什么-如果你想做这个事情,没有什么替代品可以代替研究。

如果你需要从除了网站之外的地方调用api,则cookie将不是一个好的选择。同时,请注意,在使用cookie和Web api时存在一些微妙的CSRF漏洞,你需要了解并保护自己免受这些漏洞的影响。

另一个替代cookie的选择是嵌入类似ThinkTecture Identityserver(它是免费的),并使用它来发出oAuth令牌,然后将这些令牌附加到每个API请求中。它有许多优点,但也更加复杂。

资源
你确实要求了关于开始阅读的指引。由于微软在过去几年里已经多次更改了默认方法,所以你的任务变得有些复杂。目前默认的方法是Identity,它取代了以前的MembershipProvider(好的拜拜)。如果你是新手,我建议你采用这种方法-你可以扩展它并且它与大部分的堆栈非常紧密地结合。是的,你会失去一些灵活性,而且你需要将其包装到你当前的用户存储中。但你需要问自己:出厂时获得的安全性是否值得那样做。

我还推荐Brock Allen的博客。内容非常硬核,但他精通技术并经常讲解很多微软身份验证技术的内部机制。

我建议你尝试阅读关于"OWIN身份验证中间件"的相关知识。这是未来的趋势,特别是在ASP.Net vNext方面。不幸的是,大多数文档都只关注如何使用(对于演示而言确实很容易),但缺乏关于它实际工作原理的深入信息,这可能会很令人沮丧。

为了更好地理解令牌和不同标准的工作方式,我建议您观看这个视频:http://www.ndcvideos.com/#/app/video/2651

然后看看Azure移动服务,它甚至还有处理身份验证的客户端库,或者ThinkTecture Identity Server。即使最终您没有使用IdSrv,通过学习其如何使用的教程,您将学到关于通用工作原理的很多知识;所有这些都基于开放标准。文档在这里:http://identityserver.github.io/Documentation/docs/。尝试通过他们的教程进行操作;他们使用Windows控制台应用程序代替应用,但概念是相同的。

祝你好运,但我想强调一点:请不要仅仅拼凑出似乎可以工作的东西。网络安全日益复杂,很容易在代码中留下漏洞-我谈论从经验中得出的教训 :) 。

不要成为Moonpig。


此内容旨在供移动设备使用。 - Julien
如果你所说的移动设备是指移动应用而不仅仅是在移动浏览器上的网站,那么你需要像Noel提到的oAuth令牌或承载令牌之类的东西...看看IdentityServer。或者如果你在Azure上托管,他们已经将身份验证集成到移动服务中 - 但我从未使用过,所以不确定它是否能满足你的需求。或者考虑让用户使用Google/Facebook/Twitter账号登录。 - flytzen
社交网络登录不是一个选项。这是针对移动应用的,是的。 - Julien
然后看看Azure移动服务或ThinkTecture身份服务器。即使您最终使用IdSrv,通过阅读他们关于如何使用它的教程,您将学到很多关于整个系统如何工作的知识;这一切都基于开放标准。文档在这里:http://identityserver.github.io/Documentation/docs/ 这里有一个关于OpenIDConnect的很棒的概述视频:http://www.ndcvideos.com/#/app/video/2651 - flytzen
我正在使用Xamarin PCL编写移动应用程序。不认为Azure移动服务适用。看起来IdentifyServer似乎是正确的选择。 - Julien
证明在ASP.NET中进行身份验证(auth*)比它本应该的要难得多。 - Craig Brett

4
根据您使用的版本不同,MVC5 Web API 2采用了一种称为bearer tokens的方法。因此,您需要提前使用用户名和密码执行post到https://applicationhostlocation/token端点。这将在有效载荷中返回一个bearer token。您可以在标头中使用bearer token向授权的Web API方法发送后续https请求。这是最新版本的Web API的开箱即用的功能。此链接很好地概述了该方法:http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api

哦,不错啊,我不知道他们已经把它内置了。 - flytzen
这篇文章很糟糕。它几乎完全关注客户端,使用内置的成员数据库,而且示例应用程序甚至无法构建。 "登录"按钮发送请求到令牌端点。令牌端点在哪里? - Julien

2
自定义会员提供程序,我的朋友!

https://codeutil.wordpress.com/2013/05/14/forms-authentication-in-asp-net-mvc-4/

通过自定义成员资格提供程序,您可以设置授权Cookie令牌(也称为AuthCookie),并在应用程序中使用Forms身份验证技术。使用自定义成员资格提供程序,您将能够创建一个自定义验证方法,访问您的数据库以匹配用户凭据。
使用AuthCookie,每个后续请求都将得到认证,就像传统的授权Cookie技术一样。
此外,您可以使用URL重写方法强制用户重定向到SSL页面:Best way in asp.net to force https for an entire site?

你肯定可以使用它,但MembershipProvider现在已被Identity所取代。此外,MembershipProvider是一个泄漏的抽象,往往在MVC/Web API中没有什么用处。我在这里写了一篇关于这个问题的文章:http://blog.lytzen.name/2013/03/using-aspnet-mvc-without.html Brock Allen的看法在这里:http://brockallen.com/2012/09/02/think-twice-about-using-membershipprovider-and-simplemembership/ - flytzen
1
有太多零散的信息存在,这并没有帮助。我找到的所有身份验证示例都没有使用自定义数据库进行自定义身份验证。 - Julien
@Julien:确实如此 - 过于关注简单的演示 :( - flytzen
1
@Frans 我同意这个新的身份框架很迷人。但是需要注意的是,尽管默认的SimpleCustomMembershipProvider非常有限,但是一个设计良好的CustomMembershipProvider可以非常强大。 - Vitox
@Julien 我对此有同样的感觉。即使在微软发布了.NET Core 1.0之后,仍然存在过于分散的信息。我仍然想知道如何将我的当前用户数据库与Web API连接。 - Mr_LinDowsMac
显示剩余5条评论

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