如何使用WorldDomination和Nancy管理我的身份验证?

8 forms-authentication oauth nancy simple-authentication

我正在尝试使用适用于NancyWorldDomination SimpleAuthentication插件在asp.net托管的Nancy Web应用程序中进行社交身份验证.TL; DR跳到问题底部加粗的问题.

两者都相当不错,但在身份验证过程(包含良好)和在初始身份验证请求之外的请求(无)之间识别经过身份验证的用户之间存在巨大的文档差距.

Nancy通过附加包提供基本和表单身份验证,他们提供的钩子非常简单.WorldDomination在实际身份验证过程之后没有提供太多信息.对于正常的"谁是发出此请求的用户"进程似乎明显缺乏快乐路径,每次用户点击服务器时都必须这样做.

我花了相当多的时间来解决这个问题,但是我的研究并没有让我得到任何明显的解决方案.WD演示应用程序除了身份验证请求之外没有请求代码,并且代码库似乎不包含处理正常请求周期的任何内容.

我最好的猜测是我需要与表单auth集成,实现Nancy的表单auth钩子,并使用我从WD获取的内容来填充我自己的类型.

这似乎并不是最开心的快乐路径. 事实上,它似乎更像是"做很多工作你懒惰的混蛋"的道路.

究竟什么是整合WorldDomination社交OAuth身份验证提供商和Nancy的推荐快乐途径? 我在这里专注于标准的"谁是这个要求我的人"页面生命周期部分.

奖励积分(来自我将为此目的创建的大量sockpuppet帐户),这个快乐路径如何处理用户退出!

Phi*_*ill 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

需要此类才能根据数据库对用户进行身份验证.

我们想到的事情是用户进行身份验证的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"
                }
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在引导程序中配置如:

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

这真的是......

我个人认为你不得不写很多代码.南希和简单身份验证都为你完成了大部分的工作:)

我希望通过消除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/

世界统治的第二个环节,虽然有一些重命名,但它大致相同.我打算做一个更新的博客文章,并在我们完善索赔时修改维基.

我希望能帮助你.

编辑:

  • 我已经注意到要创建一个更加端到端的解决方案演示项目.