2017-08-17 88 views
3

我有一个SPA我想升级到.NET 2.0的核心API网站升级cookie认证2.0

开箱.NET核心的有SPA很差Cookie身份验证,因为所有中间件假定你想重定向到/Account/Login

在单页的应用程序的验证重定向是无用的(没有登录页) - 而不是我需要一个401响应,告诉客户端JS要求用户登录

要解决这个问题。在.NET 1.1的核心,我不得不让AutomaticChallenge火,然后覆盖事件......

services.AddIdentity<AppUser, AppRole>(options => 
{ 
    var c = options.Cookies.ApplicationCookie; 
    c.AuthenticationScheme = "MyScheme"; 
    c.CookieName = "MyCookieName"; 
    c.AutomaticAuthenticate = true; 

    // This is a total cludge: AutomaticChallenge causes something deep in .NET to auto respond with a 302 redirect to ~/account/login 
    c.AutomaticChallenge = true; 
    c.LoginPath = PathString.Empty; // LoginPath defaults to ~/account/login 
    c.Events = new CookieAuthenticationEvents 
    { 
     // Override the 302 redirection with the 401 we actually want 
     OnRedirectToLogin = context => 
     { 
      context.Response.StatusCode = (int) HttpStatusCode.Unauthorized; 
      return Task.FromResult(0); 
     } 
    }; 
}) 

这是一个cludge,但它的工作。在.NET Core 2.0中它已被弃用。

我试过把它移到services.ConfigureApplicationCookie,但是当配置了cookie名称和其他属性时,CookieAuthenticationEvents.OnRedirectToLogin被忽略。

我试着将此移动到services.AddAuthentication(...).AddCookie(),建议为in the official docs,但这些设置只是被忽略。 services.Configure<CookieAuthenticationOptions>表现相同的方式。

如何设置.NET Core 2.0 Web API,以便如果请求没有有效的身份验证Cookie,它将返回HTTP 401状态?

+0

SPA始终存在工作表单/ cookies身份验证问题,反之亦然。如果您使用SPA,则执行JSON Web令牌身份验证并将所有后端服务作为Web API运行。 – Jeyara

+1

@Jeyara你听起来像这是SPA的一个基本问题。事实并非如此。 Cookies!=表单,服务是否返回持票人标记或Cookie应该是实现细节,而不是锁定用户名/密码请求是表单还是JSON发布。这里甚至没有问题:我有一个SPA可以与任何一个(都支持,所以一些密码管理员工作)和成功从1.1设置cookie,但2失败,因为它假定我总是希望表单重定向。 – Keith

回答

-1

在Authentication 2.0堆栈中,应用程序Cookie的配置不再是identityOptions的一部分。请参阅Auth 2.0 Changes

services.ConfigureApplicationCookie(o => 
     { 
      o.Events = new CookieAuthenticationEvents() 
      { 
       OnRedirectToLogin = (ctx) => 
       { 
        if (ctx.Request.Path.StartsWithSegments("/api") && ctx.Response.StatusCode == 200) 
        { 
         ctx.Response.StatusCode = 401; 
        } 

        return Task.CompletedTask; 
       }, 
       OnRedirectToAccessDenied = (ctx) => 
       { 
        if (ctx.Request.Path.StartsWithSegments("/api") && ctx.Response.StatusCode == 200) 
        { 
         ctx.Response.StatusCode = 403; 
        } 

        return Task.CompletedTask; 
       } 
      }; 
     }); 
+0

感谢您的回应,但如果您将问题阅读到最后,您会看到我已经尝试过。 – Keith

+0

我从我的API生产代码复制/粘贴此代码。不在你身边工作?我有4个API以这种方式工作 –

+0

很酷。任何使用身份中间件从1.1升级? – Keith