ASP.NET Core Identity 2.0 - возвращает код состояния 401 в функцию ajax - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть основное приложение ASP.NET, где я использую Identity 2.0. Я пытаюсь вернуть код состояния 401, когда пользователь не вошел в систему (или 403, если он не авторизован), но различные функции возвращают только код 302 ...

Я настроил для своих нужд приложения:

  • Персонализированный метод [Authorize]

    [HttpPost]
    [RequiresPermission("Projects.Creation, Projects.Modification")]
    public IActionResult SaveProject(Project prj)
    {
     (...)
    {
    

My requirePermission - это класс, который наследует TypeFilterAttribute и имеет функцию, которая кажется полезной для установки различных возвращаемых результатов:

 public async Task OnResourceExecutionAsync(ResourceExecutingContext context,
                                                   ResourceExecutionDelegate next)
        {
            var principal = new CustomPrincipal(_PermissionProvider, context.HttpContext.User.Identity);
            bool isInOneOfThisRole = false;
            foreach (var item in _requiredPermissions.RequiredPermissions)
            {
                if (principal.IsInRole(item))
                {
                    isInOneOfThisRole = true;
                }
            }

            if (isInOneOfThisRole == false)
            {
                if (principal.Identity.IsAuthenticated)
                {
                    context.Result = new UnauthorizedResult();
                }
                else
                {
                    context.Result = new RedirectResult("~/Connexion/Login");
                }

                await context.Result.ExecuteResultAsync(context);
            }
            else
            {
                await next();
            }
        }
  • Разные вещи в моем методе запуска

    services.AddIdentity<Utilisateur, Profil>().AddUserManager<CustomUserManager<Utilisateur>>().AddRoleManager<CustomRoleManager>().AddDefaultTokenProviders();
    services.AddTransient<IUserStore<Utilisateur>, UserStore>();
    services.AddTransient<IRoleStore<Profil>, ProfileStore>();
    services.AddTransient<IPermissionProvider, PermissionProvider>();
    
    services.Configure<IdentityOptions>(options =>
    {
        // Lockout settings
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
        options.Lockout.MaxFailedAccessAttempts = 10;
        options.Lockout.AllowedForNewUsers = true;
        //options.SecurityStampValidationInterval = TimeSpan.FromHours(2);
    });
    
    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
        // If the LoginPath isn't set, ASP.NET Core defaults the path to /Account/Login.
        options.LoginPath = new PathString("/Connexion/Login");
        options.LogoutPath = new PathString("/Connexion/SignedOut");
        // If the AccessDeniedPath isn't set, ASP.NET Core defaults the path to /Account/AccessDenied.
        options.AccessDeniedPath = new PathString("/Connexion/AccessDenied");
        options.SlidingExpiration = true;
    });
    

Я перепробовал кучу предложений, но, похоже, ничего не работает как:

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

Это решение не очень хорошее для моего, потому что оно перенаправляет методы ajax и non-ajax, которые нарушают мое другое перенаправление ...

Я также пытался переопределить класс AuthorizeAttribute классом, который я нашел в Интернете. Кажется, этот класс мне нужен, но он не работает с ASP.Net Core ...

using Microsoft.AspNetCore.Authorization;
using System.Net;

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;
        var user = httpContext.User;

        if (request.IsAjaxRequest())
        {
            if (user.Identity.IsAuthenticated == false)
                response.StatusCode = (int)HttpStatusCode.Unauthorized;
            else
                response.StatusCode = (int)HttpStatusCode.Forbidden;

            response.SuppressFormsAuthenticationRedirect = true;
            response.End();
        }

        base.HandleUnauthorizedRequest(filterContext);
    }
}

У вас есть идея решить мою проблему? Или, может быть, я что-то не так делаю.

1 Ответ

0 голосов
/ 06 сентября 2018

Благодаря Брэду, я нашел решение, и это было так глупо ...

Мне не нужен класс ApplicationAuthorizeAttribute, так как у меня уже есть класс RequiresPermissionAttribute.

Проблема была только в моей функции OnResourceExecutionAsync ():

  • Я вернул неправильный код, когда у пользователя не было прав (Несанкционированный вместо результата Запретить)
  • Когда мой пользователь не вошел в систему, я вернул redirectResult на мою страницу входа вместо StatusResult. Я изменил его для UnauthorizedResult ().

Изменена часть моей функции:

            if (isInOneOfThisRole == false)
            {
                if (principal.Identity.IsAuthenticated)
                {
                    context.Result = new ForbidResult();
                }
                else
                {
                    context.Result = new UnauthorizedResult();
                }

                await context.Result.ExecuteResultAsync(context);
            }
            else
            {
                await next();
            }

И у меня уже есть функция в моем ajax, чтобы перехватить другой код состояния:

$(document).ajaxError(function (xhr, props) {
    if (props.status == 403) {
        window.location = window.location.protocol + '//' + window.location.host + "/Connexion/AccessDenied";
    } else if (props.status == 401) {
        window.location = window.location.protocol + '//' + window.location.host + "/Connexion/Login";
    }
});

И все работает хорошо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...