我想使用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);
}