【问题标题】:Forms Authentication with NancyFx使用 NancyFx 进行表单身份验证
【发布时间】:2013-06-04 12:46:23
【问题描述】:

我正在使用NancyFx 制作一个简单的网站,用户可以使用 ajax 控件登录和退出。

我已阅读Forms Authentication with Nancy 上的文档,并且我认为我已完成所有必需的步骤。

  1. 安装 Nancy.Authentication.Forms 包
  2. 实现 IUserMapper
  3. 实现处理登录和注销的路由
  4. 配置和启用表单身份验证

我遇到一个问题,在调用登录后,请求没有当前用户集。 执行登录后,我可以看到一个 cookie 集。但是,用户映射器没有被调用。我尝试使用和不使用 this.RequiresAuthentication(); 请求路由仍然没有用户。

这是我的第 4 步的引导程序实现

public class Bootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        container.Register<ISessionFactory>((c, p) => SessionFactory.Factory);
    }

    protected override void ConfigureConventions(NancyConventions conventions)
    {
        base.ConfigureConventions(conventions);

        conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("assets", @"content/assets"));
        conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("application", @"content/application"));
    }

    protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
    {
        base.ConfigureRequestContainer(container, context);
        container.Register<IUserMapper, UserMapper>();
    }

    protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
    {
        base.RequestStartup(container, pipelines, context);

        var formsAuthConfiguration =
            new FormsAuthenticationConfiguration()
            {
                RedirectUrl = "~/",
                UserMapper = container.Resolve<IUserMapper>()
            };

        FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
    }
}

这是我第 3 步的登录和注销逻辑。

Post["/login"] = x =>
        {
            //Verify here, hardcode for testing
            string email = "test@example.com";

            User user = ExecuteCommand(new FetchUser(email));

            this.LoginWithoutRedirect(user.Session);
            return new { email = user.Email, authorized = true, status = "okay" };
        };

        Post["/logout"] = x =>
        {
            return this.Logout("~/");
        };

我的 IUsermapper 只是从具有给定 ID 的数据库中查找用户。 我可以看到它是在 RequestStartup 解析 IUserMapper 时构建的,但之后永远不会调用 getUserFromIdentifier 函数。

任何帮助都会很棒。

【问题讨论】:

    标签: authentication nancy


    【解决方案1】:

    没有调用GetUserFromIdentifier 方法,因为您使用的是LoginWithoutRedirect 扩展。调用GetUserFromIdentifier 的不是登录名,而是任何后续重定向。

    更常见的做事方式是:

    string email = "test@example.com";
    User user = ExecuteCommand(new FetchUser(email));
    this.LoginAndRedirect(user.Session);
    

    预计不会直接访问登录路径。相反,用户通常会请求受保护的资源,经过身份验证,然后重定向到请求的资源。

    其他几点:

    当我尝试您的代码时,我收到返回匿名类型的错误。相反,我需要将类型返回为 json,如下所示:

    this.LoginWithoutRedirect(user.Session);
    return Response.AsJson(new
    {
        email = user.Email,
        authorized = true,
        status = "okay"
    });
    

    这很好用,它会登录并将您的匿名类型作为 json 对象返回,并且由于没有重定向,因此正如预期的那样,它不会调用 GetUserFromIdentifier

    最后,您的/logout 路由应该使用this.RequiresAuthentication() 进行保护。这是有道理的,因为只有经过身份验证的用户才需要注销。当GetUserFromIdentifier 返回 null 时,它也会保护您 - 可能是因为缓存的用户已超时。 RequiresAuthentication 检测到这个空用户并重定向回Get["/login"]

    【讨论】:

    • 注销处理程序的要点。返回 anon 类型时我没有遇到任何问题,我将它作为前端的对象返回。这个问题的关键是你必须做重定向,你不能调用登录并返回你自己的数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    相关资源
    最近更新 更多