我正在尝试使用Nancy在asp.net托管的WorldDomination SimpleAuthentication plugin for Nancy网络应用中使用社交身份验证。 TL; DR跳到问题底部的粗体问题。
两者都非常好,但是在身份验证过程(包含良好)和在初始身份验证请求之外的请求期间识别经过身份验证的用户(没有任何内容)之间存在巨大的文档差距。
Nancy通过其他软件包提供基本和表单身份验证,他们提供的钩子非常简单。 WorldDomination在实际身份验证过程之后没有提供太多信息。对于正常的“谁是发出此请求的用户”进程似乎明显缺乏快乐路径,每次用户点击服务器时都必须这样做。
我花了相当多的时间来计算这一部分,但我的研究并没有让我得到任何明显的解决方案。 WD演示应用程序除了身份验证请求之外没有请求代码,并且代码库似乎不包含任何处理正常请求周期的内容。
我最好的猜测是我需要与表单auth集成,实现Nancy的表单auth钩子并使用我从WD获取的内容来填充我自己的类型。
这看起来并不是最开心的快乐路径。事实上,它似乎更像是“做很多工作你懒惰的混蛋”的道路。
对于整合WorldDomination的社交OAuth身份验证提供程序和Nancy的推荐快乐路径究竟是什么?我专注于标准的“这个人是谁请求我”页面生命周期部分在这里
奖励积分(来自我将为此目的创建的大量sockpuppet帐户),以了解这条快乐路径如何处理用户退出!
答案 0 :(得分:15)
使用简单身份验证,我们只需以简单的方式处理与提供程序的身份验证。每个提供商都有不同的实现,不同的命名,不同的承诺,因此我们可以将所有这些整合到简单身份验证中,并使开发人员更容易实现到他们的网站。
这就是Nancy.SimpleAuthentication包存在的原因。因为我们知道Nancy是如何工作的,所以我们通过创建模块来简化与Nancy的集成,以便处理重定向,身份验证回调等。
问题是,我们根本不知道如何根据您的网站对用户进行身份验证。
我们可以自己处理整个表单身份验证方案,我实际上计划将来使用。 (必须首先实现我60%通过的声明),但它仍然至少要求你实现IAuthenticationCallbackProvider
public class Test : IAuthenticationCallbackProvider
{
public dynamic Process(
NancyModule nancyModule,
AuthenticateCallbackData model)
{
//Query for the database user based on the Provider / Id
//Authenticate the user
//Call LoginWithoutRedirect, and redirect how you want...
// or LoginWithRedirect
return nancyModule.Negotiate.WithView("AuthenticateCallback")
.WithModel(model);
}
}
此类是必需的,以便您根据数据库对用户进行身份验证。
我们考虑过的事情是用户进行身份验证的95%的时间,很可能已经有了某种形式的身份验证。通常是表格认证。
假设你已经提入了SimpleAuthentication,并连接了IAuthenticationCallbackProvider
类。你真正需要做的就是实现Forms Auth的东西,这几乎是一个类,并且是一个方法调用。
在提供程序中,您需要调用LoginWithoutRedirect
方法,以便Nancy可以创建一个auth cookie。
然后你需要设置IUserMapper
类来告诉Nancy如何从数据库中获取用户。如果您使用的是RavenDB,那么它将类似于:
public class DatabaseUser : IUserMapper
{
public IDocumentStore DocumentStore { get; set; }
public DatabaseUser(IDocumentStore documentStore)
{
DocumentStore = documentStore;
}
public IUserIdentity GetUserFromIdentifier(
Guid identifier,
NancyContext context)
{
using (var session = DocumentStore.OpenSession())
{
var member = session.Query<Member>()
.SingleOrDefault(x => x.Identifier == identifier);
if (member == null)
return null;
return new UserIdentity
{
UserName = member.DisplayName,
Claims = new []
{
"NewUser",
"CanComment"
}
};
}
}
}
在引导程序中配置如:
protected override void ConfigureRequestContainer(
TinyIoCContainer container,
NancyContext context)
{
base.ConfigureRequestContainer(container, context);
container.Register<IUserMapper, DatabaseUser>();
}
protected override void RequestStartup(
TinyIoCContainer container,
IPipelines pipelines,
NancyContext context)
{
base.RequestStartup(container, pipelines, context);
var formsAuthConfiguration = new FormsAuthenticationConfiguration
{
RedirectUrl = "~/login",
UserMapper = container.Resolve<IUserMapper>(),
};
FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
}
这就是它......
我个人认为你不得不写很多代码。 Nancy和Simple Authentication都为您完成了大部分工作:)
我希望将来可以通过删除Forms Auth的需要,使SimpleAuthentication更容易,但是现在我认为我们有一个非常好的解决方案。
有用的链接:
http://www.philliphaydon.com/2012/12/18/forms-authentication-with-nancyfx/
http://www.philliphaydon.com/2013/01/31/oauth-with-nancyfx-and-world-domination-authentication/
World Domination的第二个链接,虽然有一些重命名,但它大致相同。我打算做一个更新的博客文章,并在我们完善索赔时修改维基。
我希望能帮助你。
编辑: