我想使用ASP.NET SimpleMembership对使用我的WebAPI的用户进行身份验证。 Thinktecture有一个很棒的身份验证库,称为Thinktecture.IdentityModel(http://thinktecture.github.com/Thinktecture.IdentityModel.45/),并带有将Forms Auth与Basic Auth(source)联系起来的示例。但是,该示例使用的Membership.ValidateUser()在没有ASP.NET Membership提供程序的情况下无法运行,而SimpleMembership(source)不支持该提供程序(编辑:这并不完全正确,请参见下面的Mark回答) 。



编辑:

这是我所做的:

1)创建一个新的MVC Internet应用程序

2)通过NuGet安装Thinktecture.IdentityModel

3)通过脚手架创建模型和api控制器:

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:未指定。但是,如果我先使用AccountController登录,然后使用Fiddler,则得到200,一切都变了。

编辑

好的,我认为问题与我的最初问题无关。我怀疑这与模板中SimpleMembership的初始化有关。当我打开项目并运行调试时,再用Fiddler命中api,我将无法通过Auth。但是,当我简单地单击Web前端上的“注册”链接时,就会越过Auth。我猜是因为在AccountController上调用了InitializeSimpleMembershipAttribute,所以直到控制器被调用才初始化吗?



我试过使用WebSecurity.Login()代替Membership.ValidateUser(),但这不起作用。

我对如何真正实现这一点不知所措。有人有建议吗?还是我试图从错误的角度解决这个问题?

最佳答案

您是正确的,ASP.NET Membership提供程序与SimpleMembershipProvider不兼容,但是SimpleMembershipProvider支持ValidateUser,请参见here。假设已正确配置和初始化SimpleMembership,您仍然应该能够调用Membership.ValidateUser()

如果您已经尝试过Membership.ValidateUser()并遇到错误,请告诉我,我们可以尝试解决它。

更新资料

因此,按照您的复制步骤,我设法查明了一个错误。使Thinktecture AuthenticationHandler处理程序内联并在调试中运行。向api控制器请求后30秒,正在引发数据库连接错误。这是异步且无提示的失败。

经过一番摆弄之后,我相信是DefaultConnection连接字符串出了问题。

像我一样,您的默认连接可能包含这样的文件名:
AttachDBFilename = | DataDirectory | \ aspnet-MvcApplication3-20121215104323.mdf“

当在应用程序启动时注册的委托中调用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”更改了连接字符串,则通过提琴手的请求将得到200:

GET http://localhost/api/goober/1
User-Agent: Fiddler
Host: localhost
Authorization: Basic dGVzdDp0ZXN0aW5n


作为旁白

我发现要获得表单授权令牌还可以访问我必须添加的api控制器。否则,Thinkteckture代码会将原理设置回匿名:

加上这个

authConfig.InheritHostClientIdentity = true;


要抵消this(第52行):

if (_authN.Configuration.InheritHostClientIdentity == false)
{
   //Tracing.Information(Area.HttpAuthentication, "Setting anonymous principal");
   SetPrincipal(Principal.Anonymous);
}

08-15 14:42