我想使用 ASP.NET SimpleMembership 对使用我的 WebAPI 的用户进行身份验证。 Thinktecture 有一个很棒的身份验证库,名为 Thinktecture.IdentityModel (http://thinktecture.github.com/Thinktecture.IdentityModel.45/),其中有一个将 Forms Auth 与 Basic Auth 联系起来的示例 ( source )。但是,该示例使用 Membership.ValidateUser(),如果没有 ASP.NET 成员(member)资格提供程序,该提供程序将无法工作,而 SimpleMembership ( source ) 不支持该提供程序(编辑:这并不完全是是的,请参阅下面马克的回答)。
<小时/>编辑:
这就是我所做的:
1) 创建一个新的 MVC Internet 应用程序
2) 通过 NuGet 安装 Thinktecture.IdentityModel
3)通过脚手架创建模型和api Controller :
public class Goober
{
public int GooberId { get; set; }
public string GooberWords { get; set; }
}
4)运行项目,创建一个新用户并使用 Fiddler 创建一个新的 Goober
5) GetGoober(int id) 添加[授权]
6)在WebApiConfig.cs中添加:
var authConfig = new AuthenticationConfiguration();
authConfig.AddBasicAuthentication((userName, password) =>
Membership.ValidateUser(userName, password));
config.MessageHandlers.Add(new AuthenticationHandler(authConfig));
当我运行该项目并使用 Fiddler 点击 api/goober/1 时,我得到一个 401 www-Authenticate: unspecified。但如果我先使用 AccountController 登录,然后使用 Fiddler,我会得到 200 ,一切都很顺利。
编辑
好吧,我认为这个问题与我最初的问题无关。我怀疑这与模板中 SimpleMembership 的初始化有关。当我打开项目并运行调试然后使用 Fiddler 访问 api 时,我无法通过身份验证。但是,当我只需单击网络前端上的“注册”链接时,我就通过了身份验证。我猜这是因为在 AccountController 中调用了 InitializeSimpleMembershipAttribute,所以在调用 Controller 之前不会初始化?
<小时/>我尝试使用 WebSecurity.Login() 代替 Membership.ValidateUser(),但这不起作用。
我不知道如何实际实现这一点。有人有建议吗?或者也许我试图从错误的角度解决这个问题?
最佳答案
您说得对,ASP.NET 成员(member)提供程序与 SimpleMembershipProvider
不兼容,但 SimpleMembershipProvider
确实支持 ValidateUser
,请参阅 here 。假设 SimpleMembership 已正确配置并初始化,您仍然应该能够调用 Membership.ValidateUser()
。
如果您已尝试 Membership.ValidateUser()
并收到错误,请告诉我,我们可以尝试解决该问题。
更新
因此,按照您的重现步骤,我成功地找出了一个错误。将 Thinktecture AuthenticationHandler
处理程序内联并在调试中运行。向 api Controller 发出请求后 30 秒,将引发数据库连接错误。这是异步且无提示地失败。
经过一番摆弄后,我相信这是 DefaultConnection
连接字符串有问题。
像我一样,您的默认连接可能包含如下文件名: AttachDBFilename=|DataDirectory|\aspnet-MvcApplication3-20121215104323.mdf"
当在应用程序启动时注册的委托(delegate)内部调用 ValidateUser 时(用于验证凭据),它似乎无法解析 |DataDirectory|
我发现通过将此路径更新为我的全名连接问题消失了。
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcApplication3-20121215104323;Integrated Security=SSPI;AttachDBFilename=C:\mydatabase\file\path\example\aspnet-MvcApplication-20121215104323.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
然后我找到了这篇文章here ,这表明 AppDomain 此时尚未正确设置其数据目录。
因此,一旦设置了配置并使用正确的文件路径和用户名“test”和密码“testing”更改了连接字符串,通过 fiddler 的此请求就会得到 200:
GET http://localhost/api/goober/1
User-Agent: Fiddler
Host: localhost
Authorization: Basic dGVzdDp0ZXN0aW5n
作为旁白
我发现要获取表单授权 token 以允许访问 api Controller ,我必须添加它。否则,Thinkteckture 代码将原则设置回匿名:
添加这个
authConfig.InheritHostClientIdentity = true;
抵消this (第 52 行):
if (_authN.Configuration.InheritHostClientIdentity == false)
{
//Tracing.Information(Area.HttpAuthentication, "Setting anonymous principal");
SetPrincipal(Principal.Anonymous);
}
关于asp.net - Thinktecture.IdentityModel 与 SimpleMembership,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13886958/