Pregunta

I'm using OWIN to self host a WebApi, and I've been looking at the newest SPA template included in VS 2013 RC as a guide. I have a Startup.Configure method which looks like this (copied from SPA as much as possible):

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();
    config.SuppressDefaultHostAuthentication();
    config.Filters.Add(new HostAuthenticationFilter(Startup.OAuthOptions.AuthenticationType));

    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

    config.MapHttpAttributeRoutes();

    app.UseWebApi(config);

    app.UseCookieAuthentication(CookieOptions);

    app.UseExternalSignInCookie(ExternalCookieAuthenticationType);

    app.UseOAuthBearerTokens(OAuthOptions, ExternalOAuthAuthenticationType);

    app.UseFacebookAuthentication(
        appId: "123456",           // obviously changed for this post
        appSecret: "deadbeef");    // obviously changed for this post
}

Which gets invoked in my command-line app like so:

static void Main(string[] args)
{
    using (WebApp.Start<Startup>(port: 1234)) { /* ... */ }
}

I also have an AccountController straight out of the SPA template, yet when I manually "curl" the url http://localhost:1234/api/Account/ExternalLogins?returnUrl=%2F&generateState=true I get an empty array. What am I missing?

Note: if you're familiar with the ExternalLogins endpoint, it eventually calls Request.GetOwinContext().Authentication.GetExternalAuthenticationTypes(), which in my case returns nothing.

¿Fue útil?

Solución

OWIN middleware registration sequence matters here. The right order is to register web api after all authentication middleware. The following code should work:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();
    config.SuppressDefaultHostAuthentication();
    config.Filters.Add(new HostAuthenticationFilter(Startup.OAuthOptions.AuthenticationType));

    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

    config.MapHttpAttributeRoutes();

    app.UseCookieAuthentication(CookieOptions);

    app.UseExternalSignInCookie(ExternalCookieAuthenticationType);

    app.UseOAuthBearerTokens(OAuthOptions, ExternalOAuthAuthenticationType);

    app.UseFacebookAuthentication(
        appId: "123456",           // obviously changed for this post
        appSecret: "deadbeef");    // obviously changed for this post


    app.UseWebApi(config);
}

BTW, I just wrote a blog to explain the security features in SPA template. http://blogs.msdn.com/b/webdev/archive/2013/09/20/understanding-security-features-in-spa-template.aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top