我有一个 ASP.NET Core 应用程序,其中使用 Identity 2.0。我试图在用户未登录时返回 401 状态代码(或在未授权时返回 403),但不同的函数仅返回 302 代码...
我根据我的应用程序需求进行了设置:
个性化的[授权]方法
[HttpPost] [RequiresPermission("Projects.Creation, Projects.Modification")] public IActionResult SaveProject(Project prj) { (...) {
我的 RequiresPermission 是一个继承 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 和非 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);
}
}
你有办法解决我的问题吗?或者也许我做错了什么。
最佳答案
感谢 Brad,我找到了解决方案,但它太愚蠢了......
我不需要 ApplicationAuthorizeAttribute
类,因为我已经有了 RequiresPermissionAttribute
类。
问题出在我的函数 OnResourceExecutionAsync() 中:
- 当用户没有权限时,我返回了错误的代码(未经授权而不是禁止结果)
- 当我的用户未登录时,我将重定向结果返回到我的登录页面,而不是 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";
}
});
一切都运行良好!
关于c# - ASP.NET Core Identity 2.0 - 将 401 状态代码返回到 ajax 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52197786/