Thinktecture.IdentityModel with SimpleMembership

bru*_*ert 5 asp.net authentication asp.net-mvc asp.net-web-api thinktecture-ident-model

我想使用ASP.NET SimpleMembership来验证使用我的WebAPI的用户.Thinktecture有一个名为Thinktecture.IdentityModel(http://thinktecture.github.com/Thinktecture.IdentityModel.45/)的精彩认证库,其中包含一个将Forms Auth与Basic Auth()联系起来的示例.但是,该示例使用Membership.ValidateUser(),它在没有ASP.NET成员资格提供程序的情况下不起作用,SimpleMembership(源代码)不支持(编辑:这不完全正确,请参阅下面的Mark答案).


编辑:

这是我做的:

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

2)通过NuGet安装Thinktecture.IdentityModel

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

public class Goober
{
    public int GooberId { get; set; }
    public string GooberWords { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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));
Run Code Online (Sandbox Code Playgroud)

当我运行该项目并用Fiddler命中api/goober/1时,我得到了一个401 www-Authenticate:未指定.但是如果我首先使用AccountController登录然后使用Fiddler我得到200并且一切都很好.

编辑

好的,我认为问题与我最初的问题无关.我怀疑它与模板中SimpleMembership的初始化有关.当我打开项目并运行调试然后用Fiddler点击api我无法通过Auth.但是,当我只是点击网络前端的"注册"链接时,我就会通过Auth.我猜是因为在AccountController中调用了InitializeSimpleMembershipAttribute,所以在调用控制器之前不会初始化?


我尝试在Membership.ValidateUser()的位置使用WebSecurity.Login(),但这不起作用.

我对如何实现这一点感到茫然.有人有建议吗?或者我可能试图从错误的角度解决这个问题?

Mar*_*nes 3

您说得对,ASP.NET 会员资格提供程序与 ASP.NET 会员资格提供程序不兼容,SimpleMembershipProviderSimpleMembershipProvider确实支持ValidateUser,请参阅此处。假设 SimpleMembership 已正确配置并初始化,您仍然应该能够调用Membership.ValidateUser().

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

更新

因此,按照您的重现步骤,我成功地找出了一个错误。将 ThinktectureAuthenticationHandler处理程序内联并在调试中运行。向 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>
Run Code Online (Sandbox Code Playgroud)

然后我在这里找到了这篇文章,它表明 AppDomain 此时尚未正确设置其数据目录。

因此,一旦配置设置完毕并使用正确的文件路径和用户名“test”和密码“testing”更改连接字符串,通过 fiddler 发出的此请求将得到 200:

GET http://localhost/api/goober/1
User-Agent: Fiddler
Host: localhost
Authorization: Basic dGVzdDp0ZXN0aW5n
Run Code Online (Sandbox Code Playgroud)

作为旁白

我发现要获取表单授权令牌以允许访问 api 控制器,我必须添加它。否则,Thinkteckture 代码将原则设置回匿名:

添加这个

authConfig.InheritHostClientIdentity = true;
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题(第 52 行):

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