6
votes

I see that I can add Nancy to my Azure Mobile App. http://www.strathweb.com/2014/02/running-owin-pipeline-new-net-azure-mobile-services/ but how can I add the authentication for Nancy? The goal here is to be able to have both a web app and a mobile app using the same server.

Goal: If Nancy page requires authentication, jump to ~/.auth/login/aad (for example), then return to the originating page.

Where I am:

  1. Created new Azure Mobile App ASP.NET application
  2. Added Nancy
  3. Remove default MobileAppConfig and replace with

        new MobileAppConfiguration()
            .MapApiControllers()
            .AddTables(
                new MobileAppTableConfiguration()
                    .MapTableControllers()
                    .AddEntityFramework()
            )
            .AddPushNotifications()
            .MapLegacyCrossDomainController()
            .ApplyTo(config);
    
  4. Create an IndexModule and confirm that Nancy works

    public IndexModule()
    {
        Get["/"] = _ => "Hello";
    }
    
  5. Create an AdminModule, RequiresAuthentication comes after installing Nancy.Authentication.Forms

    public AdminModule()
        : base("admin")
    {
        Get["/"] = _ =>
        {
            this.RequiresAuthentication();
            return "This is admin";
        };
    }
    
  6. Probably the wrong thing to do, but I have

    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 formsAuthConfig = new FormsAuthenticationConfiguration
        {
            RedirectUrl = "~/.auth/login/aad",
            UserMapper = container.Resolve<IUserMapper>(),
        };
    
        FormsAuthentication.Enable(pipelines, formsAuthConfig);
    }
    

This sends the user to the right auth page, but when zumo returns it (1) returns to a callback with token, and (2) gives a link to "website" that is the main site, rather than the returnUrl, and (3) still doesn't really work.

Update. Looks like Nancy.Forms.Authentication is a deadend on this. Can I use UseCookieAuthentication from Owin.Security?

Update2. I got rid of Nancy.Forms.Authentication. It looks like when Zumo finishes authenticating, the owin server.user is actually set.

    protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
    {
        base.ApplicationStartup(container, pipelines);

        Csrf.Enable(pipelines);
        pipelines.BeforeRequest.AddItemToStartOfPipeline(FlowPrincipal);
    }

    private Response FlowPrincipal(NancyContext context)
    {
        var env = Get<IDictionary<string, object>>(context.Items, NancyMiddleware.RequestEnvironmentKey);
        if (env != null)
        {
            var principal = Get<IPrincipal>(env, "server.User") as ClaimsPrincipal;
            if (principal != null)
            {
                context.CurrentUser = new ClaimsPrincipalUserIdentity(principal);
            }
        }

        return null;
    }

Will give a valid useable user. How to trigger login and redirect is another question though.

Update3. I was able to force login using the setting in Azure

enter image description here

And surprisingly this also takes care of the redirect. Not sure how it affects SignalR/Zumo tables, but hopefully it will be able to check for the header and not force login on those.

1

1 Answers

1
votes

The blog post you reference is for Azure Mobile Services, not Azure Mobile Apps.

Check out chapter 6 of my book - http://aka.ms/zumobook. It explicitly shows you how to handle App Service Authentication for a variety of platforms. Nancy isn't one of them directly, but the MVC version should assist you there.