Как вернуть 403 вместо перенаправления на отказ в доступе при сбое AuthorizeFilter

В Startup.ConfigureServices() я настраиваю фильтр авторизации следующим образом:

services.AddMvc(options =>
{
    options.Filters.Add(new AuthorizeFilter(myAuthorizationPolicy));
})

и я использую либо аутентификацию cookie, либо аутентификацию AAD на основе конфигурации:

if (useCookieAuth)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie();
}
else
{
    services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
       .AddAzureAD(options => Configuration.Bind("Authentication:AzureAd", options));
}

Теперь, когда я посещаю страницу и myAuthorizationPolicy дает сбой, меня перенаправляют на «Account/AccessDenied?ReturnUrl=%2F», но вместо этого я хочу вернуть 403.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
4 442
5

Ответы 5

public class AuthorizeOrForbidAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpStatusCodeResult(403);
        }

    }
}

Попробуйте вышеуказанный фильтр.

Где я должен использовать это?

Liero 31.01.2019 14:13

options.Filters.Add (новый AuthorizeFilter (myAuthorizationPolicy)); Можете ли вы отправить метод myAuthorizationPolicy? Я должен сначала увидеть этот метод.

GANESH KUMAR 31.01.2019 14:18

Если у вас нет кода в методе myAuthorizationPolicy, создайте класс, подобный приведенному выше коду. и удалите свой код options.Filters.Add(new AuthorizeFilter(myAuthorizationPolicy)); <br> . Затем добавьте эту строку options.Filters.Add(new AuthorizeOrForbidAttribute());

GANESH KUMAR 31.01.2019 14:22

Кажется, вам нужно переопределить OnRedirectToAccessDenied

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options => {
        options.Events.OnRedirectToAccessDenied = context => {
             context.Response.StatusCode = 403;
             return Task.CompletedTask;
        };
    });

Да, но как насчет аутентификации AAD?

Liero 31.01.2019 14:14

Скорее всего, вам придется создать собственный AddAzureAD(), так как он пока не настраивается...

Boris Sokolov 31.01.2019 14:43

Что-то вроде общедоступного статического AuthenticationBuilder AddAzureAd (этот построитель AuthenticationBuilder, Action<azureadoptions> configureOptions) { builder.Services.Configure(configureOptions); builder.Services.AddSingleton<iconfigureoptions<openidconnect‌​toptions>, ConfigureAzureOptions>(); builder.AddOpenIdConnect(options => { options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = RedirectToIdentityProvider }; }); возврат застройщика; }

Boris Sokolov 31.01.2019 14:44

Это хорошо работает!! Отсутствует возврат Task.CompletedTask

Daniel 29.04.2020 07:10

Это не работает на стороне сервера, когда я использую Blazor WebAssembly Solution

Simon 31.07.2020 14:08

@Simon Я не тестировал его с Blazor WebAssembly ... может быть лучше задать отдельный вопрос, если есть какой-то конкретный вопрос, кроме этого.

Boris Sokolov 31.07.2020 14:32

@BorisSokolov: Да, конечно. Я сделал: stackoverflow.com/questions/63191785/…

Simon 31.07.2020 14:36

Вы можете создать собственный Authorization Filter в сочетании с вашей политикой.

public class MyAuthorizeFilter: IAsyncAuthorizationFilter
{
    public MyAuthorizeFilter(string policy)
    {
        Policy = policy;
    }

    public string Policy { get; set; }
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;

        var authZService = context.HttpContext.RequestServices.GetRequiredService<IAuthorizationService>();
        var accessable = await authZService.AuthorizeAsync(user, null, this.Policy);
        if (!accessable.Succeeded)
        {
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
        }

    }
}

и теперь вы можете использовать фильтр авторизации для перехвата запроса:

[MyAuthorizeFilter("MyPolicy")]
public IActionResult Index()

или глобально:

services.AddMvc(options =>
        {
            options.Filters.Add(new MyAuthorizeFilter("MyPolicy"));              
        });

Конечно, сначала нужно зарегистрировать полис.

services.AddAuthorization(o => {
            o.AddPolicy("MyPolicy", pb => {
                pb.RequireAuthenticatedUser();
                //...
            });
        });

Недавно я столкнулся с этой проблемой и смог найти инструкции, связанные с тем, как переопределить поведение файлов cookie по умолчанию в AzureADB2C по адресу:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/azure-ad-b2c?view=aspnetcore-3.1#configure-the-underlying-openidconnectoptionsjwtbearrcookie-options

Вот пример реализации этого переопределения для возврата простого 403 вместо перенаправления:

services
    .AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
    .AddAzureADB2C();

services.Configure<CookieAuthenticationOptions> (AzureADB2CDefaults.CookieScheme, options =>
{
    // Stop AzureADB2C from redirecting 403's, which it does by default.  We just want to return the 403.
    options.Events.OnRedirectToAccessDenied = new Func<RedirectContext<CookieAuthenticationOptions>, Task>(context =>
    {
        context.Response.StatusCode = StatusCodes.Status403Forbidden;
        return context.Response.CompleteAsync();
    });
});

Надеюсь, это поможет кому-то.

Для тех людей (кашель меня), которые используют Azure AD и используют в своем ConfigureServices:

services.AddMicrosoftIdentityWebAppAuthentication(Configuration);

Решением является следующее дополнение:

        services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options =>
        {
            options.Events.OnRedirectToAccessDenied = new Func<RedirectContext<CookieAuthenticationOptions>, Task>(context =>
            {
                context.Response.StatusCode = StatusCodes.Status403Forbidden;
                return context.Response.CompleteAsync();
            });
        });

При этом ASP.NET больше не будет перенаправлять на AccessDenied, а вместо этого будет возвращать 403.

Более подробную информацию можно найти здесь: https://blog.johnnyreilly.com/2020/12/21/how-to-make-azure-ad-403/ (но все, что вам действительно нужно, это этот ответ, я надеюсь)

Я пробовал это, но по какой-то причине это не работает (точка останова внутри функции не срабатывает). Меня по-прежнему перенаправляют на страницу входа в ADB2C. Любая подсказка о том, что это может быть?

killswitch 29.03.2021 17:54

Другие вопросы по теме