2016-08-06 4 views
9

Я пытаюсь вернуть Core Identity ASP.NET 401, когда пользователь не вошел в систему. Я добавил атрибут [Authorize] к моему методу и вместо того, чтобы возвращать 401, он возвращает 302. Я пробовал тонну предложений, но ничего не работает, в том числе services.Configure и app.UseCookieAuthentication установка LoginPath по null или PathString.Empty.Как вернуть 401 вместо 302 в ASP.NET Core?

ответ

11

По ASP.NET ядра 2.х:

services.ConfigureApplicationCookie(options => 
{ 
    options.Events.OnRedirectToLogin = context => 
    { 
     context.Response.StatusCode = 401;  
     return Task.CompletedTask; 
    }; 
}); 
+0

, также ваш призыв к сервисам. AddIdentity должен быть до этого –

5

Хорошо после того, как выкапывали в asp.net core unit tests Наконец-то я нашел рабочее решение. Вы должны добавить следующую строку в ваш призыв к services.AddIdentity

services.AddIdentity<ApplicationUser, IdentityRole>(o => { 
    o.Cookies.ApplicationCookie.AutomaticChallenge = false; 
}); 
+0

Это еще раз перенаправляет пользователя на страницу входа? Я получаю ТОЛЬКО трафик на страницы, которые при нажатии на них будут перенаправляться на страницу входа из-за 302. Я все еще хочу, чтобы это сработало, но я хочу, чтобы все боты терпели неудачу, поэтому они никогда не называют это снова (401/403). 302 все равно скажет, что они продолжают называть это. (Это для тех, которые не соблюдают файл robots.txt, где я специально «запрещаю» этот шаблон url) – ganders

+1

@ganders No. Если вы хотите, чтобы ваше приложение вел себя определенным образом на 401, вы должны справиться с этим сами. Обычно 401 должен включать заголовок WWW-Authenticate, который описывает, как аутентифицироваться. –

+0

'WWW-Authenticate' заголовок ДОЛЖЕН быть предоставлен на 401. ' Если запрос защищенного ресурса не включает учетные данные для проверки подлинности или не содержит токен доступа, который обеспечивает доступ к защищенному ресурсу, сервер ресурсов ДОЛЖЕН включать HTTP «WWW» -Authenticate "поле заголовка ответа – urbanhusky

5
services.Configure<IdentityOptions>(options => 
{ 
    options.Cookies.ApplicationCookie.LoginPath = new PathString("/"); 
    options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents() 
    { 
     OnRedirectToLogin = context => 
     { 
     if (context.Request.Path.Value.StartsWith("/api")) 
     { 
      context.Response.Clear(); 
      context.Response.StatusCode = 401; 
      return Task.FromResult(0); 
     } 
     context.Response.Redirect(context.RedirectUri); 
     return Task.FromResult(0); 
     } 
    }; 
}); 

Источник:

https://www.illucit.com/blog/2016/04/asp-net-5-identity-302-redirect-vs-401-unauthorized-for-api-ajax-requests/

+0

Это именно то, что мне нужно. Благодаря! –

+1

К сожалению, это не работает с идентификационным ядром 2 –

1

Для Asp.net Core 2 ИСПОЛЬЗОВАТЬ ВМЕСТО

services.ConfigureApplicationCookie(options => 
{ 
    options.LoginPath = new PathString("/Account/Login"); 
    options.LogoutPath = new PathString("/Account/Logout"); 

    options.Events.OnRedirectToLogin = context => 
    { 
     if (context.Request.Path.StartsWithSegments("/api") 
      && context.Response.StatusCode == StatusCodes.Status200OK) 
     { 
      context.Response.Clear(); 
      context.Response.StatusCode = StatusCodes.Status401Unauthorized; 
      return Task.FromResult<object>(null); 
     } 
     context.Response.Redirect(context.RedirectUri); 
     return Task.FromResult<object>(null); 
    }; 
}); 
+0

Это решение работает в Core 2 отлично! спасибо –

0

Если заголовок запроса содержит X-Requested-With: XMLHttpRequest код состояния будет 401 вместо 302

private static bool IsAjaxRequest(HttpRequest request) 
    { 
     return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) || 
      string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal); 
    } 

Посмотреть на GitHub: https://github.com/aspnet/Security/blob/5de25bb11cfb2bf60d05ea2be36e80d86b38d18b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs#L40-L52