使用NancyFx进行表单身份验证

时间:2013-06-04 12:46:24

标签: authentication nancy

我正在使用NancyFx创建一个简单的网站,用户可以使用ajax控件登录和注销。

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

  1. 安装Nancy.Authentication.Forms包
  2. 实施IUserMapper
  3. 实施路由以处理登录和注销
  4. 配置并启用表单身份验证
  5. 我遇到一个问题,在调用登录后,请求没有当前用户设置。 登录执行后我可以看到一个cookie集。但是,用户映射器未被调用。我已经尝试过使用和退出this.RequiresAuthentication();仍然没有用户。

    这是我的第4步的Bootstrapper实现

    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);
        }
    }
    

    这是我的登录信息&amp;步骤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时被构造,但是从来没有调用get GetUserFromIdentifier函数。

    任何帮助都会很棒。

1 个答案:

答案 0 :(得分: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"]